From 43dd012b79fc5ad639cda126991be8d0599b413f Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Sun, 5 Jun 2011 16:09:02 +0000 Subject: [PATCH] Fix compilation warnings in smtp.h (cgreco) --- AUTHORS | 108 + COPYING | 354 + Changelog | 883 +++ INSTALL | 56 + NEWS | 4 + README | 40 + README.os2 | 62 + TODO | 2 + configure | 1652 ++++ doc/qbittorrent-nox.1 | 44 + doc/qbittorrent.1 | 42 + install.os2 | 136 + macxconf.pri | 16 + os2conf.pri | 18 + qbittorrent.pro | 4 + qbittorrent.qc | 25 + qcm/geoip-database.qcm | 37 + qcm/libboost.qcm | 112 + qcm/libmagick.qcm | 76 + qcm/libnotify.qcm | 60 + qcm/libtorrent-rasterbar.qcm | 24 + qcm/pkg-config.qcm | 16 + qcm/qt-dbus.qcm | 31 + qcm/qt-svg.qcm | 31 + qcm/qt4.qcm | 36 + qcm/qtsingleapplication.qcm | 26 + src/Icons/3-state-checkbox.gif | Bin 0 -> 322 bytes src/Icons/L.gif | Bin 0 -> 66 bytes src/Icons/flags/ad.png | Bin 0 -> 643 bytes src/Icons/flags/ae.png | Bin 0 -> 408 bytes src/Icons/flags/af.png | Bin 0 -> 604 bytes src/Icons/flags/ag.png | Bin 0 -> 591 bytes src/Icons/flags/ai.png | Bin 0 -> 643 bytes src/Icons/flags/al.png | Bin 0 -> 600 bytes src/Icons/flags/am.png | Bin 0 -> 497 bytes src/Icons/flags/an.png | Bin 0 -> 488 bytes src/Icons/flags/ao.png | Bin 0 -> 428 bytes src/Icons/flags/ar.png | Bin 0 -> 506 bytes src/Icons/flags/as.png | Bin 0 -> 647 bytes src/Icons/flags/at.png | Bin 0 -> 403 bytes src/Icons/flags/au.png | Bin 0 -> 673 bytes src/Icons/flags/aw.png | Bin 0 -> 524 bytes src/Icons/flags/ax.png | Bin 0 -> 663 bytes src/Icons/flags/az.png | Bin 0 -> 589 bytes src/Icons/flags/ba.png | Bin 0 -> 593 bytes src/Icons/flags/bb.png | Bin 0 -> 585 bytes src/Icons/flags/bd.png | Bin 0 -> 504 bytes src/Icons/flags/be.png | Bin 0 -> 449 bytes src/Icons/flags/bf.png | Bin 0 -> 497 bytes src/Icons/flags/bg.png | Bin 0 -> 462 bytes src/Icons/flags/bh.png | Bin 0 -> 457 bytes src/Icons/flags/bi.png | Bin 0 -> 675 bytes src/Icons/flags/bj.png | Bin 0 -> 486 bytes src/Icons/flags/bm.png | Bin 0 -> 611 bytes src/Icons/flags/bn.png | Bin 0 -> 639 bytes src/Icons/flags/bo.png | Bin 0 -> 500 bytes src/Icons/flags/br.png | Bin 0 -> 593 bytes src/Icons/flags/bs.png | Bin 0 -> 526 bytes src/Icons/flags/bt.png | Bin 0 -> 631 bytes src/Icons/flags/bv.png | Bin 0 -> 512 bytes src/Icons/flags/bw.png | Bin 0 -> 443 bytes src/Icons/flags/by.png | Bin 0 -> 514 bytes src/Icons/flags/bz.png | Bin 0 -> 600 bytes src/Icons/flags/ca.png | Bin 0 -> 628 bytes src/Icons/flags/cc.png | Bin 0 -> 625 bytes src/Icons/flags/cd.png | Bin 0 -> 528 bytes src/Icons/flags/cf.png | Bin 0 -> 614 bytes src/Icons/flags/cg.png | Bin 0 -> 521 bytes src/Icons/flags/ch.png | Bin 0 -> 367 bytes src/Icons/flags/ci.png | Bin 0 -> 453 bytes src/Icons/flags/ck.png | Bin 0 -> 586 bytes src/Icons/flags/cl.png | Bin 0 -> 450 bytes src/Icons/flags/cm.png | Bin 0 -> 525 bytes src/Icons/flags/cn.png | Bin 0 -> 472 bytes src/Icons/flags/co.png | Bin 0 -> 483 bytes src/Icons/flags/cr.png | Bin 0 -> 477 bytes src/Icons/flags/cs.png | Bin 0 -> 423 bytes src/Icons/flags/cu.png | Bin 0 -> 563 bytes src/Icons/flags/cv.png | Bin 0 -> 529 bytes src/Icons/flags/cx.png | Bin 0 -> 608 bytes src/Icons/flags/cy.png | Bin 0 -> 428 bytes src/Icons/flags/cz.png | Bin 0 -> 476 bytes src/Icons/flags/de.png | Bin 0 -> 545 bytes src/Icons/flags/dj.png | Bin 0 -> 572 bytes src/Icons/flags/dk.png | Bin 0 -> 495 bytes src/Icons/flags/dm.png | Bin 0 -> 620 bytes src/Icons/flags/do.png | Bin 0 -> 508 bytes src/Icons/flags/dz.png | Bin 0 -> 582 bytes src/Icons/flags/ec.png | Bin 0 -> 500 bytes src/Icons/flags/ee.png | Bin 0 -> 429 bytes src/Icons/flags/eg.png | Bin 0 -> 465 bytes src/Icons/flags/eh.png | Bin 0 -> 508 bytes src/Icons/flags/er.png | Bin 0 -> 653 bytes src/Icons/flags/es.png | Bin 0 -> 469 bytes src/Icons/flags/et.png | Bin 0 -> 592 bytes src/Icons/flags/fi.png | Bin 0 -> 489 bytes src/Icons/flags/fj.png | Bin 0 -> 610 bytes src/Icons/flags/fk.png | Bin 0 -> 648 bytes src/Icons/flags/fm.png | Bin 0 -> 552 bytes src/Icons/flags/fo.png | Bin 0 -> 474 bytes src/Icons/flags/fr.png | Bin 0 -> 545 bytes src/Icons/flags/ga.png | Bin 0 -> 489 bytes src/Icons/flags/gb.png | Bin 0 -> 599 bytes src/Icons/flags/gd.png | Bin 0 -> 637 bytes src/Icons/flags/ge.png | Bin 0 -> 594 bytes src/Icons/flags/gf.png | Bin 0 -> 545 bytes src/Icons/flags/gh.png | Bin 0 -> 490 bytes src/Icons/flags/gi.png | Bin 0 -> 463 bytes src/Icons/flags/gl.png | Bin 0 -> 470 bytes src/Icons/flags/gm.png | Bin 0 -> 493 bytes src/Icons/flags/gn.png | Bin 0 -> 480 bytes src/Icons/flags/gp.png | Bin 0 -> 488 bytes src/Icons/flags/gq.png | Bin 0 -> 537 bytes src/Icons/flags/gr.png | Bin 0 -> 487 bytes src/Icons/flags/gs.png | Bin 0 -> 630 bytes src/Icons/flags/gt.png | Bin 0 -> 493 bytes src/Icons/flags/gu.png | Bin 0 -> 509 bytes src/Icons/flags/gw.png | Bin 0 -> 516 bytes src/Icons/flags/gy.png | Bin 0 -> 645 bytes src/Icons/flags/hk.png | Bin 0 -> 527 bytes src/Icons/flags/hm.png | Bin 0 -> 673 bytes src/Icons/flags/hn.png | Bin 0 -> 537 bytes src/Icons/flags/hr.png | Bin 0 -> 524 bytes src/Icons/flags/ht.png | Bin 0 -> 487 bytes src/Icons/flags/hu.png | Bin 0 -> 432 bytes src/Icons/flags/icons-set-readme.txt | 9 + src/Icons/flags/id.png | Bin 0 -> 430 bytes src/Icons/flags/ie.png | Bin 0 -> 481 bytes src/Icons/flags/il.png | Bin 0 -> 431 bytes src/Icons/flags/in.png | Bin 0 -> 503 bytes src/Icons/flags/io.png | Bin 0 -> 658 bytes src/Icons/flags/iq.png | Bin 0 -> 515 bytes src/Icons/flags/ir.png | Bin 0 -> 512 bytes src/Icons/flags/is.png | Bin 0 -> 532 bytes src/Icons/flags/it.png | Bin 0 -> 420 bytes src/Icons/flags/jm.png | Bin 0 -> 637 bytes src/Icons/flags/jo.png | Bin 0 -> 473 bytes src/Icons/flags/jp.png | Bin 0 -> 420 bytes src/Icons/flags/ke.png | Bin 0 -> 569 bytes src/Icons/flags/kg.png | Bin 0 -> 510 bytes src/Icons/flags/kh.png | Bin 0 -> 549 bytes src/Icons/flags/ki.png | Bin 0 -> 656 bytes src/Icons/flags/km.png | Bin 0 -> 577 bytes src/Icons/flags/kn.png | Bin 0 -> 604 bytes src/Icons/flags/kp.png | Bin 0 -> 561 bytes src/Icons/flags/kr.png | Bin 0 -> 592 bytes src/Icons/flags/kw.png | Bin 0 -> 486 bytes src/Icons/flags/ky.png | Bin 0 -> 643 bytes src/Icons/flags/kz.png | Bin 0 -> 616 bytes src/Icons/flags/la.png | Bin 0 -> 563 bytes src/Icons/flags/lb.png | Bin 0 -> 517 bytes src/Icons/flags/lc.png | Bin 0 -> 520 bytes src/Icons/flags/li.png | Bin 0 -> 537 bytes src/Icons/flags/lk.png | Bin 0 -> 627 bytes src/Icons/flags/lr.png | Bin 0 -> 466 bytes src/Icons/flags/ls.png | Bin 0 -> 628 bytes src/Icons/flags/lt.png | Bin 0 -> 508 bytes src/Icons/flags/lu.png | Bin 0 -> 481 bytes src/Icons/flags/lv.png | Bin 0 -> 465 bytes src/Icons/flags/ly.png | Bin 0 -> 419 bytes src/Icons/flags/ma.png | Bin 0 -> 432 bytes src/Icons/flags/mc.png | Bin 0 -> 380 bytes src/Icons/flags/md.png | Bin 0 -> 566 bytes src/Icons/flags/me.png | Bin 0 -> 448 bytes src/Icons/flags/mg.png | Bin 0 -> 453 bytes src/Icons/flags/mh.png | Bin 0 -> 628 bytes src/Icons/flags/mk.png | Bin 0 -> 664 bytes src/Icons/flags/ml.png | Bin 0 -> 474 bytes src/Icons/flags/mm.png | Bin 0 -> 483 bytes src/Icons/flags/mn.png | Bin 0 -> 492 bytes src/Icons/flags/mo.png | Bin 0 -> 588 bytes src/Icons/flags/mp.png | Bin 0 -> 597 bytes src/Icons/flags/mq.png | Bin 0 -> 655 bytes src/Icons/flags/mr.png | Bin 0 -> 569 bytes src/Icons/flags/ms.png | Bin 0 -> 614 bytes src/Icons/flags/mt.png | Bin 0 -> 420 bytes src/Icons/flags/mu.png | Bin 0 -> 496 bytes src/Icons/flags/mv.png | Bin 0 -> 542 bytes src/Icons/flags/mw.png | Bin 0 -> 529 bytes src/Icons/flags/mx.png | Bin 0 -> 574 bytes src/Icons/flags/my.png | Bin 0 -> 571 bytes src/Icons/flags/mz.png | Bin 0 -> 584 bytes src/Icons/flags/na.png | Bin 0 -> 647 bytes src/Icons/flags/nc.png | Bin 0 -> 591 bytes src/Icons/flags/ne.png | Bin 0 -> 537 bytes src/Icons/flags/nf.png | Bin 0 -> 602 bytes src/Icons/flags/ng.png | Bin 0 -> 482 bytes src/Icons/flags/ni.png | Bin 0 -> 508 bytes src/Icons/flags/nl.png | Bin 0 -> 453 bytes src/Icons/flags/no.png | Bin 0 -> 512 bytes src/Icons/flags/np.png | Bin 0 -> 443 bytes src/Icons/flags/nr.png | Bin 0 -> 527 bytes src/Icons/flags/nu.png | Bin 0 -> 572 bytes src/Icons/flags/nz.png | Bin 0 -> 639 bytes src/Icons/flags/om.png | Bin 0 -> 478 bytes src/Icons/flags/pa.png | Bin 0 -> 519 bytes src/Icons/flags/pe.png | Bin 0 -> 397 bytes src/Icons/flags/pf.png | Bin 0 -> 498 bytes src/Icons/flags/pg.png | Bin 0 -> 593 bytes src/Icons/flags/ph.png | Bin 0 -> 538 bytes src/Icons/flags/pk.png | Bin 0 -> 569 bytes src/Icons/flags/pl.png | Bin 0 -> 374 bytes src/Icons/flags/pm.png | Bin 0 -> 689 bytes src/Icons/flags/pn.png | Bin 0 -> 657 bytes src/Icons/flags/pr.png | Bin 0 -> 556 bytes src/Icons/flags/ps.png | Bin 0 -> 472 bytes src/Icons/flags/pt.png | Bin 0 -> 554 bytes src/Icons/flags/pw.png | Bin 0 -> 550 bytes src/Icons/flags/py.png | Bin 0 -> 473 bytes src/Icons/flags/qa.png | Bin 0 -> 450 bytes src/Icons/flags/re.png | Bin 0 -> 545 bytes src/Icons/flags/ro.png | Bin 0 -> 495 bytes src/Icons/flags/rs.png | Bin 0 -> 423 bytes src/Icons/flags/ru.png | Bin 0 -> 420 bytes src/Icons/flags/rw.png | Bin 0 -> 533 bytes src/Icons/flags/sa.png | Bin 0 -> 551 bytes src/Icons/flags/sb.png | Bin 0 -> 624 bytes src/Icons/flags/sc.png | Bin 0 -> 608 bytes src/Icons/flags/sd.png | Bin 0 -> 492 bytes src/Icons/flags/se.png | Bin 0 -> 542 bytes src/Icons/flags/sg.png | Bin 0 -> 468 bytes src/Icons/flags/sh.png | Bin 0 -> 645 bytes src/Icons/flags/si.png | Bin 0 -> 510 bytes src/Icons/flags/sj.png | Bin 0 -> 512 bytes src/Icons/flags/sk.png | Bin 0 -> 562 bytes src/Icons/flags/sl.png | Bin 0 -> 436 bytes src/Icons/flags/sm.png | Bin 0 -> 502 bytes src/Icons/flags/sn.png | Bin 0 -> 532 bytes src/Icons/flags/so.png | Bin 0 -> 527 bytes src/Icons/flags/sr.png | Bin 0 -> 513 bytes src/Icons/flags/st.png | Bin 0 -> 584 bytes src/Icons/flags/sv.png | Bin 0 -> 501 bytes src/Icons/flags/sy.png | Bin 0 -> 422 bytes src/Icons/flags/sz.png | Bin 0 -> 643 bytes src/Icons/flags/tc.png | Bin 0 -> 624 bytes src/Icons/flags/td.png | Bin 0 -> 570 bytes src/Icons/flags/tf.png | Bin 0 -> 527 bytes src/Icons/flags/tg.png | Bin 0 -> 562 bytes src/Icons/flags/th.png | Bin 0 -> 452 bytes src/Icons/flags/tj.png | Bin 0 -> 496 bytes src/Icons/flags/tk.png | Bin 0 -> 638 bytes src/Icons/flags/tl.png | Bin 0 -> 514 bytes src/Icons/flags/tm.png | Bin 0 -> 593 bytes src/Icons/flags/tn.png | Bin 0 -> 495 bytes src/Icons/flags/to.png | Bin 0 -> 426 bytes src/Icons/flags/tr.png | Bin 0 -> 492 bytes src/Icons/flags/tt.png | Bin 0 -> 617 bytes src/Icons/flags/tv.png | Bin 0 -> 536 bytes src/Icons/flags/tw.png | Bin 0 -> 465 bytes src/Icons/flags/tz.png | Bin 0 -> 642 bytes src/Icons/flags/ua.png | Bin 0 -> 446 bytes src/Icons/flags/ug.png | Bin 0 -> 531 bytes src/Icons/flags/um.png | Bin 0 -> 571 bytes src/Icons/flags/us.png | Bin 0 -> 609 bytes src/Icons/flags/uy.png | Bin 0 -> 532 bytes src/Icons/flags/uz.png | Bin 0 -> 515 bytes src/Icons/flags/va.png | Bin 0 -> 553 bytes src/Icons/flags/vc.png | Bin 0 -> 577 bytes src/Icons/flags/ve.png | Bin 0 -> 528 bytes src/Icons/flags/vg.png | Bin 0 -> 630 bytes src/Icons/flags/vi.png | Bin 0 -> 616 bytes src/Icons/flags/vn.png | Bin 0 -> 474 bytes src/Icons/flags/vu.png | Bin 0 -> 604 bytes src/Icons/flags/wf.png | Bin 0 -> 554 bytes src/Icons/flags/ws.png | Bin 0 -> 476 bytes src/Icons/flags/ye.png | Bin 0 -> 413 bytes src/Icons/flags/yt.png | Bin 0 -> 593 bytes src/Icons/flags/za.png | Bin 0 -> 642 bytes src/Icons/flags/zm.png | Bin 0 -> 500 bytes src/Icons/flags/zw.png | Bin 0 -> 574 bytes src/Icons/loading.png | Bin 0 -> 248 bytes src/Icons/magnet.png | Bin 0 -> 7199 bytes src/Icons/oxygen/application-exit.png | Bin 0 -> 1760 bytes src/Icons/oxygen/application-rss+xml.png | Bin 0 -> 1136 bytes src/Icons/oxygen/application-x-mswinurl.png | Bin 0 -> 1810 bytes src/Icons/oxygen/chronometer.png | Bin 0 -> 7133 bytes src/Icons/oxygen/dialog-cancel.png | Bin 0 -> 2207 bytes src/Icons/oxygen/dialog-information.png | Bin 0 -> 1636 bytes src/Icons/oxygen/dialog-warning.png | Bin 0 -> 3422 bytes src/Icons/oxygen/document-edit-verify.png | Bin 0 -> 1998 bytes src/Icons/oxygen/document-edit.png | Bin 0 -> 1700 bytes src/Icons/oxygen/document-encrypt.png | Bin 0 -> 1052 bytes src/Icons/oxygen/document-import.png | Bin 0 -> 1244 bytes src/Icons/oxygen/document-new.png | Bin 0 -> 1410 bytes src/Icons/oxygen/document-properties.png | Bin 0 -> 1328 bytes src/Icons/oxygen/document-save.png | Bin 0 -> 1263 bytes src/Icons/oxygen/download.png | Bin 0 -> 2445 bytes src/Icons/oxygen/edit-clear-history.png | Bin 0 -> 2031 bytes src/Icons/oxygen/edit-clear.png | Bin 0 -> 2073 bytes src/Icons/oxygen/edit-copy.png | Bin 0 -> 860 bytes src/Icons/oxygen/edit-cut.png | Bin 0 -> 892 bytes src/Icons/oxygen/edit-delete.png | Bin 0 -> 1333 bytes src/Icons/oxygen/edit-find-user.png | Bin 0 -> 1908 bytes src/Icons/oxygen/edit-find.png | Bin 0 -> 1705 bytes src/Icons/oxygen/edit-paste.png | Bin 0 -> 937 bytes src/Icons/oxygen/edit-rename.png | Bin 0 -> 496 bytes src/Icons/oxygen/folder-documents.png | Bin 0 -> 1119 bytes src/Icons/oxygen/folder-new.png | Bin 0 -> 1369 bytes src/Icons/oxygen/folder-remote.png | Bin 0 -> 2393 bytes src/Icons/oxygen/gear.png | Bin 0 -> 1403 bytes src/Icons/oxygen/gear32.png | Bin 0 -> 1836 bytes src/Icons/oxygen/go-down.png | Bin 0 -> 1437 bytes src/Icons/oxygen/go-up.png | Bin 0 -> 1517 bytes src/Icons/oxygen/help-about.png | Bin 0 -> 1491 bytes src/Icons/oxygen/help-contents.png | Bin 0 -> 1599 bytes src/Icons/oxygen/inode-directory.png | Bin 0 -> 645 bytes src/Icons/oxygen/insert-link.png | Bin 0 -> 1881 bytes src/Icons/oxygen/list-add.png | Bin 0 -> 1487 bytes src/Icons/oxygen/list-remove.png | Bin 0 -> 1065 bytes src/Icons/oxygen/mail-folder-inbox.png | Bin 0 -> 739 bytes src/Icons/oxygen/mail-mark-read.png | Bin 0 -> 1360 bytes src/Icons/oxygen/media-playback-pause.png | Bin 0 -> 1145 bytes src/Icons/oxygen/media-playback-start.png | Bin 0 -> 1177 bytes src/Icons/oxygen/network-server.png | Bin 0 -> 1056 bytes src/Icons/oxygen/network-wired.png | Bin 0 -> 1267 bytes src/Icons/oxygen/object-locked.png | Bin 0 -> 1052 bytes src/Icons/oxygen/preferences-desktop.png | Bin 0 -> 2245 bytes src/Icons/oxygen/preferences-other.png | Bin 0 -> 1906 bytes .../oxygen/preferences-system-network.png | Bin 0 -> 2685 bytes src/Icons/oxygen/preferences-system.png | Bin 0 -> 2171 bytes .../preferences-web-browser-cookies.png | Bin 0 -> 2394 bytes src/Icons/oxygen/security-high.png | Bin 0 -> 1628 bytes src/Icons/oxygen/security-low.png | Bin 0 -> 1650 bytes src/Icons/oxygen/services.png | Bin 0 -> 722 bytes src/Icons/oxygen/tab-close.png | Bin 0 -> 1349 bytes src/Icons/oxygen/task-attention.png | Bin 0 -> 651 bytes src/Icons/oxygen/text-plain.png | Bin 0 -> 1138 bytes src/Icons/oxygen/tools-report-bug.png | Bin 0 -> 1709 bytes src/Icons/oxygen/unavailable.png | Bin 0 -> 813 bytes src/Icons/oxygen/user-group-delete.png | Bin 0 -> 1365 bytes src/Icons/oxygen/user-group-new.png | Bin 0 -> 1274 bytes src/Icons/oxygen/view-calendar-journal.png | Bin 0 -> 1314 bytes src/Icons/oxygen/view-categories.png | Bin 0 -> 2248 bytes src/Icons/oxygen/view-filter.png | Bin 0 -> 885 bytes src/Icons/oxygen/view-preview.png | Bin 0 -> 1462 bytes src/Icons/oxygen/view-refresh.png | Bin 0 -> 2182 bytes src/Icons/oxygen/wallet-open.png | Bin 0 -> 1702 bytes src/Icons/oxygen/webui.png | Bin 0 -> 1577 bytes src/Icons/qBitTorrentDocument.icns | Bin 0 -> 127327 bytes src/Icons/qBittorrent.desktop | 41 + src/Icons/qbittorrent_mac.icns | Bin 0 -> 50278 bytes src/Icons/skin/arrow-right.gif | Bin 0 -> 54 bytes src/Icons/skin/bg-handle-horizontal.gif | Bin 0 -> 57 bytes src/Icons/skin/checking.png | Bin 0 -> 3352 bytes src/Icons/skin/connected.png | Bin 0 -> 1412 bytes src/Icons/skin/disconnected.png | Bin 0 -> 1474 bytes src/Icons/skin/download.png | Bin 0 -> 463 bytes src/Icons/skin/downloading.png | Bin 0 -> 3270 bytes src/Icons/skin/error.png | Bin 0 -> 3038 bytes src/Icons/skin/filteractive.png | Bin 0 -> 3211 bytes src/Icons/skin/filterall.png | Bin 0 -> 3174 bytes src/Icons/skin/filterinactive.png | Bin 0 -> 3127 bytes src/Icons/skin/firewalled.png | Bin 0 -> 1488 bytes src/Icons/skin/handle-icon-horizontal.gif | Bin 0 -> 46 bytes src/Icons/skin/handle-icon.gif | Bin 0 -> 46 bytes src/Icons/skin/knob.gif | Bin 0 -> 198 bytes src/Icons/skin/mascot.png | Bin 0 -> 22693 bytes src/Icons/skin/paused.png | Bin 0 -> 2970 bytes src/Icons/skin/qbittorrent16.png | Bin 0 -> 965 bytes src/Icons/skin/qbittorrent22.png | Bin 0 -> 1444 bytes src/Icons/skin/qbittorrent32.png | Bin 0 -> 2615 bytes src/Icons/skin/qbittorrent_mono.svg | 83 + src/Icons/skin/qbittorrent_mono_dark.png | Bin 0 -> 1513 bytes src/Icons/skin/qbittorrent_mono_light.png | Bin 0 -> 1637 bytes src/Icons/skin/queued.png | Bin 0 -> 3014 bytes src/Icons/skin/ratio.png | Bin 0 -> 483 bytes src/Icons/skin/seeding.png | Bin 0 -> 427 bytes src/Icons/skin/slider-area.gif | Bin 0 -> 78 bytes src/Icons/skin/splash.png | Bin 0 -> 76804 bytes src/Icons/skin/stalledDL.png | Bin 0 -> 3188 bytes src/Icons/skin/stalledUP.png | Bin 0 -> 3237 bytes src/Icons/skin/tabs.gif | Bin 0 -> 2060 bytes src/Icons/skin/toolbox-divider.gif | Bin 0 -> 48 bytes src/Icons/skin/uploading.png | Bin 0 -> 3147 bytes src/Icons/slow.png | Bin 0 -> 1720 bytes src/Icons/slow_off.png | Bin 0 -> 2387 bytes src/Icons/sphere.png | Bin 0 -> 337 bytes src/Icons/sphere2.png | Bin 0 -> 379 bytes src/Icons/url.png | Bin 0 -> 722 bytes src/Info.plist | 60 + src/about.qrc | 6 + src/about.ui | 302 + src/about_imp.h | 106 + src/bandwidth_limit.ui | 97 + src/confirmdeletiondlg.ui | 153 + src/deletionconfirmationdlg.h | 80 + src/dnsupdater.cpp | 288 + src/dnsupdater.h | 81 + src/downloadfromurldlg.h | 91 + src/downloadfromurldlg.ui | 136 + src/downloadthread.cpp | 261 + src/downloadthread.h | 76 + src/executionlog.cpp | 32 + src/executionlog.h | 28 + src/executionlog.ui | 51 + src/filesystemwatcher.h | 290 + src/geoip/README | 12 + src/geoip/geoip.pri | 19 + src/geoip/geoip.qrc | 5 + src/geoip/geoipmanager.cpp | 202 + src/geoip/geoipmanager.h | 55 + src/gpl.html | 508 ++ src/headlessloader.h | 108 + src/hidabletabwidget.h | 64 + src/ico.cpp | 462 ++ src/ico.h | 52 + src/iconprovider.cpp | 118 + src/iconprovider.h | 63 + src/icons.qrc | 352 + src/lang.qrc | 37 + src/lang/qbittorrent_ar.qm | Bin 0 -> 106467 bytes src/lang/qbittorrent_ar.ts | 6763 ++++++++++++++++ src/lang/qbittorrent_bg.qm | Bin 0 -> 118498 bytes src/lang/qbittorrent_bg.ts | 6715 ++++++++++++++++ src/lang/qbittorrent_ca.qm | Bin 0 -> 107176 bytes src/lang/qbittorrent_ca.ts | 6536 ++++++++++++++++ src/lang/qbittorrent_cs.qm | Bin 0 -> 117216 bytes src/lang/qbittorrent_cs.ts | 6778 ++++++++++++++++ src/lang/qbittorrent_da.qm | Bin 0 -> 50563 bytes src/lang/qbittorrent_da.ts | 6042 +++++++++++++++ src/lang/qbittorrent_de.qm | Bin 0 -> 107063 bytes src/lang/qbittorrent_de.ts | 6610 ++++++++++++++++ src/lang/qbittorrent_el.qm | Bin 0 -> 124844 bytes src/lang/qbittorrent_el.ts | 6729 ++++++++++++++++ src/lang/qbittorrent_en.qm | 1 + src/lang/qbittorrent_en.ts | 5202 +++++++++++++ src/lang/qbittorrent_es.qm | Bin 0 -> 108417 bytes src/lang/qbittorrent_es.ts | 6540 ++++++++++++++++ src/lang/qbittorrent_fi.qm | Bin 0 -> 79692 bytes src/lang/qbittorrent_fi.ts | 6624 ++++++++++++++++ src/lang/qbittorrent_fr.qm | Bin 0 -> 125389 bytes src/lang/qbittorrent_fr.ts | 6769 ++++++++++++++++ src/lang/qbittorrent_gl.qm | Bin 0 -> 122470 bytes src/lang/qbittorrent_gl.ts | 5486 +++++++++++++ src/lang/qbittorrent_hr.qm | Bin 0 -> 118476 bytes src/lang/qbittorrent_hr.ts | 6173 +++++++++++++++ src/lang/qbittorrent_hu.qm | Bin 0 -> 100480 bytes src/lang/qbittorrent_hu.ts | 6711 ++++++++++++++++ src/lang/qbittorrent_hy.qm | Bin 0 -> 114609 bytes src/lang/qbittorrent_hy.ts | 5658 ++++++++++++++ src/lang/qbittorrent_it.qm | Bin 0 -> 121942 bytes src/lang/qbittorrent_it.ts | 6800 +++++++++++++++++ src/lang/qbittorrent_ja.qm | Bin 0 -> 98040 bytes src/lang/qbittorrent_ja.ts | 5231 +++++++++++++ src/lang/qbittorrent_ko.qm | Bin 0 -> 55836 bytes src/lang/qbittorrent_ko.ts | 6244 +++++++++++++++ src/lang/qbittorrent_lt.qm | Bin 0 -> 101195 bytes src/lang/qbittorrent_lt.ts | 5452 +++++++++++++ src/lang/qbittorrent_nb.qm | Bin 0 -> 120769 bytes src/lang/qbittorrent_nb.ts | 5701 ++++++++++++++ src/lang/qbittorrent_nl.qm | Bin 0 -> 119552 bytes src/lang/qbittorrent_nl.ts | 5401 +++++++++++++ src/lang/qbittorrent_pl.qm | Bin 0 -> 118078 bytes src/lang/qbittorrent_pl.ts | 5629 ++++++++++++++ src/lang/qbittorrent_pt.qm | Bin 0 -> 119929 bytes src/lang/qbittorrent_pt.ts | 5663 ++++++++++++++ src/lang/qbittorrent_pt_BR.qm | Bin 0 -> 119929 bytes src/lang/qbittorrent_pt_BR.ts | 5663 ++++++++++++++ src/lang/qbittorrent_ro.qm | Bin 0 -> 63830 bytes src/lang/qbittorrent_ro.ts | 5098 ++++++++++++ src/lang/qbittorrent_ru.qm | Bin 0 -> 120268 bytes src/lang/qbittorrent_ru.ts | 5741 ++++++++++++++ src/lang/qbittorrent_sk.qm | Bin 0 -> 120018 bytes src/lang/qbittorrent_sk.ts | 5665 ++++++++++++++ src/lang/qbittorrent_sr.qm | Bin 0 -> 118806 bytes src/lang/qbittorrent_sr.ts | 5800 ++++++++++++++ src/lang/qbittorrent_sv.qm | Bin 0 -> 118572 bytes src/lang/qbittorrent_sv.ts | 5568 ++++++++++++++ src/lang/qbittorrent_tr.qm | Bin 0 -> 79455 bytes src/lang/qbittorrent_tr.ts | 5544 ++++++++++++++ src/lang/qbittorrent_uk.qm | Bin 0 -> 103978 bytes src/lang/qbittorrent_uk.ts | 5659 ++++++++++++++ src/lang/qbittorrent_zh.qm | Bin 0 -> 87069 bytes src/lang/qbittorrent_zh.ts | 5673 ++++++++++++++ src/lang/qbittorrent_zh_TW.qm | Bin 0 -> 89245 bytes src/lang/qbittorrent_zh_TW.ts | 5681 ++++++++++++++ src/lineedit/lineedit.pri | 4 + src/lineedit/resources/lineeditimages.qrc | 6 + .../resources/lineeditimages/clear_left.png | Bin 0 -> 265 bytes .../resources/lineeditimages/search.png | Bin 0 -> 528 bytes src/lineedit/src/lineedit.cpp | 55 + src/lineedit/src/lineedit.h | 37 + src/login.ui | 299 + src/main.cpp | 322 + src/mainwindow.cpp | 1384 ++++ src/mainwindow.h | 211 + src/mainwindow.ui | 370 + src/menuicons/128x128/apps/qbittorrent.png | Bin 0 -> 21783 bytes src/menuicons/16x16/apps/qbittorrent.png | Bin 0 -> 954 bytes src/menuicons/192x192/apps/qbittorrent.png | Bin 0 -> 38579 bytes src/menuicons/22x22/apps/qbittorrent.png | Bin 0 -> 1456 bytes src/menuicons/24x24/apps/qbittorrent.png | Bin 0 -> 1682 bytes src/menuicons/32x32/apps/qbittorrent.png | Bin 0 -> 2531 bytes src/menuicons/36x36/apps/qbittorrent.png | Bin 0 -> 3032 bytes src/menuicons/48x48/apps/qbittorrent.png | Bin 0 -> 4784 bytes src/menuicons/64x64/apps/qbittorrent.png | Bin 0 -> 7729 bytes src/menuicons/72x72/apps/qbittorrent.png | Bin 0 -> 9397 bytes src/menuicons/96x96/apps/qbittorrent.png | Bin 0 -> 14592 bytes src/misc.cpp | 928 +++ src/misc.h | 195 + src/powermanagement/powermanagement.cpp | 90 + src/powermanagement/powermanagement.h | 70 + src/powermanagement/powermanagement.pri | 9 + src/powermanagement/powermanagement_x11.cpp | 185 + src/powermanagement/powermanagement_x11.h | 71 + src/preferences/advancedsettings.h | 245 + src/preferences/options.ui | 2766 +++++++ src/preferences/options_imp.cpp | 1281 ++++ src/preferences/options_imp.h | 163 + src/preferences/preferences.h | 1186 +++ src/preferences/preferences.pri | 13 + src/preview.ui | 149 + src/previewlistdelegate.h | 86 + src/previewselect.cpp | 122 + src/previewselect.h | 70 + src/programupdater.cpp | 235 + src/programupdater.h | 68 + src/properties/downloadedpiecesbar.h | 131 + src/properties/peer.ui | 109 + src/properties/peeraddition.h | 103 + src/properties/peerlistdelegate.h | 86 + src/properties/peerlistwidget.cpp | 426 ++ src/properties/peerlistwidget.h | 100 + src/properties/pieceavailabilitybar.h | 117 + src/properties/properties.pri | 22 + src/properties/propertieswidget.cpp | 731 ++ src/properties/propertieswidget.h | 115 + src/properties/propertieswidget.ui | 891 +++ src/properties/proplistdelegate.h | 202 + src/properties/proptabbar.cpp | 129 + src/properties/proptabbar.h | 66 + src/properties/trackerlist.cpp | 379 + src/properties/trackerlist.h | 79 + src/properties/trackersadditiondlg.h | 148 + src/properties/trackersadditiondlg.ui | 121 + src/qbittorrent.exe.manifest | 8 + src/qbittorrent.ico | Bin 0 -> 99678 bytes src/qbittorrent.rc | 2 + src/qbittorrent_file.ico | Bin 0 -> 99678 bytes src/qbittorrent_mingw.rc | 3 + src/qbittorrent_os2.ico | Bin 0 -> 3428 bytes src/qbittorrent_os2.rc | 1 + src/qinisettings.h | 78 + src/qmacapplication.cpp | 59 + src/qmacapplication.h | 49 + src/qtlibtorrent/bandwidthscheduler.h | 113 + src/qtlibtorrent/filterparserthread.h | 429 ++ src/qtlibtorrent/qbtsession.cpp | 2919 +++++++ src/qtlibtorrent/qbtsession.h | 280 + src/qtlibtorrent/qtlibtorrent.pri | 19 + src/qtlibtorrent/qtorrenthandle.cpp | 799 ++ src/qtlibtorrent/qtorrenthandle.h | 150 + src/qtlibtorrent/shutdownconfirm.h | 68 + src/qtlibtorrent/torrentmodel.cpp | 460 ++ src/qtlibtorrent/torrentmodel.h | 124 + src/qtlibtorrent/torrentspeedmonitor.cpp | 138 + src/qtlibtorrent/torrentspeedmonitor.h | 74 + src/qtlibtorrent/trackerinfos.h | 65 + src/qtnotify/notifications.cpp | 26 + src/qtnotify/notifications.h | 84 + src/qtnotify/notifications.xml | 31 + src/qtnotify/qtnotify.pri | 5 + src/qtsingleapp/QtLockedFile | 1 + src/qtsingleapp/QtSingleApplication | 1 + src/qtsingleapp/qtlocalpeer.cpp | 208 + src/qtsingleapp/qtlocalpeer.h | 82 + src/qtsingleapp/qtlockedfile.cpp | 199 + src/qtsingleapp/qtlockedfile.h | 101 + src/qtsingleapp/qtlockedfile_unix.cpp | 121 + src/qtsingleapp/qtlockedfile_win.cpp | 213 + src/qtsingleapp/qtsingleapplication.cpp | 351 + src/qtsingleapp/qtsingleapplication.h | 105 + src/qtsingleapp/qtsingleapplication.pri | 16 + src/qtsingleapp/qtsinglecoreapplication.cpp | 155 + src/qtsingleapp/qtsinglecoreapplication.h | 73 + src/qtsingleapp/qtsinglecoreapplication.pri | 10 + src/reverseresolution.h | 111 + src/rss/automatedrssdownloader.cpp | 582 ++ src/rss/automatedrssdownloader.h | 93 + src/rss/automatedrssdownloader.ui | 476 ++ src/rss/cookiesdlg.cpp | 104 + src/rss/cookiesdlg.h | 60 + src/rss/cookiesdlg.ui | 172 + src/rss/feedlistwidget.cpp | 221 + src/rss/feedlistwidget.h | 91 + src/rss/rss.pri | 34 + src/rss/rss.ui | 217 + src/rss/rss_imp.cpp | 685 ++ src/rss/rss_imp.h | 93 + src/rss/rssarticle.cpp | 330 + src/rss/rssarticle.h | 78 + src/rss/rssarticle_p.h | 61 + src/rss/rssdownloadrule.cpp | 148 + src/rss/rssdownloadrule.h | 80 + src/rss/rssdownloadrulelist.cpp | 225 + src/rss/rssdownloadrulelist.h | 77 + src/rss/rssfeed.cpp | 356 + src/rss/rssfeed.h | 97 + src/rss/rssfile.cpp | 40 + src/rss/rssfile.h | 62 + src/rss/rssfolder.cpp | 217 + src/rss/rssfolder.h | 80 + src/rss/rssmanager.cpp | 165 + src/rss/rssmanager.h | 73 + src/rss/rsssettings.h | 110 + src/rss/rsssettingsdlg.cpp | 57 + src/rss/rsssettingsdlg.h | 58 + src/rss/rsssettingsdlg.ui | 158 + src/scannedfoldersmodel.cpp | 204 + src/scannedfoldersmodel.h | 81 + src/searchengine/engineselect.ui | 130 + src/searchengine/engineselectdlg.cpp | 456 ++ src/searchengine/engineselectdlg.h | 83 + src/searchengine/nova/__init__.py | 0 src/searchengine/nova/engines/__init__.py | 0 src/searchengine/nova/engines/btdigg.png | Bin 0 -> 692 bytes src/searchengine/nova/engines/btdigg.py | 66 + src/searchengine/nova/engines/btjunkie.png | Bin 0 -> 622 bytes src/searchengine/nova/engines/btjunkie.py | 122 + .../nova/engines/extratorrent.png | Bin 0 -> 605 bytes src/searchengine/nova/engines/extratorrent.py | 116 + src/searchengine/nova/engines/isohunt.png | Bin 0 -> 633 bytes src/searchengine/nova/engines/isohunt.py | 69 + .../nova/engines/kickasstorrents.png | Bin 0 -> 787 bytes .../nova/engines/kickasstorrents.py | 71 + src/searchengine/nova/engines/mininova.png | Bin 0 -> 365 bytes src/searchengine/nova/engines/mininova.py | 114 + src/searchengine/nova/engines/piratebay.png | Bin 0 -> 609 bytes src/searchengine/nova/engines/piratebay.py | 114 + .../nova/engines/torrentdownloads.png | Bin 0 -> 423 bytes .../nova/engines/torrentdownloads.py | 141 + .../nova/engines/torrentreactor.png | Bin 0 -> 529 bytes .../nova/engines/torrentreactor.py | 107 + src/searchengine/nova/engines/versions.txt | 10 + src/searchengine/nova/engines/vertor.png | Bin 0 -> 643 bytes src/searchengine/nova/engines/vertor.py | 129 + src/searchengine/nova/helpers.py | 99 + src/searchengine/nova/nova2.py | 157 + src/searchengine/nova/nova2dl.py | 64 + src/searchengine/nova/novaprinter.py | 69 + src/searchengine/nova/socks.py | 391 + src/searchengine/pluginsource.h | 65 + src/searchengine/pluginsource.ui | 52 + src/searchengine/search.qrc | 29 + src/searchengine/search.ui | 194 + src/searchengine/searchengine.cpp | 735 ++ src/searchengine/searchengine.h | 151 + src/searchengine/searchengine.pri | 18 + src/searchengine/searchlistdelegate.h | 71 + src/searchengine/searchtab.cpp | 152 + src/searchengine/searchtab.h | 79 + src/searchengine/supportedengines.h | 180 + src/sessionapplication.cpp | 44 + src/sessionapplication.h | 61 + src/smtp.cpp | 458 ++ src/smtp.h | 98 + src/speedlimitdlg.h | 119 + src/src.pro | 219 + src/stacktrace.h | 94 + src/statusbar.h | 280 + src/torrentadditiondlg.cpp | 792 ++ src/torrentadditiondlg.h | 96 + src/torrentadditiondlg.ui | 361 + src/torrentcreator/createtorrent.ui | 314 + src/torrentcreator/torrentcreator.pri | 10 + src/torrentcreator/torrentcreatordlg.cpp | 282 + src/torrentcreator/torrentcreatordlg.h | 78 + src/torrentcreator/torrentcreatorthread.cpp | 130 + src/torrentcreator/torrentcreatorthread.h | 73 + src/torrentfilesmodel.h | 680 ++ src/torrentimportdlg.cpp | 307 + src/torrentimportdlg.h | 90 + src/torrentimportdlg.ui | 124 + src/torrentpersistentdata.h | 464 ++ src/tracker/qpeer.h | 35 + src/tracker/qtracker.cpp | 236 + src/tracker/qtracker.h | 74 + src/tracker/tracker.pri | 9 + src/tracker/trackerannouncerequest.h | 15 + src/trackerlogin.h | 75 + src/transferlistdelegate.h | 213 + src/transferlistfilterswidget.h | 492 ++ src/transferlistwidget.cpp | 917 +++ src/transferlistwidget.h | 122 + src/update_qrc_files.py | 91 + src/updownratiodlg.cpp | 75 + src/updownratiodlg.h | 61 + src/updownratiodlg.ui | 137 + src/webui/css/Core.css | 54 + src/webui/css/Layout.css | 427 ++ src/webui/css/Tabs.css | 66 + src/webui/css/Window.css | 371 + src/webui/css/dynamicTable.css | 62 + src/webui/css/style.css | 292 + src/webui/eventmanager.cpp | 525 ++ src/webui/eventmanager.h | 65 + src/webui/html/about.html | 380 + src/webui/html/addtrackers.html | 32 + src/webui/html/confirmdeletion.html | 73 + src/webui/html/download.html | 17 + src/webui/html/downloadlimit.html | 54 + src/webui/html/filters.html | 17 + src/webui/html/index.html | 112 + src/webui/html/preferences.html | 56 + src/webui/html/preferences_content.html | 1012 +++ src/webui/html/prop-files.html | 318 + src/webui/html/prop-general.html | 108 + src/webui/html/prop-trackers.html | 146 + src/webui/html/properties.html | 37 + src/webui/html/transferlist.html | 67 + src/webui/html/upload.html | 22 + src/webui/html/uploadframe.html | 25 + src/webui/html/uploadlimit.html | 54 + src/webui/httpconnection.cpp | 633 ++ src/webui/httpconnection.h | 98 + src/webui/httprequestparser.cpp | 148 + src/webui/httprequestparser.h | 62 + src/webui/httpresponsegenerator.cpp | 78 + src/webui/httpresponsegenerator.h | 52 + src/webui/httpserver.cpp | 335 + src/webui/httpserver.h | 101 + src/webui/json.h | 186 + src/webui/scripts/client.js | 366 + src/webui/scripts/contextmenu.js | 161 + src/webui/scripts/download.js | 34 + src/webui/scripts/dynamicTable.js | 435 ++ src/webui/scripts/excanvas-compressed.js | 876 +++ src/webui/scripts/mocha-init.js | 292 + src/webui/scripts/mocha-yc.js | 1 + src/webui/scripts/mocha.js | 6279 +++++++++++++++ src/webui/scripts/mootools-1.2-core-yc.js | 357 + src/webui/scripts/mootools-1.2-more.js | 386 + src/webui/scripts/parametrics.js | 191 + src/webui/scripts/progressbar.js | 96 + src/webui/webui.pri | 16 + src/webui/webui.qrc | 38 + unixconf.pri | 83 + version.pri | 11 + winconf-mingw.pri | 22 + winconf-msvc.pri | 21 + winconf.pri | 54 + 741 files changed, 261428 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 Changelog create mode 100644 INSTALL create mode 100644 NEWS create mode 100644 README create mode 100644 README.os2 create mode 100644 TODO create mode 100755 configure create mode 100644 doc/qbittorrent-nox.1 create mode 100644 doc/qbittorrent.1 create mode 100644 install.os2 create mode 100644 macxconf.pri create mode 100644 os2conf.pri create mode 100644 qbittorrent.pro create mode 100644 qbittorrent.qc create mode 100644 qcm/geoip-database.qcm create mode 100644 qcm/libboost.qcm create mode 100644 qcm/libmagick.qcm create mode 100644 qcm/libnotify.qcm create mode 100644 qcm/libtorrent-rasterbar.qcm create mode 100644 qcm/pkg-config.qcm create mode 100644 qcm/qt-dbus.qcm create mode 100644 qcm/qt-svg.qcm create mode 100644 qcm/qt4.qcm create mode 100644 qcm/qtsingleapplication.qcm create mode 100644 src/Icons/3-state-checkbox.gif create mode 100644 src/Icons/L.gif create mode 100755 src/Icons/flags/ad.png create mode 100755 src/Icons/flags/ae.png create mode 100755 src/Icons/flags/af.png create mode 100755 src/Icons/flags/ag.png create mode 100755 src/Icons/flags/ai.png create mode 100755 src/Icons/flags/al.png create mode 100755 src/Icons/flags/am.png create mode 100755 src/Icons/flags/an.png create mode 100644 src/Icons/flags/ao.png create mode 100755 src/Icons/flags/ar.png create mode 100755 src/Icons/flags/as.png create mode 100755 src/Icons/flags/at.png create mode 100755 src/Icons/flags/au.png create mode 100755 src/Icons/flags/aw.png create mode 100755 src/Icons/flags/ax.png create mode 100755 src/Icons/flags/az.png create mode 100755 src/Icons/flags/ba.png create mode 100755 src/Icons/flags/bb.png create mode 100755 src/Icons/flags/bd.png create mode 100755 src/Icons/flags/be.png create mode 100755 src/Icons/flags/bf.png create mode 100755 src/Icons/flags/bg.png create mode 100755 src/Icons/flags/bh.png create mode 100755 src/Icons/flags/bi.png create mode 100755 src/Icons/flags/bj.png create mode 100755 src/Icons/flags/bm.png create mode 100755 src/Icons/flags/bn.png create mode 100755 src/Icons/flags/bo.png create mode 100755 src/Icons/flags/br.png create mode 100755 src/Icons/flags/bs.png create mode 100755 src/Icons/flags/bt.png create mode 100755 src/Icons/flags/bv.png create mode 100755 src/Icons/flags/bw.png create mode 100755 src/Icons/flags/by.png create mode 100755 src/Icons/flags/bz.png create mode 100755 src/Icons/flags/ca.png create mode 100755 src/Icons/flags/cc.png create mode 100644 src/Icons/flags/cd.png create mode 100755 src/Icons/flags/cf.png create mode 100755 src/Icons/flags/cg.png create mode 100755 src/Icons/flags/ch.png create mode 100755 src/Icons/flags/ci.png create mode 100755 src/Icons/flags/ck.png create mode 100755 src/Icons/flags/cl.png create mode 100755 src/Icons/flags/cm.png create mode 100755 src/Icons/flags/cn.png create mode 100755 src/Icons/flags/co.png create mode 100755 src/Icons/flags/cr.png create mode 100755 src/Icons/flags/cs.png create mode 100755 src/Icons/flags/cu.png create mode 100755 src/Icons/flags/cv.png create mode 100755 src/Icons/flags/cx.png create mode 100755 src/Icons/flags/cy.png create mode 100755 src/Icons/flags/cz.png create mode 100755 src/Icons/flags/de.png create mode 100755 src/Icons/flags/dj.png create mode 100755 src/Icons/flags/dk.png create mode 100755 src/Icons/flags/dm.png create mode 100755 src/Icons/flags/do.png create mode 100755 src/Icons/flags/dz.png create mode 100755 src/Icons/flags/ec.png create mode 100755 src/Icons/flags/ee.png create mode 100755 src/Icons/flags/eg.png create mode 100755 src/Icons/flags/eh.png create mode 100755 src/Icons/flags/er.png create mode 100755 src/Icons/flags/es.png create mode 100755 src/Icons/flags/et.png create mode 100755 src/Icons/flags/fi.png create mode 100755 src/Icons/flags/fj.png create mode 100755 src/Icons/flags/fk.png create mode 100755 src/Icons/flags/fm.png create mode 100755 src/Icons/flags/fo.png create mode 100755 src/Icons/flags/fr.png create mode 100755 src/Icons/flags/ga.png create mode 100644 src/Icons/flags/gb.png create mode 100755 src/Icons/flags/gd.png create mode 100755 src/Icons/flags/ge.png create mode 100755 src/Icons/flags/gf.png create mode 100755 src/Icons/flags/gh.png create mode 100755 src/Icons/flags/gi.png create mode 100755 src/Icons/flags/gl.png create mode 100755 src/Icons/flags/gm.png create mode 100755 src/Icons/flags/gn.png create mode 100755 src/Icons/flags/gp.png create mode 100755 src/Icons/flags/gq.png create mode 100755 src/Icons/flags/gr.png create mode 100755 src/Icons/flags/gs.png create mode 100755 src/Icons/flags/gt.png create mode 100755 src/Icons/flags/gu.png create mode 100755 src/Icons/flags/gw.png create mode 100755 src/Icons/flags/gy.png create mode 100755 src/Icons/flags/hk.png create mode 100755 src/Icons/flags/hm.png create mode 100755 src/Icons/flags/hn.png create mode 100755 src/Icons/flags/hr.png create mode 100755 src/Icons/flags/ht.png create mode 100755 src/Icons/flags/hu.png create mode 100755 src/Icons/flags/icons-set-readme.txt create mode 100755 src/Icons/flags/id.png create mode 100755 src/Icons/flags/ie.png create mode 100755 src/Icons/flags/il.png create mode 100755 src/Icons/flags/in.png create mode 100755 src/Icons/flags/io.png create mode 100755 src/Icons/flags/iq.png create mode 100755 src/Icons/flags/ir.png create mode 100755 src/Icons/flags/is.png create mode 100755 src/Icons/flags/it.png create mode 100755 src/Icons/flags/jm.png create mode 100755 src/Icons/flags/jo.png create mode 100755 src/Icons/flags/jp.png create mode 100755 src/Icons/flags/ke.png create mode 100755 src/Icons/flags/kg.png create mode 100755 src/Icons/flags/kh.png create mode 100755 src/Icons/flags/ki.png create mode 100755 src/Icons/flags/km.png create mode 100755 src/Icons/flags/kn.png create mode 100755 src/Icons/flags/kp.png create mode 100755 src/Icons/flags/kr.png create mode 100755 src/Icons/flags/kw.png create mode 100755 src/Icons/flags/ky.png create mode 100755 src/Icons/flags/kz.png create mode 100755 src/Icons/flags/la.png create mode 100755 src/Icons/flags/lb.png create mode 100644 src/Icons/flags/lc.png create mode 100755 src/Icons/flags/li.png create mode 100755 src/Icons/flags/lk.png create mode 100755 src/Icons/flags/lr.png create mode 100755 src/Icons/flags/ls.png create mode 100755 src/Icons/flags/lt.png create mode 100755 src/Icons/flags/lu.png create mode 100755 src/Icons/flags/lv.png create mode 100755 src/Icons/flags/ly.png create mode 100755 src/Icons/flags/ma.png create mode 100755 src/Icons/flags/mc.png create mode 100755 src/Icons/flags/md.png create mode 100644 src/Icons/flags/me.png create mode 100755 src/Icons/flags/mg.png create mode 100755 src/Icons/flags/mh.png create mode 100755 src/Icons/flags/mk.png create mode 100755 src/Icons/flags/ml.png create mode 100755 src/Icons/flags/mm.png create mode 100755 src/Icons/flags/mn.png create mode 100755 src/Icons/flags/mo.png create mode 100755 src/Icons/flags/mp.png create mode 100755 src/Icons/flags/mq.png create mode 100755 src/Icons/flags/mr.png create mode 100755 src/Icons/flags/ms.png create mode 100755 src/Icons/flags/mt.png create mode 100755 src/Icons/flags/mu.png create mode 100755 src/Icons/flags/mv.png create mode 100755 src/Icons/flags/mw.png create mode 100755 src/Icons/flags/mx.png create mode 100755 src/Icons/flags/my.png create mode 100755 src/Icons/flags/mz.png create mode 100755 src/Icons/flags/na.png create mode 100755 src/Icons/flags/nc.png create mode 100755 src/Icons/flags/ne.png create mode 100755 src/Icons/flags/nf.png create mode 100755 src/Icons/flags/ng.png create mode 100755 src/Icons/flags/ni.png create mode 100755 src/Icons/flags/nl.png create mode 100755 src/Icons/flags/no.png create mode 100755 src/Icons/flags/np.png create mode 100755 src/Icons/flags/nr.png create mode 100755 src/Icons/flags/nu.png create mode 100755 src/Icons/flags/nz.png create mode 100755 src/Icons/flags/om.png create mode 100755 src/Icons/flags/pa.png create mode 100755 src/Icons/flags/pe.png create mode 100755 src/Icons/flags/pf.png create mode 100755 src/Icons/flags/pg.png create mode 100755 src/Icons/flags/ph.png create mode 100755 src/Icons/flags/pk.png create mode 100755 src/Icons/flags/pl.png create mode 100755 src/Icons/flags/pm.png create mode 100755 src/Icons/flags/pn.png create mode 100755 src/Icons/flags/pr.png create mode 100755 src/Icons/flags/ps.png create mode 100755 src/Icons/flags/pt.png create mode 100755 src/Icons/flags/pw.png create mode 100755 src/Icons/flags/py.png create mode 100755 src/Icons/flags/qa.png create mode 100755 src/Icons/flags/re.png create mode 100755 src/Icons/flags/ro.png create mode 100644 src/Icons/flags/rs.png create mode 100755 src/Icons/flags/ru.png create mode 100755 src/Icons/flags/rw.png create mode 100755 src/Icons/flags/sa.png create mode 100755 src/Icons/flags/sb.png create mode 100755 src/Icons/flags/sc.png create mode 100755 src/Icons/flags/sd.png create mode 100755 src/Icons/flags/se.png create mode 100755 src/Icons/flags/sg.png create mode 100755 src/Icons/flags/sh.png create mode 100755 src/Icons/flags/si.png create mode 100755 src/Icons/flags/sj.png create mode 100755 src/Icons/flags/sk.png create mode 100755 src/Icons/flags/sl.png create mode 100755 src/Icons/flags/sm.png create mode 100755 src/Icons/flags/sn.png create mode 100755 src/Icons/flags/so.png create mode 100755 src/Icons/flags/sr.png create mode 100755 src/Icons/flags/st.png create mode 100755 src/Icons/flags/sv.png create mode 100755 src/Icons/flags/sy.png create mode 100755 src/Icons/flags/sz.png create mode 100755 src/Icons/flags/tc.png create mode 100755 src/Icons/flags/td.png create mode 100755 src/Icons/flags/tf.png create mode 100755 src/Icons/flags/tg.png create mode 100755 src/Icons/flags/th.png create mode 100755 src/Icons/flags/tj.png create mode 100755 src/Icons/flags/tk.png create mode 100755 src/Icons/flags/tl.png create mode 100755 src/Icons/flags/tm.png create mode 100755 src/Icons/flags/tn.png create mode 100755 src/Icons/flags/to.png create mode 100755 src/Icons/flags/tr.png create mode 100755 src/Icons/flags/tt.png create mode 100755 src/Icons/flags/tv.png create mode 100755 src/Icons/flags/tw.png create mode 100755 src/Icons/flags/tz.png create mode 100755 src/Icons/flags/ua.png create mode 100755 src/Icons/flags/ug.png create mode 100755 src/Icons/flags/um.png create mode 100755 src/Icons/flags/us.png create mode 100755 src/Icons/flags/uy.png create mode 100755 src/Icons/flags/uz.png create mode 100755 src/Icons/flags/va.png create mode 100755 src/Icons/flags/vc.png create mode 100755 src/Icons/flags/ve.png create mode 100755 src/Icons/flags/vg.png create mode 100755 src/Icons/flags/vi.png create mode 100755 src/Icons/flags/vn.png create mode 100755 src/Icons/flags/vu.png create mode 100755 src/Icons/flags/wf.png create mode 100755 src/Icons/flags/ws.png create mode 100755 src/Icons/flags/ye.png create mode 100755 src/Icons/flags/yt.png create mode 100755 src/Icons/flags/za.png create mode 100755 src/Icons/flags/zm.png create mode 100755 src/Icons/flags/zw.png create mode 100644 src/Icons/loading.png create mode 100644 src/Icons/magnet.png create mode 100644 src/Icons/oxygen/application-exit.png create mode 100644 src/Icons/oxygen/application-rss+xml.png create mode 100644 src/Icons/oxygen/application-x-mswinurl.png create mode 100644 src/Icons/oxygen/chronometer.png create mode 100644 src/Icons/oxygen/dialog-cancel.png create mode 100644 src/Icons/oxygen/dialog-information.png create mode 100644 src/Icons/oxygen/dialog-warning.png create mode 100644 src/Icons/oxygen/document-edit-verify.png create mode 100644 src/Icons/oxygen/document-edit.png create mode 100644 src/Icons/oxygen/document-encrypt.png create mode 100644 src/Icons/oxygen/document-import.png create mode 100644 src/Icons/oxygen/document-new.png create mode 100644 src/Icons/oxygen/document-properties.png create mode 100644 src/Icons/oxygen/document-save.png create mode 100644 src/Icons/oxygen/download.png create mode 100644 src/Icons/oxygen/edit-clear-history.png create mode 100644 src/Icons/oxygen/edit-clear.png create mode 100644 src/Icons/oxygen/edit-copy.png create mode 100644 src/Icons/oxygen/edit-cut.png create mode 100644 src/Icons/oxygen/edit-delete.png create mode 100644 src/Icons/oxygen/edit-find-user.png create mode 100644 src/Icons/oxygen/edit-find.png create mode 100644 src/Icons/oxygen/edit-paste.png create mode 100644 src/Icons/oxygen/edit-rename.png create mode 100644 src/Icons/oxygen/folder-documents.png create mode 100644 src/Icons/oxygen/folder-new.png create mode 100644 src/Icons/oxygen/folder-remote.png create mode 100644 src/Icons/oxygen/gear.png create mode 100644 src/Icons/oxygen/gear32.png create mode 100644 src/Icons/oxygen/go-down.png create mode 100644 src/Icons/oxygen/go-up.png create mode 100644 src/Icons/oxygen/help-about.png create mode 100644 src/Icons/oxygen/help-contents.png create mode 100644 src/Icons/oxygen/inode-directory.png create mode 100644 src/Icons/oxygen/insert-link.png create mode 100644 src/Icons/oxygen/list-add.png create mode 100644 src/Icons/oxygen/list-remove.png create mode 100644 src/Icons/oxygen/mail-folder-inbox.png create mode 100644 src/Icons/oxygen/mail-mark-read.png create mode 100644 src/Icons/oxygen/media-playback-pause.png create mode 100644 src/Icons/oxygen/media-playback-start.png create mode 100644 src/Icons/oxygen/network-server.png create mode 100644 src/Icons/oxygen/network-wired.png create mode 100644 src/Icons/oxygen/object-locked.png create mode 100644 src/Icons/oxygen/preferences-desktop.png create mode 100644 src/Icons/oxygen/preferences-other.png create mode 100644 src/Icons/oxygen/preferences-system-network.png create mode 100644 src/Icons/oxygen/preferences-system.png create mode 100644 src/Icons/oxygen/preferences-web-browser-cookies.png create mode 100644 src/Icons/oxygen/security-high.png create mode 100644 src/Icons/oxygen/security-low.png create mode 100644 src/Icons/oxygen/services.png create mode 100644 src/Icons/oxygen/tab-close.png create mode 100644 src/Icons/oxygen/task-attention.png create mode 100644 src/Icons/oxygen/text-plain.png create mode 100644 src/Icons/oxygen/tools-report-bug.png create mode 100644 src/Icons/oxygen/unavailable.png create mode 100644 src/Icons/oxygen/user-group-delete.png create mode 100644 src/Icons/oxygen/user-group-new.png create mode 100644 src/Icons/oxygen/view-calendar-journal.png create mode 100644 src/Icons/oxygen/view-categories.png create mode 100644 src/Icons/oxygen/view-filter.png create mode 100644 src/Icons/oxygen/view-preview.png create mode 100644 src/Icons/oxygen/view-refresh.png create mode 100644 src/Icons/oxygen/wallet-open.png create mode 100644 src/Icons/oxygen/webui.png create mode 100644 src/Icons/qBitTorrentDocument.icns create mode 100644 src/Icons/qBittorrent.desktop create mode 100644 src/Icons/qbittorrent_mac.icns create mode 100644 src/Icons/skin/arrow-right.gif create mode 100644 src/Icons/skin/bg-handle-horizontal.gif create mode 100644 src/Icons/skin/checking.png create mode 100644 src/Icons/skin/connected.png create mode 100755 src/Icons/skin/disconnected.png create mode 100755 src/Icons/skin/download.png create mode 100644 src/Icons/skin/downloading.png create mode 100644 src/Icons/skin/error.png create mode 100644 src/Icons/skin/filteractive.png create mode 100644 src/Icons/skin/filterall.png create mode 100644 src/Icons/skin/filterinactive.png create mode 100644 src/Icons/skin/firewalled.png create mode 100644 src/Icons/skin/handle-icon-horizontal.gif create mode 100644 src/Icons/skin/handle-icon.gif create mode 100644 src/Icons/skin/knob.gif create mode 100644 src/Icons/skin/mascot.png create mode 100644 src/Icons/skin/paused.png create mode 100644 src/Icons/skin/qbittorrent16.png create mode 100644 src/Icons/skin/qbittorrent22.png create mode 100644 src/Icons/skin/qbittorrent32.png create mode 100644 src/Icons/skin/qbittorrent_mono.svg create mode 100644 src/Icons/skin/qbittorrent_mono_dark.png create mode 100644 src/Icons/skin/qbittorrent_mono_light.png create mode 100644 src/Icons/skin/queued.png create mode 100644 src/Icons/skin/ratio.png create mode 100644 src/Icons/skin/seeding.png create mode 100644 src/Icons/skin/slider-area.gif create mode 100644 src/Icons/skin/splash.png create mode 100644 src/Icons/skin/stalledDL.png create mode 100644 src/Icons/skin/stalledUP.png create mode 100644 src/Icons/skin/tabs.gif create mode 100644 src/Icons/skin/toolbox-divider.gif create mode 100644 src/Icons/skin/uploading.png create mode 100644 src/Icons/slow.png create mode 100644 src/Icons/slow_off.png create mode 100644 src/Icons/sphere.png create mode 100644 src/Icons/sphere2.png create mode 100644 src/Icons/url.png create mode 100644 src/Info.plist create mode 100644 src/about.qrc create mode 100644 src/about.ui create mode 100644 src/about_imp.h create mode 100644 src/bandwidth_limit.ui create mode 100644 src/confirmdeletiondlg.ui create mode 100644 src/deletionconfirmationdlg.h create mode 100644 src/dnsupdater.cpp create mode 100644 src/dnsupdater.h create mode 100644 src/downloadfromurldlg.h create mode 100644 src/downloadfromurldlg.ui create mode 100644 src/downloadthread.cpp create mode 100644 src/downloadthread.h create mode 100644 src/executionlog.cpp create mode 100644 src/executionlog.h create mode 100644 src/executionlog.ui create mode 100644 src/filesystemwatcher.h create mode 100644 src/geoip/README create mode 100644 src/geoip/geoip.pri create mode 100644 src/geoip/geoip.qrc create mode 100644 src/geoip/geoipmanager.cpp create mode 100644 src/geoip/geoipmanager.h create mode 100644 src/gpl.html create mode 100644 src/headlessloader.h create mode 100644 src/hidabletabwidget.h create mode 100644 src/ico.cpp create mode 100644 src/ico.h create mode 100644 src/iconprovider.cpp create mode 100644 src/iconprovider.h create mode 100644 src/icons.qrc create mode 100644 src/lang.qrc create mode 100644 src/lang/qbittorrent_ar.qm create mode 100644 src/lang/qbittorrent_ar.ts create mode 100644 src/lang/qbittorrent_bg.qm create mode 100644 src/lang/qbittorrent_bg.ts create mode 100644 src/lang/qbittorrent_ca.qm create mode 100644 src/lang/qbittorrent_ca.ts create mode 100644 src/lang/qbittorrent_cs.qm create mode 100644 src/lang/qbittorrent_cs.ts create mode 100644 src/lang/qbittorrent_da.qm create mode 100644 src/lang/qbittorrent_da.ts create mode 100644 src/lang/qbittorrent_de.qm create mode 100644 src/lang/qbittorrent_de.ts create mode 100644 src/lang/qbittorrent_el.qm create mode 100644 src/lang/qbittorrent_el.ts create mode 100644 src/lang/qbittorrent_en.qm create mode 100644 src/lang/qbittorrent_en.ts create mode 100644 src/lang/qbittorrent_es.qm create mode 100644 src/lang/qbittorrent_es.ts create mode 100644 src/lang/qbittorrent_fi.qm create mode 100644 src/lang/qbittorrent_fi.ts create mode 100644 src/lang/qbittorrent_fr.qm create mode 100644 src/lang/qbittorrent_fr.ts create mode 100644 src/lang/qbittorrent_gl.qm create mode 100644 src/lang/qbittorrent_gl.ts create mode 100644 src/lang/qbittorrent_hr.qm create mode 100644 src/lang/qbittorrent_hr.ts create mode 100644 src/lang/qbittorrent_hu.qm create mode 100644 src/lang/qbittorrent_hu.ts create mode 100644 src/lang/qbittorrent_hy.qm create mode 100644 src/lang/qbittorrent_hy.ts create mode 100644 src/lang/qbittorrent_it.qm create mode 100644 src/lang/qbittorrent_it.ts create mode 100644 src/lang/qbittorrent_ja.qm create mode 100644 src/lang/qbittorrent_ja.ts create mode 100644 src/lang/qbittorrent_ko.qm create mode 100644 src/lang/qbittorrent_ko.ts create mode 100644 src/lang/qbittorrent_lt.qm create mode 100644 src/lang/qbittorrent_lt.ts create mode 100644 src/lang/qbittorrent_nb.qm create mode 100644 src/lang/qbittorrent_nb.ts create mode 100644 src/lang/qbittorrent_nl.qm create mode 100644 src/lang/qbittorrent_nl.ts create mode 100644 src/lang/qbittorrent_pl.qm create mode 100644 src/lang/qbittorrent_pl.ts create mode 100644 src/lang/qbittorrent_pt.qm create mode 100644 src/lang/qbittorrent_pt.ts create mode 100644 src/lang/qbittorrent_pt_BR.qm create mode 100644 src/lang/qbittorrent_pt_BR.ts create mode 100644 src/lang/qbittorrent_ro.qm create mode 100644 src/lang/qbittorrent_ro.ts create mode 100644 src/lang/qbittorrent_ru.qm create mode 100644 src/lang/qbittorrent_ru.ts create mode 100644 src/lang/qbittorrent_sk.qm create mode 100644 src/lang/qbittorrent_sk.ts create mode 100644 src/lang/qbittorrent_sr.qm create mode 100644 src/lang/qbittorrent_sr.ts create mode 100644 src/lang/qbittorrent_sv.qm create mode 100644 src/lang/qbittorrent_sv.ts create mode 100644 src/lang/qbittorrent_tr.qm create mode 100644 src/lang/qbittorrent_tr.ts create mode 100644 src/lang/qbittorrent_uk.qm create mode 100644 src/lang/qbittorrent_uk.ts create mode 100644 src/lang/qbittorrent_zh.qm create mode 100644 src/lang/qbittorrent_zh.ts create mode 100644 src/lang/qbittorrent_zh_TW.qm create mode 100644 src/lang/qbittorrent_zh_TW.ts create mode 100644 src/lineedit/lineedit.pri create mode 100644 src/lineedit/resources/lineeditimages.qrc create mode 100644 src/lineedit/resources/lineeditimages/clear_left.png create mode 100644 src/lineedit/resources/lineeditimages/search.png create mode 100644 src/lineedit/src/lineedit.cpp create mode 100644 src/lineedit/src/lineedit.h create mode 100644 src/login.ui create mode 100644 src/main.cpp create mode 100644 src/mainwindow.cpp create mode 100644 src/mainwindow.h create mode 100644 src/mainwindow.ui create mode 100644 src/menuicons/128x128/apps/qbittorrent.png create mode 100644 src/menuicons/16x16/apps/qbittorrent.png create mode 100644 src/menuicons/192x192/apps/qbittorrent.png create mode 100644 src/menuicons/22x22/apps/qbittorrent.png create mode 100644 src/menuicons/24x24/apps/qbittorrent.png create mode 100644 src/menuicons/32x32/apps/qbittorrent.png create mode 100644 src/menuicons/36x36/apps/qbittorrent.png create mode 100644 src/menuicons/48x48/apps/qbittorrent.png create mode 100644 src/menuicons/64x64/apps/qbittorrent.png create mode 100644 src/menuicons/72x72/apps/qbittorrent.png create mode 100644 src/menuicons/96x96/apps/qbittorrent.png create mode 100644 src/misc.cpp create mode 100644 src/misc.h create mode 100644 src/powermanagement/powermanagement.cpp create mode 100644 src/powermanagement/powermanagement.h create mode 100644 src/powermanagement/powermanagement.pri create mode 100644 src/powermanagement/powermanagement_x11.cpp create mode 100644 src/powermanagement/powermanagement_x11.h create mode 100644 src/preferences/advancedsettings.h create mode 100644 src/preferences/options.ui create mode 100644 src/preferences/options_imp.cpp create mode 100644 src/preferences/options_imp.h create mode 100644 src/preferences/preferences.h create mode 100644 src/preferences/preferences.pri create mode 100644 src/preview.ui create mode 100644 src/previewlistdelegate.h create mode 100644 src/previewselect.cpp create mode 100644 src/previewselect.h create mode 100644 src/programupdater.cpp create mode 100644 src/programupdater.h create mode 100644 src/properties/downloadedpiecesbar.h create mode 100644 src/properties/peer.ui create mode 100644 src/properties/peeraddition.h create mode 100644 src/properties/peerlistdelegate.h create mode 100644 src/properties/peerlistwidget.cpp create mode 100644 src/properties/peerlistwidget.h create mode 100644 src/properties/pieceavailabilitybar.h create mode 100644 src/properties/properties.pri create mode 100644 src/properties/propertieswidget.cpp create mode 100644 src/properties/propertieswidget.h create mode 100644 src/properties/propertieswidget.ui create mode 100644 src/properties/proplistdelegate.h create mode 100644 src/properties/proptabbar.cpp create mode 100644 src/properties/proptabbar.h create mode 100644 src/properties/trackerlist.cpp create mode 100644 src/properties/trackerlist.h create mode 100644 src/properties/trackersadditiondlg.h create mode 100644 src/properties/trackersadditiondlg.ui create mode 100644 src/qbittorrent.exe.manifest create mode 100644 src/qbittorrent.ico create mode 100644 src/qbittorrent.rc create mode 100644 src/qbittorrent_file.ico create mode 100644 src/qbittorrent_mingw.rc create mode 100644 src/qbittorrent_os2.ico create mode 100644 src/qbittorrent_os2.rc create mode 100644 src/qinisettings.h create mode 100644 src/qmacapplication.cpp create mode 100644 src/qmacapplication.h create mode 100644 src/qtlibtorrent/bandwidthscheduler.h create mode 100644 src/qtlibtorrent/filterparserthread.h create mode 100644 src/qtlibtorrent/qbtsession.cpp create mode 100644 src/qtlibtorrent/qbtsession.h create mode 100644 src/qtlibtorrent/qtlibtorrent.pri create mode 100644 src/qtlibtorrent/qtorrenthandle.cpp create mode 100644 src/qtlibtorrent/qtorrenthandle.h create mode 100644 src/qtlibtorrent/shutdownconfirm.h create mode 100644 src/qtlibtorrent/torrentmodel.cpp create mode 100644 src/qtlibtorrent/torrentmodel.h create mode 100644 src/qtlibtorrent/torrentspeedmonitor.cpp create mode 100644 src/qtlibtorrent/torrentspeedmonitor.h create mode 100644 src/qtlibtorrent/trackerinfos.h create mode 100644 src/qtnotify/notifications.cpp create mode 100644 src/qtnotify/notifications.h create mode 100644 src/qtnotify/notifications.xml create mode 100644 src/qtnotify/qtnotify.pri create mode 100644 src/qtsingleapp/QtLockedFile create mode 100644 src/qtsingleapp/QtSingleApplication create mode 100644 src/qtsingleapp/qtlocalpeer.cpp create mode 100644 src/qtsingleapp/qtlocalpeer.h create mode 100644 src/qtsingleapp/qtlockedfile.cpp create mode 100644 src/qtsingleapp/qtlockedfile.h create mode 100644 src/qtsingleapp/qtlockedfile_unix.cpp create mode 100644 src/qtsingleapp/qtlockedfile_win.cpp create mode 100644 src/qtsingleapp/qtsingleapplication.cpp create mode 100644 src/qtsingleapp/qtsingleapplication.h create mode 100644 src/qtsingleapp/qtsingleapplication.pri create mode 100644 src/qtsingleapp/qtsinglecoreapplication.cpp create mode 100644 src/qtsingleapp/qtsinglecoreapplication.h create mode 100644 src/qtsingleapp/qtsinglecoreapplication.pri create mode 100644 src/reverseresolution.h create mode 100644 src/rss/automatedrssdownloader.cpp create mode 100644 src/rss/automatedrssdownloader.h create mode 100644 src/rss/automatedrssdownloader.ui create mode 100644 src/rss/cookiesdlg.cpp create mode 100644 src/rss/cookiesdlg.h create mode 100644 src/rss/cookiesdlg.ui create mode 100644 src/rss/feedlistwidget.cpp create mode 100644 src/rss/feedlistwidget.h create mode 100644 src/rss/rss.pri create mode 100644 src/rss/rss.ui create mode 100644 src/rss/rss_imp.cpp create mode 100644 src/rss/rss_imp.h create mode 100644 src/rss/rssarticle.cpp create mode 100644 src/rss/rssarticle.h create mode 100644 src/rss/rssarticle_p.h create mode 100644 src/rss/rssdownloadrule.cpp create mode 100644 src/rss/rssdownloadrule.h create mode 100644 src/rss/rssdownloadrulelist.cpp create mode 100644 src/rss/rssdownloadrulelist.h create mode 100644 src/rss/rssfeed.cpp create mode 100644 src/rss/rssfeed.h create mode 100644 src/rss/rssfile.cpp create mode 100644 src/rss/rssfile.h create mode 100644 src/rss/rssfolder.cpp create mode 100644 src/rss/rssfolder.h create mode 100644 src/rss/rssmanager.cpp create mode 100644 src/rss/rssmanager.h create mode 100644 src/rss/rsssettings.h create mode 100644 src/rss/rsssettingsdlg.cpp create mode 100644 src/rss/rsssettingsdlg.h create mode 100644 src/rss/rsssettingsdlg.ui create mode 100644 src/scannedfoldersmodel.cpp create mode 100644 src/scannedfoldersmodel.h create mode 100644 src/searchengine/engineselect.ui create mode 100644 src/searchengine/engineselectdlg.cpp create mode 100644 src/searchengine/engineselectdlg.h create mode 100644 src/searchengine/nova/__init__.py create mode 100644 src/searchengine/nova/engines/__init__.py create mode 100644 src/searchengine/nova/engines/btdigg.png create mode 100644 src/searchengine/nova/engines/btdigg.py create mode 100644 src/searchengine/nova/engines/btjunkie.png create mode 100644 src/searchengine/nova/engines/btjunkie.py create mode 100644 src/searchengine/nova/engines/extratorrent.png create mode 100755 src/searchengine/nova/engines/extratorrent.py create mode 100644 src/searchengine/nova/engines/isohunt.png create mode 100644 src/searchengine/nova/engines/isohunt.py create mode 100644 src/searchengine/nova/engines/kickasstorrents.png create mode 100755 src/searchengine/nova/engines/kickasstorrents.py create mode 100644 src/searchengine/nova/engines/mininova.png create mode 100644 src/searchengine/nova/engines/mininova.py create mode 100644 src/searchengine/nova/engines/piratebay.png create mode 100644 src/searchengine/nova/engines/piratebay.py create mode 100644 src/searchengine/nova/engines/torrentdownloads.png create mode 100644 src/searchengine/nova/engines/torrentdownloads.py create mode 100644 src/searchengine/nova/engines/torrentreactor.png create mode 100644 src/searchengine/nova/engines/torrentreactor.py create mode 100644 src/searchengine/nova/engines/versions.txt create mode 100644 src/searchengine/nova/engines/vertor.png create mode 100755 src/searchengine/nova/engines/vertor.py create mode 100644 src/searchengine/nova/helpers.py create mode 100755 src/searchengine/nova/nova2.py create mode 100755 src/searchengine/nova/nova2dl.py create mode 100644 src/searchengine/nova/novaprinter.py create mode 100644 src/searchengine/nova/socks.py create mode 100644 src/searchengine/pluginsource.h create mode 100644 src/searchengine/pluginsource.ui create mode 100644 src/searchengine/search.qrc create mode 100644 src/searchengine/search.ui create mode 100644 src/searchengine/searchengine.cpp create mode 100644 src/searchengine/searchengine.h create mode 100644 src/searchengine/searchengine.pri create mode 100644 src/searchengine/searchlistdelegate.h create mode 100644 src/searchengine/searchtab.cpp create mode 100644 src/searchengine/searchtab.h create mode 100644 src/searchengine/supportedengines.h create mode 100644 src/sessionapplication.cpp create mode 100644 src/sessionapplication.h create mode 100644 src/smtp.cpp create mode 100644 src/smtp.h create mode 100644 src/speedlimitdlg.h create mode 100644 src/src.pro create mode 100644 src/stacktrace.h create mode 100644 src/statusbar.h create mode 100644 src/torrentadditiondlg.cpp create mode 100644 src/torrentadditiondlg.h create mode 100644 src/torrentadditiondlg.ui create mode 100644 src/torrentcreator/createtorrent.ui create mode 100644 src/torrentcreator/torrentcreator.pri create mode 100644 src/torrentcreator/torrentcreatordlg.cpp create mode 100644 src/torrentcreator/torrentcreatordlg.h create mode 100644 src/torrentcreator/torrentcreatorthread.cpp create mode 100644 src/torrentcreator/torrentcreatorthread.h create mode 100644 src/torrentfilesmodel.h create mode 100644 src/torrentimportdlg.cpp create mode 100644 src/torrentimportdlg.h create mode 100644 src/torrentimportdlg.ui create mode 100644 src/torrentpersistentdata.h create mode 100644 src/tracker/qpeer.h create mode 100644 src/tracker/qtracker.cpp create mode 100644 src/tracker/qtracker.h create mode 100644 src/tracker/tracker.pri create mode 100644 src/tracker/trackerannouncerequest.h create mode 100644 src/trackerlogin.h create mode 100644 src/transferlistdelegate.h create mode 100644 src/transferlistfilterswidget.h create mode 100644 src/transferlistwidget.cpp create mode 100644 src/transferlistwidget.h create mode 100755 src/update_qrc_files.py create mode 100644 src/updownratiodlg.cpp create mode 100644 src/updownratiodlg.h create mode 100644 src/updownratiodlg.ui create mode 100644 src/webui/css/Core.css create mode 100644 src/webui/css/Layout.css create mode 100644 src/webui/css/Tabs.css create mode 100644 src/webui/css/Window.css create mode 100644 src/webui/css/dynamicTable.css create mode 100644 src/webui/css/style.css create mode 100644 src/webui/eventmanager.cpp create mode 100644 src/webui/eventmanager.h create mode 100644 src/webui/html/about.html create mode 100644 src/webui/html/addtrackers.html create mode 100644 src/webui/html/confirmdeletion.html create mode 100644 src/webui/html/download.html create mode 100644 src/webui/html/downloadlimit.html create mode 100644 src/webui/html/filters.html create mode 100644 src/webui/html/index.html create mode 100644 src/webui/html/preferences.html create mode 100644 src/webui/html/preferences_content.html create mode 100644 src/webui/html/prop-files.html create mode 100644 src/webui/html/prop-general.html create mode 100644 src/webui/html/prop-trackers.html create mode 100644 src/webui/html/properties.html create mode 100644 src/webui/html/transferlist.html create mode 100644 src/webui/html/upload.html create mode 100644 src/webui/html/uploadframe.html create mode 100644 src/webui/html/uploadlimit.html create mode 100644 src/webui/httpconnection.cpp create mode 100644 src/webui/httpconnection.h create mode 100644 src/webui/httprequestparser.cpp create mode 100644 src/webui/httprequestparser.h create mode 100644 src/webui/httpresponsegenerator.cpp create mode 100644 src/webui/httpresponsegenerator.h create mode 100644 src/webui/httpserver.cpp create mode 100644 src/webui/httpserver.h create mode 100644 src/webui/json.h create mode 100644 src/webui/scripts/client.js create mode 100644 src/webui/scripts/contextmenu.js create mode 100644 src/webui/scripts/download.js create mode 100644 src/webui/scripts/dynamicTable.js create mode 100644 src/webui/scripts/excanvas-compressed.js create mode 100644 src/webui/scripts/mocha-init.js create mode 100644 src/webui/scripts/mocha-yc.js create mode 100644 src/webui/scripts/mocha.js create mode 100644 src/webui/scripts/mootools-1.2-core-yc.js create mode 100644 src/webui/scripts/mootools-1.2-more.js create mode 100644 src/webui/scripts/parametrics.js create mode 100644 src/webui/scripts/progressbar.js create mode 100644 src/webui/webui.pri create mode 100644 src/webui/webui.qrc create mode 100644 unixconf.pri create mode 100644 version.pri create mode 100644 winconf-mingw.pri create mode 100644 winconf-msvc.pri create mode 100644 winconf.pri diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..e4e981764 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,108 @@ +Author: +* Christophe Dumez + +Contributors: +* Vladimir Golovnev +* Stefanos Antaris +* Mohammad Dib +* Mirco Chinelli +* Ishan Arora +* Arnaud Demaizière +* Grigis Gaëtan +* Christian Kandeler +* Silvan Scherrer + +Code from other projects: +* files src/qtsingleapp/* src/lineedit/* + copyright: Nokia Corporation + license: LGPL + +* files src/ico.cpp src/ico.h + copyright: Malte Starostik + license: LGPL + +* files src/search_engine/socks.py + copyright: Dan Haim + license: BSD + +Images Authors: +* files: src/Icons/*.png + copyright: Gnome Icon Theme + license: GPLv2 + url: http://ftp.acc.umu.se/pub/GNOME/sources/gnome-icon-theme + +* files: src/oxygen/*.png + copyright: Oxygen Icon Theme (KDE) + license: LGPL + url: http://www.oxygen-icons.org + +* files: src/Icons/flags/*.png + copyright: Mark James + license: Public Domain + url: http://www.famfamfam.com + +* files: src/Icons/skin/*.png + files: src/menuicons/YYxYY/*.png + copyright: Mateusz Tobola + license: GPLv2 + +* file: src/Icons/skin/tabs.gif + copyright: Greg Houston + license: MIT + +* file: src/Icons/skin/qbittorrent_mono* + copyright: Daniel Eguren + license: LGPL + +* file: src/search_engine/engines/btjunkie.png + copyright: Downloaded from btjunkie.org + +* file: src/search_engine/engines/isohunt.png + copyright: Downloaded from isohunt.com + +* file: src/search_engine/engines/mininova.png + copyright: Downloaded from mininova.org + +* file: src/search_engine/engines/piratebay.png + copyright: Downloaded from thepiratebay.org + +* file: src/search_engine/engines/torrentreactor.png + copyright: Downloaded from torrentreactor.net + +Translations authors: +* files: src/lang/*.ts + copyright: + - Arabic: SDERAWI (abz8868@msn.com) and sn51234 (nesseyan@gmail.com) + - Armenian: Hrant Ohanyan (hrantohanyan@mail.am) + - Brazilian: Nick Marinho (nickmarinho@gmail.com) + - Bulgarian: Tsvetan & Boyko Bankoff (emerge_life@users.sourceforge.net) + - Catalan: Francisco Luque Contreras (frannoe@ya.com) + - Chinese (Simplified): Guo Yue (yue.guo0418@gmail.com) + - Chinese (Traditional): Yi-Shun Wang (dnextstep@gmail.com) + - Croatian: Oliver Mucafir (oliver.untwist@gmail.com) + - Czech: Jirka Vilim (web@tets.cz) + - Danish: Mathias Nielsen (comoneo@gmail.com) + - Dutch: Pieter Heyvaert (pieter_heyvaert@hotmail.com) + - English: Christophe Dumez (chris@qbittorrent.org) + - Finnish: Niklas Laxström (nikerabbit@users.sourceforge.net) + - French: Christophe Dumez (chris@qbittorrent.org) + - Galician: Marcos Lans (marcoslansgarza@gmail.com) + - German: Niels Hoffmann (zentralmaschine@users.sourceforge.net) + - Greek: Tsvetan Bankov (emerge_life@users.sourceforge.net) and Stephanos Antaris (santaris@csd.auth.gr) + - Hungarian: Majoros Péter (majoros.j.p@t-online.hu) + - Italian: Matteo Sechi (bu17714@gmail.com) + - Japanese: Masato Hashimoto (cabezon.hashimoto@gmail.com) + - Korean: Jin Woo Sin (jin828sin@users.sourceforge.net) + - Lithuanian: Naglis Jonaitis (njonaitis@gmail.com) + - Norwegian: Tomaso + - Polish: Mariusz Fik (fisiu@opensuse.org) + - Portuguese: Nick Marinho (nickmarinho@gmail.com) + - Romanian: Obada Denis (obadadenis@users.sourceforge.net) + - Russian: Nick Khazov (m2k3d0n at users.sourceforge.net) + - Serbian: Anaximandar Milet (anaximandar at operamail.com) + - Slovak: helix84 + - Spanish: Francisco Luque Contreras (frannoe@ya.com) + - Swedish: Daniel Nylander (po@danielnylander.se) + - Turkish: Hasan Yilmaz (iletisim@hedefturkce.com) + - Ukrainian: Andrey Shpachenko (masterfix@users.sourceforge.net) and Oleh Prypin (blaxpirit@gmail.com) + license: GPLv2 diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..148c0b5eb --- /dev/null +++ b/COPYING @@ -0,0 +1,354 @@ +qBittorrent is licensed under the GNU General Public License version 2 with the +addition of the following special exception: + +In addition, as a special exception, the copyright holders give permission to +link this program with the OpenSSL project's "OpenSSL" library (or with +modified versions of it that use the same license as the "OpenSSL" library), +and distribute the linked executables. You must obey the GNU General Public +License in all respects for all of the code used other than "OpenSSL". If you +modify file(s), you may extend this exception to your version of the file(s), +but you are not obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + +---------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Changelog b/Changelog new file mode 100644 index 000000000..78ec6442a --- /dev/null +++ b/Changelog @@ -0,0 +1,883 @@ +* Sun Jun 05 2011 - Christophe Dumez - v2.8.1 + - BUGFIX: Fix Web UI username/password change (Web UI) + +* Thu Jun 02 2011 - Christophe Dumez - v2.8.0 + - FEATURE: Added full libtorrent v0.16 support (uTP, ...) + - FEATURE: Proxy can be disabled for peer connections + - FEATURE: Added support for secure SMTP connection (SSL) + - FEATURE: Added support for SMTP authentication + - FEATURE: Added UPnP/NAT-PMP port forward for the Web UI port + - FEATURE: qBittorrent can update dynamic DNS services (DynDNS, no-ip) + - FEATURE: Display peer connection type in peer list (BT, uTP, Web) + - FEATURE: Added full regex support to RSS downloader + - FEATURE: Added regex help and validation in RSS downloader + - FEATURE: Added HTTPS support to Web UI (Ishan Arora) + - BUGFIX: Change systray icon on the fly (no restart needed) + - BUGFIX: Remember peer-level rate limits (requires libtorrent v0.16) + - BUGFIX: Stop annoncing to trackers an all tiers (more respectful) + - BUGFIX: Stop sharing private trackers with other peers + - BUGFIX: Tracker exchange extension can be disabled + - BUGFIX: Cleaner program exit on system log out + - BUGFIX: Fix possible magnet link parsing problems + - BUGFIX: Fix possible RSS URL parsing problems + - COSMETIC: Added monochrome icon for light themes + +* Sun Mar 20 2011 - Christophe Dumez - v2.7.0 + - FEATURE: Added search field for torrent content + - FEATURE: Added auto-shutdown confirmation dialog + - FEATURE: Added option to skip torrent deletion confirmation (Ville Kiiskinen) + - FEATURE: IP address reported to trackers is now customizable + - FEATURE: Inhibit system sleep when torrents are active (Vladimir Golovnev) + - FEATURE: Added option to bypass Web UI authentication for localhost + - FEATURE: Added option to disable program exit confirmation + - FEATURE: Added per-torrent ratio limiting (Christian Kandeler) + - FEATURE: Torrent content list is now sortable + - BUGFIX: Fix compilation with namespaced Qt (Christian Kandeler) + - BUGFIX: Added length restriction on UI lock password + - COSMETIC: Added monochrome tray icon + - COSMETIC: Improved status bar's style + - OTHER: Make QtDBus dependency optional (X11) + +* Sun Jan 9 2011 - Christophe Dumez - v2.6.0 + - FEATURE: Use system icons (Linux, Qt >= 4.6) + - FEATURE: Improved ETA calculation + - FEATURE: Simplify program preferences + - FEATURE: Software update check can now be disabled (Mac OS X / Windows) + - FEATURE: Display pieces size in torrent properties + - FEATURE: Added "Time Active/Seeded" column to transfer list + - FEATURE: Give feedback regarding the IP filter parsing + - FEATURE: Added a button to reload the IP filter + - FEATURE: Search engine results can now be opened in a Web browser + - FEATURE: Added a search engine plugin to extratorrent.com + - FEATURE: Added a search engine plugin for kickasstorrents.com + - FEATURE: Added auto-suspend upon downloads completion feature + - BUGFIX: Hide unwanted files that have to be partly downloaded + - BUGFIX: Do not allocate space for unwanted files (preallocation mode) + - I18N: Added Galician translation + - COSMETIC: Same deletion confirmation dialog in the GUI and Web UI + - COSMETIC: Simplified the top toolbar + - COSMETIC: Display execution log as a tab instead of a modal window + +* Sun Dec 5 2010 - Christophe Dumez - v2.5.0 + - FEATURE: qBittorrent can now act as a tracker + - FEATURE: New and improved RSS feed automated downloader + - FEATURE: Added feature to shutdown qbittorrent on torrents completion + - FEATURE: Added a torrent import assistant to seed or keep downloading outside torrents + - FEATURE: qBittorrent can update itself from Sourceforge (Windows/Mac OS X only) + - FEATURE: Added a transfer list column to display the current tracker + - FEATURE: Remember the last trackers used in the torrent creation tool + - FEATURE: The optimal piece size is now automatically computed in the torrent creation tool + - FEATURE: Bring up the connection settings when clicking on the connection status icon + - FEATURE: Major code refactoring and optimization + - FEATURE: Added "Amount downloaded/left" columns to transfer list + - FEATURE: Simplified proxy settings + - FEATURE: Optimized and improved the peer country resolution code + - FEATURE: Download first/last pieces first when sequential download is + enabled (Thanks Ahmad) + - FEATURE: Download first/last pieces first now applies to all media files + in the torrent (Thanks Ahmad) + - BUGFIX: Fix SOCKS5 proxy authentication in search engine(closes #680072) + - BUGFIX: Fix two advanced settings (ignore limits on LAN and protocol + overhead inclusion in rate limiter) + - BUGFIX: Fix strict super seeding (was not working) + - BUGFIX: Improve magnet save path handling (closes #683395) + - BUGFIX: Disable overwrite confirmation in torrent addition dialog (closes # 685269) + - COSMETIC: Replaced message box by on-screen notification for download errors + - COSMETIC: Improved the torrent creation tool appearance + - COSMETIC: Use country flags by Mark James (Thanks to Dmytro Pukha) + - COSMETIC: Use bigger alternative speed icon + - OTHERS: Dropped support for Qt <= 4.4 + +* Tue Aug 24 2010 - Christophe Dumez - v2.4.0 + - FEATURE: Added actions to "Move to top/bottom" of priority queue + - FEATURE: Auto-Shutdown on downloads completion + - FEATURE: Email notification on download completion + - FEATURE: Added button to password-lock the UI + - FEATURE: Added label-level Pause/Resume/Delete actions + - FEATURE: Torrents can now be filtered by name + - FEATURE: Run external program on torrent completion + - FEATURE: Detect executable updates in order to advise the user to restart + +* Tue Jul 27 2010 - Christophe Dumez - v2.3.0 + - FEATURE: Simplified torrent root folder renaming/truncating (< v2.3.0 is no longer forward compatible) + - FEATURE: Remember previous save paths in torrent addition dialog + - FEATURE: Max number of half-open connections can now be edited + - FEATURE: Added support for strict super seeding + - FEATURE: The user can force listening on a particular network interface + - FEATURE: Added cookie support for RSS feeds + - FEATURE: User can force tracker reannounce + - FEATURE: Added "No action" setting for double-click action + - FEATURE: Several torrents can be moved at once + - FEATURE: Added error state for torrents (error is displayed in a tooltip) + - FEATURE: Added filter for paused/error torrents + - FEATURE: Add Check/Uncheck all feature in Web UI + - FEATURE: Search engine can now be disabled + - FEATURE: Torrents can be automatically paused once they reach a given ratio + - FEATURE: Several files can now be disabled at once + - FEATURE: Added "Select All/None" buttons to files list + - FEATURE: Added support for BitComet links (bc://bt/...) + - BUGFIX: Hide seeding torrents files priorities in Web UI + - BUGFIX: The user can disable permanently recursive torrent download + - BUGFIX: Peer Exchange status is now correctly reported + - BUGFIX: Use an INI file instead of the registry on Windows (More reliable) + - BUGFIX: Removed client spoofing feature to avoid tracker blacklisting + - COSMETIC: Display peers country name in tooltip + - COSMETIC: Display number of torrents in transfers tab label + - COSMETIC: Simplified program preferences + - COSMETIC: Fix naming of actions opening new dialogs (use Name...) + +* Sun Mar 14 2010 - Christophe Dumez - v2.2.0 + - FEATURE: User can set alternative speed limits for fast toggling + - FEATURE: Bandwidth scheduler (automatically use alternative speed limits for a given period) + - FEATURE: Added "Added/Completed On" columns to transfer list + - FEATURE: Added "Upload/Download limit" columns to transfer list + - FEATURE: Torrent files can be exported to a given directory + - FEATURE: Outgoing ports range can be customized (for QoS) + - FEATURE: User can choose to apply transfer limits on LAN too + - FEATURE: User can choose to include the protocol overhead in transfer limits + - FEATURE: Torrents can be automatically rechecked on completion + - FEATURE: If 2 torrents have the same hash, add new trackers/URL seeds to the existing torrent + - FEATURE: Trackers can be added from Web UI + - FEATURE: Global transfer information are displayed in the new Web UI status bar + - FEATURE: Allow to change the priority of several files at once + - FEATURE: Support for multiple scan folders (Patch by Christian Kandeler) + - BUGFIX: Only one log window can be opened at a time + - BUGFIX: Optimized RSS module memory usage + - BUGFIX: Consider HTTP downloads >1MB as invalid .torrent files and abort + - BUGFIX: Fix Web UI authentication with some browsers + - BUGFIX: Set Web UI ban period to 1 hour + - COSMETIC: Improved style management + +* Mon Jan 18 2010 - Christophe Dumez - v2.1.0 + - FEATURE: Graphical User Interface can be disabled at compilation time (headless running) + - FEATURE: Torrents can be labeled/categorized + - FEATURE: Labeled torrent can be downloaded corresponding subfolders + - FEATURE: Disk cache size can be set from preferences + - FEATURE: Peer Exchange (PeX) can be disabled from preferences + - FEATURE: Append !.qB extension to incomplete files option (libtorrent >= v0.15 only) + - FEATURE: Torrent files/folders can be renamed (torrent addition dialog or files properties) + - FEATURE: uTorrent compatible tracker list support (use torrentz.com url as a default) + - FEATURE: Better proxy support and preferences remodeling + - FEATURE: qBittorrent can identify itself as uTorrent, Vuze or KTorrent (Any stable version) + - FEATURE: Torrents can be renamed in transfer list + - FEATURE: Display torrent addition dialog for magnet links too + - FEATURE: Files contained in a torrent are opened on double click (files panel) + - FEATURE: Added support for magnet links in search engine + - FEATURE: Added vertor.com and torrentdownloads.net search plugins + - FEATURE: Search engine can now use a SOCKS5 proxy + - FEATURE: HTTP proxy support for peer communication + - BUGFIX: Search engine loads new proxy settings without program restart + - BUGFIX: Use XDG folders (.cache, .local) instead of .qbittorrent + - BUGFIX: Added legal notice on startup that the user must accept + - BUGFIX: Protect Web UI authentication against brute forcing + - BUGFIX: Use HTTP digest mode for Web UI authentication (instead of Basic) + - BUGFIX: Properly display torrents with one file in subfolder(s) + - BUGFIX: Display Web UI favicon + - BUGFIX: File priority can be set for finished torrents that have filtered files + - COSMETIC: Use checkboxes to filter torrent content instead of comboboxes + - COSMETIC: Use alternating row colors in transfer list (set in program preferences) + - COSMETIC: Added a spin box to speed limiting dialog for manual input + +* Mon Jan 11 2010 - Christophe Dumez - v2.0.7 + - BUGFIX: Fix 'Add in pause' setting in torrent addition dialog + - BUGFIX: Update RSS feed as soon as feed downloader is enabled + - BUGFIX: RSS Feed downloader ignores articles above maximum number of articles + - BUGFIX: Fix possible bug when deleting a RSS folder + - BUGFIX: Remove persistant data when a RSS feed is deleted + - BUGFIX: RSS filters are now alphabetically sorted + - BUGFIX: Fix crash when renaming currently displayed RSS filter + - BUGFIX: Remove overwriting confirmation when exporting RSS filters since Qt takes care of it + +* Tue Jan 5 2010 - Christophe Dumez - v2.0.6 + - BUGFIX: Fix detection of invalid torrent files + - BUGFIX: Stop catching signals once one has been caught to avoid possible infinite loop + - BUGFIX: Force data recheck whenever a torrent is moved + - BUGFIX: Detect existing torrent data even if incomplete torrents are saved to a different folder + - COSMETIC: Improve torrent deletion confirmation dialog so that the text that not get truncated + +* Thu Dec 31 2009 - Christophe Dumez - v2.0.5 + - BUGFIX: Fix crash with downloaded/availability bars when the torrent has too many pieces + +* Wed Dec 30 2009 - Christophe Dumez - v2.0.4 + - BUGFIX: Fix PeerGuardian .p2b binary filter support + - BUGFIX: Fix possible crash when closing a search engine tab + - BUGFIX: Make sure service port does not change + - BUGFIX: Fix possible DHT port saving issue + - BUGFIX: Fix communication between qBittorrent and Web UI (Qt 4.6) + - BUGFIX: Use Wildcard matching instead of full regex in RSS feed downloader + - BUGFIX: Fix code for listening on a random port whenever it failed to listen on the one defined + - BUGFIX: Use global maximum transfer rates as maximum values in per-torrent speed limiting dialogs + - BUGFIX: Fix global download rate limiting from Web UI + - COSMETIC: Display a disconnected icon in status bar whenever qBittorrent failed to listen on the port defined + +* Wed Dec 23 2009 - Christophe Dumez - v2.0.3 + - BUGFIX: Minor cosmetic fix to program preferences + - BUGFIX: Fix "Temp path" button in program preferences + - BUGFIX: Handle paths with [~, ., ..] properly + - BUGFIX: Trackers are now displayed for torrents without metadata + - BUGFIX: Fix issue with speed limiting (unlimited was not handled properly) + - BUGFIX: Use the save path set in program preferences as a default in torrent addition dialog + +* Fri Dec 18 2009 - Christophe Dumez - v2.0.2 + - BUGFIX: Fix .qbittorrent folder not being created (critical bug introduced in v2.0.1 that makes qBittorrent unusuable for new users) + - BUGFIX: Fix RSS Feed downloader for some feeds + - BUGFIX: Do not use home folder as a fallback when the save path is not accessible + - BUGFIX: Fix Mininova, ThePirateBay search engine plugins + - BUGFIX: Read RSS articles are remembered on restart for feeds with no torrents attached + +* Sun Dec 13 2009 - Christophe Dumez - v2.0.1 + - BUGFIX: µTorrent user-agent is now spoofed correctly + - BUGFIX: Fix column hiding behavior when queueing system is disabled + - BUGFIX: Fix link to plugins.qbittorrent.org in plugins dialog + - BUGFIX: ~/qBT_dir is created only when it is actually used + - BUGFIX: Fix possible missing slot message (toggleSelectedTorrentsSuperSeeding) + - BUGFIX: Fix possible crash in torrent properties (files) + - BUGFIX: Added Hex Magnet Links support (Thanks Haypo) + +* Thu Dec 10 2009 - Christophe Dumez - v2.0.0 + - FEATURE: Added program option to disable splash screen + - FEATURE: Dropped dependency on libcurl and libzzip + - FEATURE: Display more information regarding the torrent in its properties + - FEATURE: Various optimizations to save CPU and memory + - FEATURE: Folder scanning now works with CIFS and NFS mounted folders + - FEATURE: Speed up qBittorrent startup and shutdown + - FEATURE: Display per-torrent peer list + - FEATURE: Make sure torrent files are always sorted by name + - FEATURE: Seeds and Peers columns are now sortable + - FEATURE: Torrents can be rechecked from Web UI (Stephanos Antaris) + - FEATURE: New peers can manually be added to the torrents + - FEATURE: Support per-peer rate limiting + - FEATURE: Support peer manual ban + - FEATURE: Display total amounts transferred in status bar + - FEATURE: Display trackers status as well as error/warning messages + - FEATURE: Display the number of peers returned by each tracker & DHT/PeX/LSD + - FEATURE: Global upload/download speeds can be capped from status bar (µTorrent behavior) + - FEATURE: Added option to download first and last piece of a torrent main file first (for preview) + - FEATURE: Graphically display piece availability in torrent properties + - FEATURE: Dropped Qt 4.3 support (Qt >= 4.4 is now required) + - FEATURE: Display close tab button into the tabs in search engine (Qt >= 4.5 only) + - FEATURE: Show official documentation when pressing F1 key + - FEATURE: Search engine plugins now handle HTTP protocol gzip compression + - FEATURE: Enabled lazy bitfield as a counter-measure for ISP speed throttling + - FEATURE: Fall back to a random port if qBittorrent could not listen on the chosen port + - FEATURE: Announce to all trackers specified for a torrent (µTorrent behavior) (libtorrent >= v0.15 only) + - FEATURE: Added per-torrent super seeding mode (libtorrent >= v0.15 only) + - FEATURE: Support for storing symbolic links in .torrent files (libtorrent >= v0.15 only) + - FEATURE: Support for uTorrent interpretation of multi-tracker torrents (libtorrent >= v0.15 only) + - FEATURE: Handle torrents with duplicate filenames (libtorrent >= v0.15 only) + - FEATURE: Support for merkle hash tree torrents (.merkle.torrent) (libtorrent >= v0.15 only) + - FEATURE: Metadata download from swarm is now compatible with µtorrent (libtorrent >= v0.15 only) + - FEATURE: Support tracker exchange between peers (libtorrent >= v0.15 only) + - FEATURE: Better http seed support (libtorrent >= v0.15 only) + - FEATURE: Tracker connections are now also subject to IP filtering (libtorrent >= v0.15 only) + - FEATURE: Include DHT traffic in the rate limiter (libtorrent >= v0.15 only) + - FEATURE: Support for bitcomet padding files (libtorrent >= v0.15 only) + - FEATURE: Option to skip file checking and start seeding immediately in torrent addition dialog (Stephanos Antaris) (libtorrent >= v0.15 only) + - BUGFIX: Made sure qBittorrent does not scrape the tracker too frequently (libtorrent >= 0.15 only) + - BUGFIX: Fix Paste action in search engine field + - BUGFIX: Fix possible double free in search engine destructor + - BUGFIX: Properly handle trackers error messages + - WEB UI: Remodeled Web UI to match new qBittorrent UI (Properties and preferences available) + - WEB UI: Added internationalization support + - WEB UI: Reduced computation in Javascript (do this one server side instead) + - WEB UI: Fixed Transfer list flickering + - WEB UI: Password is now stored as md5 + - I18N: Added Serbian translation (By Anaximandar Milet) + - COSMETIC: Merged download / upload lists + - COSMETIC: Torrents can be filtered based on their status + - COSMETIC: Torrent properties are now displayed in main window + - COSMETIC: Made program preferences scrollable for usability on small screens (e.g. netbooks) + - COSMETIC: Added a "torrent status" column to transfer list + - COSMETIC: Display Seeds and Peers in two separate columns + - COSMETIC: New deletion confirmation dialog (Merged delete/delete permanently actions) + - COSMETIC: Improved status bar layout spacing + - COSMETIC: Display speeds with more user friendly units instead of always using KiB/s + - COSMETIC: New torrent status icons by Mateusz Tolola + - COSMETIC: Make use of libnotify if available for system notifications (Ubuntu, ...) + +* Tue Nov 17 2009 - Christophe Dumez - v1.5.6 + - BUGFIX: RSS feed articles can now be displayed using keyboard arrows + - BUGFIX: RSS feed downloader can only process unread articles now + - BUGFIX: Fixed memory leak in RSS parser + - BUGFIX: Fixed possible crash in search autocompletion + - BUGFIX: Improved ETA calculation for big torrents + - BUGFIX: Fixed per-torrent speed limiting + +* Wed Nov 4 2009 - Christophe Dumez - v1.5.5 + - BUGFIX: Fixed man page + - BUGFIX: Fix crash on torrent addition (if libtorrent-rasterbar has debug enabled) + - BUGFIX: Fix trackers addition to torrents (bug introduced in v1.5.4) + - BUGFIX: Suppress compilation warning regarding sortNewsList() not being used + - BUGFIX: Make sure scan folder is different than qBittorrent backup directory to avoid torrents deletion + - BUGFIX: Added safety mecanism which adds the torrents back to the list in case qbittorrent-resume.conf gets deleted or corrupted. + +* Sun Oct 25 2009 - Christophe Dumez - v1.5.4 + - BUGFIX: Updated man page + - BUGFIX: Fixed possible crash with torrents containing unicode characters + - BUGFIX: Fixed problem when disabling systray integration and starting minimized + - BUGFIX: Fixed PirateBay search plugin + - BUGFIX: Using Download button in search results list now downloads the right torrents + - BUGFIX: The search results list is no longer sorted automatically when a row color is updated + +* Wed Sep 30 2009 - Christophe Dumez - v1.5.3 + - BUGFIX: Fix a possible crash when pausing then deleting a torrent quickly + - BUGFIX: Fix a race condition in folder scanning and torrent downloader + - BUGFIX: Hide download url column in search results + - BUGFIX: Fix a crash when scanned directory does not exist + - BUGFIX: Fix compilation on Mac OS + - BUGFIX: Added a command line parameter to disable splash screen + - BUGFIX: Ignore permanent deletion button when no torrent is selected + - BUGFIX: When a selected torrent is deleted, select next suitable torrent + +* Sun Sep 20 2009 - Christophe Dumez - v1.5.2 + - BUGFIX: Some torrents were pausing for no reason + - I18N: Updated Korean translation + +* Thu Sep 7 2009 - Christophe Dumez - v1.5.1 + - BUGFIX: Fix crash in torrent addition dialog when save path does not exist (closes #425227) + - BUGFIX: Fix downloading from URL (broken in v1.5.0) + - BUGFIX: Pause torrents in error state + +* Thu Sep 3 2009 - Christophe Dumez - v1.5.0 + - FEATURE: Added Magnet URI support + - FEATURE: Search engine supports category-based requests + - FEATURE: Make use of torrent enclosure in RSS feeds for direct download + - FEATURE: Implemented a RSS feed downloader with filter support + - FEATURE: Save old RSS item to hard disk to remember them on start up + - FEATURE: Display free disk space in torrent addition dialog + - FEATURE: In torrent addition from URL, paste clipboard content if it contains an URL + - FEATURE: RSS feeds URLs can now be copied to clipboard + - FEATURE: RSS feeds can now be grouped into folders + - FEATURE: Added "Unread" item to RSS feed list to display all unread news + - FEATURE: If a torrent contains a torrent file, process downloaded torrent file too + - FEATURE: A random listening port can be chosen automatically + - BUGFIX: torrent resume code rewrited + - BUGFIX: Fixed uTorrent spoofing code + - BUGFIX: Greatly improved column sorting code + - BUGFIX: Possibility to create trackerless torrents + - BUGFIX: Better item coloring in torrent content filtering dialog + - COSMETIC: Redesigned search tab to improve usability + - COSMETIC: Redesigned RSS tab to improve usability + - COSMETIC: Improved tracker errors readability + +* Sun Aug 21 2009 - Christophe Dumez - v1.4.1 + - BUGFIX: Fix problems when changing save path (if using temporary download folder) + - BUGFIX: Display real save path instead of the temporary one in torrent properties + - BUGFIX: Catching invalid_handle exception to avoid rare crashes + - BUGFIX: Fixed popup menu position in RSS feeds list + - BUGFIX: Don't save RSS feed state if it could not be updated + +* Thu Aug 13 2009 - Christophe Dumez - v1.4.0 + - FEATURE: Display swarm information in lists + - FEATURE: Allow to define temporary download folder + - FEATURE: Display total amount of uploaded data in finished list + - FEATURE: Resizing a column in a search results tab affects all tabs + - FEATURE: Search results tab columns are now remembered upon startup + - FEATURE: Added right click menu in search engine to clear completion history + - FEATURE: Allow to set a different port for DHT (UDP) than the one used for Bittorrent + - FEATURE: Updated spoofing code to avoid trackers ban + - BUGFIX: Provide more helpful explanation when an I/O error occured + - BUGFIX: Stop enforcing UTF-8 and use system locale instead + - COSMETIC: Redesigned program preferences + - COSMETIC: Updated icons set + +* Fri Jul 24 2009 - Christophe DUMEZ - 1.3.5 + - BUGFIX: Made IP filter parser more robust + - BUGFIX: Fixed torrent creation tool + - BUGFIX: Fixed possible overflow in progress calculation in arborescence.h + - BUGFIX: Save properties window size, position, columns width and restore them + - BUGFIX: Set a minimum default width for NAME column in properties + - BUGFIX: Remember visual indexes of columns in transfer lists + +* Sun Jul 12 2009 - Christophe DUMEZ - v1.3.4 + - BUGFIX: Fixed IP filter file parsing on 64bits + - BUGFIX: Suppressed QLayout: Attempting to add QLayout "" to properties "properties" warning message when opening a properties dialog + - BUGFIX: Fixed a little bug in search engine plugins helper file + - BUGFIX: Fixed compilation problems with Qt 4.3 + - BUGFIX: Percentages no longer disapear with default cleanlooks style + - BUGFIX: Cleanly fixed popup menus position in lists (no more workarounds) + - BUGFIX: Fixed memory leak in search engine + - BUGFIX: Torrents with an infinite ratio are no longer affected by ratio_limit set in program preferences + - BUGFIX: Display a ratio of 0.0 if total_upload and total_download are both 0 + - BUGFIX: Remove last separator in top tool bar + - BUGFIX: Tuned lists properties to make sure display is correct + - COSMETIC: Display date as well as time in log window + +* Sun Apr 5 2009 - Christophe Dumez - v1.3.3 + - BUGFIX: Fixed Web UI torrent upload form + - BUGFIX: Fixed unicode support in search engine + - BUGFIX: Fixed search engine bug that prevented a torrent from appearing more than once among all tabs + - LICENSE: Added an exception to the license regarding OpenSSL. + - I18N: Updated Finnish translation + +* Sat Mar 7 2009 - Christophe Dumez - v1.3.2 + - BUGFIX: Fix top toolbar disabling + - BUGFIX: Fix building with Qt 4.5 + - BUGFIX: RSS items read status is now remembered upon restart + +* Mon Jan 26 2009 - Christophe Dumez - v1.3.1 + - BUGFIX: Torrents paused due to an I/O error were displayed as queued + - BUGFIX: qBittorrent now prints backtrace in terminal when segfaulting + - BUGFIX: Fixed files progress display in torrent properties + - BUGFIX: Improved torrent ratio calculation + - BUGFIX: Fixed possible crash when parsing filter file + - BUGFIX: Made some code optimization + - BUGFIX: Fixed download/upload speed decrease problems + - I18N: Updated Finnish, Bulgarian and Greek translations + +* Fri Jan 9 2009 - Christophe Dumez - v1.3.0 + - FEATURE: Based on libtorrent-rasterbar v0.14.2 + - FEATURE: Improved ratio calculation system + - FEATURE: Torrent creation code cleanup + - FEATURE: Allow to set maximum number of active seeds (queueing) + - FEATURE: Now seeds priorities are handled automatically by libtorrent-rasterbar (queueing) + - FEATURE: Code cleanup and optimization (save memory and cpu) + - FEATURE: ETA calculation now relies on average speed over all sessions + - FEATURE: Allow to force rechecking torrents + - FEATURE: Added support for 2 new extensions (uTorrent metadata and smart ban plugin) + - FEATURE: Allow to change the save path of torrents after addition + - FEATURE: Got rid of libmagick++ dependency + - FEATURE: Updated Web interface to MochaUI v0.9.5 + - FEATURE: Added notification in WebUI when qBittorrent is not reachable + - FEATURE: Rewrote folder scanning code (Now uses a filesystem watcher) + - FEATURE: Added torrent deletion from hard drive function in Web UI + - FEATURE: Added queueing priority actions in Web UI + - FEATURE: Display progress using progress bars in Web UI + - BUGFIX: Made usage of fastresume data more reliable + - BUGFIX: qBittorrent shutdown is now faster + - BUGFIX: Fixed several memory leaks + - BUGFIX: WebUI is now working with IE7 + - BUGFIX: Fixed spacing problem in toolbar when toggling its visibility + - BUGFIX: Fixed some compilation and Qt4 warnings + - BUGFIX: Do not use an addition dialog for torrents from folder scanning + - BUGFIX: Catch SIGTERM to exit cleanly (e.g. computer shutdown) + - BUGFIX: Improved proxy support code + - BUGFIX: Fixed systray icon tooltip on Windows + - BUGFIX: Proxy settings are now saved even if disabled + +* Sun Nov 9 2008 - Christophe Dumez - v1.2.1 + - BUGFIX: Fixed possible crash when deleting a torrent permanently + - BUGFIX: Queued_for_checking torrents were not displayed as checking in seeding list + - BUGFIX: Speed up startup time when having a lot of torrents + +* Wed Oct 29th 2008 - Christophe Dumez - v1.2.0 + - FEATURE: Torrent queueing system (with priorities) + - FEATURE: The number of DHT nodes is displayed + - FEATURE: RSS can now be disabled from program preferences + - FEATURE: Added collapse/expand all buttons in addition and properties dialogs + - FEATURE: Can have different proxies for Bittorrent and search engine + - FEATURE: Allow multiple item selection in Web UI transfer list + - FEATURE: Moved uploads to a separate list in Web UI + - BUGFIX: Totally rewritten Web UI list refresh system (fixed memory leak) + - BUGFIX: Disable ETA calculation when ETA column is hidden + - BUGFIX: Removed "disconnected" connection state, detection was far from perfect + - BUGFIX: Torrents are no longer starting from scratch when changing default save path (when torrent addition dialog is disabled) + - BUGFIX: Single instance code is now more reliable on Qt >= 4.4 + - COSMETIC: Transfer speed, ratio, connection status and DHT nodes are displayed in status bar + - COSMETIC: RSS Tab is now hidden as a default + - COSMETIC: Allow to hide or display top toolbar + - COSMETIC: Log is now in a separate dialog + +* Sun Sept 14 2008 - Christophe Dumez - v1.1.4 + - FEATURE: DHT is no longer used as fallback only + - FEATURE: Ported WebUI to Mootools v1.2 + - BUGFIX: Fixed 'start seeding after torrent creation' feature + - BUGFIX: Fixed compilation with boost v1.36 + - BUGFIX: Some code optimization + - BUGFIX: Fixed memory leak in Web UI + - BUGFIX: Fixed problems with column sorting + - BUGFIX: Improved code for pausing torrents on startup + - BUGFIX: Torrent addition dialog is now disabled for downloads from WebUI + - BUGFIX: Give focus to input field in WebUI download dialog + +* Tue Aug 26 2008 - Christophe Dumez - v1.1.3 + - BUGFIX: Fixed ratio saving for seeding torrents + - I18N: Added czech and traditional chinese translations + +* Sun Aug 17 2008 - Christophe Dumez - v1.1.2 + - BUGFIX: Fixed progress calculation + - BUGFIX: Fixed finished torrent detection + +* Fri Aug 01 2008 - Christophe Dumez - v1.1.1 + - BUGFIX: Fixed bad resource file for icons + +* Fri Aug 01 2008 - Christophe Dumez - v1.1.0 + - FEATURE: Web interface to control qbittorrent (Ishan Arora) + - FEATURE: Can spoof Azureus peer id to avoid ban + - FEATURE: Allow to hide/show some columns in download and seeding lists + - FEATURE: Option to start qBittorrent minimized in systray + - FEATURE: Multi-tab support in search engine (Grigis Gaëtan) + - FEATURE: Allow to define double-click actions in torrents lists + - FEATURE: Allow to open torrent destination folder + - FEATURE: Real progress bar in torrent properties that displays downloaded pieces + - FEATURE: Allow to buy downloads using ShareMonkey + - FEATURE: Display if UPnP/NAT-PMP was successful or not + - FEATURE: Threadified torrent creation + - FEATURE: Improved eMule DAT ip filter parser + - FEATURE: Added support for PeerGuardian p2p filters (text) + - FEATURE: Added support for PeerGuardian p2b filters (binary) + - FEATURE: Allow to customize folder scan interval + - FEATURE: Allow to add several trackers at once + - BUGFIX: Allow to run one instance of qBittorrent per user + - BUGFIX: Do not display seeds number in seeding list (always 0) + - BUGFIX: Threadified IP filter file parser to avoid GUI freeze + - BUGFIX: Ask if we want to redownload if content was deleted from hard drive + - BUGFIX: Added missing copyright/licensing information for some files + - BUGFIX: qBittorrent is no longer conflicting with rTorrent (libtorrent renamed to libtorrent-rasterbar) + - COSMETIC: Do not display progress bar in seeding list (always 100%) + - COSMETIC: Added a progress bar for torrent creation + - COSMETIC: Display tracker errors in a cleaner way + - COSMETIC: Display "unpaused/total_torrent" in download/upload tabs + - COSMETIC: Allow to resize RSS column + - COSMETIC: Global UP/DL speeds and ratio are displayed above tabs + - COSMETIC: Use infinity symbol for ETA when time is infinite + +* Fri Apr 11 2008 - Christophe Dumez - v1.0.0 + - FEATURE: Based on new libtorrent v0.13 + - FEATURE: Added UPnP / NAT-PMP port forwarding support + - FEATURE: Added encryption support (compatible with Azureus) + - FEATURE: Bittorrent FAST extension support + - FEATURE: Added RSS support + - FEATURE: Support files prioritizing in a torrent + - FEATURE: Brand new search engine plugins system + - FEATURE: Filtered files don't appear on hard disk anymore + - FEATURE: Finished torrents are now moved to another tab for seeding + - FEATURE: Display more infos about the torrent in its properties + - FEATURE: Allow the user to edit torrents' trackers + - FEATURE: Allow user to change qBT's style (Plastique, Cleanlooks, Motif, CDE, MacOSX, WinXP) + - FEATURE: Allow the user to disable system tray integration + - FEATURE: Search engine is now using one thread per website for faster results + - FEATURE: Improved a lot the torrent creation module + - FEATURE: Allow to set upload/download limit per torrent (right click) + - FEATURE: Ask for exit confirmation only if download list is not empty + - FEATURE: Allow to use a proxy for trackers / web seeds / peers / DHT connections + - FEATURE: Supports SOCKS5 proxies as well as HTTP ones + - FEATURE: Better systems integration (buttons, dialogs...) + - FEATURE: Filtered files are not allocated on the hard-drive anymore (sparse file support) + - FEATURE: IPs blocked by filter are now logged in GUI + - FEATURE: Added a way to link against static libtorrent (useful for deb packages) + - FEATURE: Allow to set global upload/download limits from tray icon menu + - FEATURE: IPv6 is now fully supported + - FEATURE: Real torrent share ratio is now displayed in transfer list + - FEATURE: Added keyboard shortcuts for main actions (see wiki) + - FEATURE: Added a popup menu to set priority for multiple files at once + - FEATURE: Improved a lot downloading from urls (using libcommoncpp2 instead of libcurl) + - FEATURE: A search request can now be terminated by another + - FEATURE: User is now warned when fast resume data was rejected + - FEATURE: Url seeds are now displayed in torrent properties and are editable + - FEATURE: Allow to drag 'n drop urls on the main window + - FEATURE: Improved search engine (multipage support in all plugins) + - FEATURE: Added BTJunkie search engine plugin + - FEATURE: Added an option to force full disk allocation for all torrents + - FEATURE: Added an option to add torrents in paused state + - FEATURE: Added an option to set the max number of connections per torrent + - FEATURE: Added an option to set the max number of uploads per torrent + - FEATURE: Added an option to automatically delete torrents when they reach a given ratio (>= 1.0) + - FEATURE: Added an option to display current transfer speeds in title bar + - FEATURE: Torrent content is now displayed as a tree + - I18N: Added Hungarian translation + - I18N: Added Brazilian translation + - BUGFIX: Progress of paused torrents is now correct on restart + - BUGFIX: Progress column gets sorted on restart it is was during last execution + - BUGFIX: Made ETA more reliable using stats instead of instant values + - BUGFIX: Remove torrent from hard drive used to delete parent folder if empty + - BUGFIX: Fixed a crash when filtering all the files in a torrent + - BUGFIX: Reload torrent only when necessary (properties) + - BUGFIX: qBittorrent is not exiting anymore when a dialog is closed and main window is hidden + - BUGFIX: Search plugin update is not making the GUI freeze anymore (moved to a thread) + - BUGFIX: DHT settings were not saved correctly + - BUGFIX: Workaround to build on Fedora system (pkg-config problem) + - BUGFIX: search plugin update - do not display only last version changelog + - BUGFIX: Search plugin update - fixed missing new lines in changelog + - BUGFIX: The number of search results was not reset when clicking on 'Clear' button + - BUGFIX: Update torrent progress when its content changed (filtered files) + - BUGFIX: Improved the way menu icons are installed to avoid problems on some systems + - BUGFIX: Improved incremental download + - BUGFIX: Improved unicode support + - BUGFIX: Made torrent deletion from hard-drive safer + - BUGFIX: Prevent downloadFromUrl flooding + - BUGFIX: ETA was wrong for torrents with filtered files + - BUGFIX: Fixed drag'n drop on non-KDE systems + - BUGFIX: Removed build dependency on Python + - BUGFIX: Catching DHT exception in case there is a problem + - COSMETIC: Redesigned torrent properties a little + - COSMETIC: Totally redesigned program preferences + - COSMETIC: Display more logs messages concerning features + - COSMETIC: Improved lists renderers + - COSMETIC: Use a different icon for torrents being checked and for connecting ones + - COSMETIC: Improved some icons + - COSMETIC: Improved systray tooltip style + +* Mon May 07 2007 - Christophe Dumez - v0.9.3 + - BUGFIX: Fixed pause toggle on double-click in download list + - BUGFIX: The torrent size displayed now only takes unfiltered files into account + - BUGFIX: Fixed compiling errors with libtorrent svn (future v0.13 with UPnP enabled) + - BUGFIX: Remember sorted column in download list on restart + - BUGFIX: Small fix in the german translation + - BUGFIX: Some fixes in slovak translation + +* Tue Apr 10 2007 - Christophe Dumez - v0.9.2 + - BUGFIX: Window can now stay maximized on exit + - BUGFIX: Use PKGCONFIG again for configuring libtorrent + - BUGFIX: Allow to compile with libtorrent v0.11 + - BUGFIX: Disabled main window context menu (annoying) + - I18N: Added Japanese translation + - I18N: Updated Turkish translation + +* Wed Apr 04 2007 - Christophe Dumez - v0.9.1 + - BUGFIX: A lot of fixes in configure file + +* Sun Apr 01 2007 - Christophe Dumez - v0.9.0 + - FEATURE: Based on libtorrent v0.12 + - FEATURE: Based on Qt4.2 + - FEATURE: Brand new trayicon from Qt4.2 + - FEATURE: Support uTorrent Peer Exchange (PeX - exchanges peers between clients) + - FEATURE: Added a menu action to visit qBittorrent website + - FEATURE: Added a menu action to report a bug in qBittorrent + - FEATURE: Improved the way parameters are passed between qBT instances (socket) + - FEATURE: User is warned when hard drive becomes full and downloads are paused + - FEATURE: Number of complete/incomplete sources are now displayed in download list for each torrent + - FEATURE: Implemented close to systray + - FEATURE: Added Autocompletion to search engine + - FEATURE: Splitted BT & GUI parts (huge code rewriting & optimization) + - FEATURE: New parameters for configure file to point to custom locations for libtorrent/libcurl + - FEATURE: Update application style according to the system (WindowsXP, MacOS, X11) + - BUGFIX: Two torrents can now have the same name although they are different (use their hash) + - BUGFIX: Fixed download from url that would fail sometimes + - BUGFIX: Save directory was reset to default when filtering files in torrent + - BUGFIX: Force a refresh of download list when the window is shown (avoid delay) + - BUGFIX: Fixed deletion from hard drive (failed for non-empty folders) + - BUGFIX: qBittorrent now identifies its version correctly on the network + - BUGFIX: Preventing GUI from freezing when deleting a download permanently + - BUGFIX: Fixed directory scanning (stop trying to download the same files several times) + - BUGFIX: Fixed bad loading of scan dir in option (widgets still disabled) + - BUGFIX: Threads are now stopped cleanly before their destruction + - BUGFIX: Create Options object only when necessary (to save memory) + - BUGFIX: Let libtorrent store the torrent handles (save memory) + - BUGFIX: Set DHT Port only when DHT is enabled + - BUGFIX: Made ipfilter.dat parser less sensitive to errors + - BUGFIX: Bring main window to foreground when asking for exit confirmation + - I18N: Added Danish translation + - I18N: Better internationalization thanks to dynamic text support + - COSMETIC: Replaced OSD messages by Qt4.2 systray messages + +* Tue Nov 28 2006 - Christophe Dumez - v0.8.0 + - FEATURE: Added a torrent addition dialog + - FEATURE: Allow user to change DHT port + - FEATURE: Added an action to remove files from download list and hard drive too + - FEATURE: Rewritten intensively options code + - FEATURE: Remember GUI settings in a cleaner way on restart + - I18N: Added Finnish translation + - I18N: Improved Italian translation a lot + - BUGFIX: Enabled debug with Qt 4.2.1 too because Trolltech didn't fix their bug yet + - BUGFIX: Fixed layout in torrent properties + - BUGFIX: Made right click menu work for multiple selection in DL list + - BUGFIX: Fixed utf-8 support in paths and filenames + - BUGFIX: Could only listen on the first IP of the given range + - COSMETIC: Connection status in toolBar is not clickable anymore + - COSMETIC: Displaying save path in torrent properties window + - COSMETIC: Reworked options window a little + - COSMETIC: Remember mainwindow position during last execution + +* Mon Oct 16 2006 - Christophe Dumez - v0.7.1 + - I18N: Updated French, Polish, Dutch, Swedish, Slovak translations + - BUGFIX: Fixed Seeds/Leechers display in torrent properties + - BUGFIX: Fixed finished torrent state on restart + - BUGFIX: Fixed trayicon with Qt 4.2 + - BUGFIX: Enabling debug when Qt 4.2.0 is detected (because of a bug in this Qt) + - BUGFIX: Fixed new lines in log widget with Qt 4.2 + - BUGFIX: Display errors to stderr instead of stdout + - BUGFIX: Forgot to catch invalid_handle exception thrown by libtorrent + - BUGFIX: Close torrents properties windows when they are deleted + - BUGFIX: Fixed prefix in Makefile + +* Fri Oct 13 2006 - Christophe Dumez - v0.7.0 + - FEATURE: Based on new libtorrent v0.11 (a lot of bugfixes, new features) + - FEATURE: Added DHT (Trackerless - Decentralized BT) support + - FEATURE: Audio/Video File previewing while downloading + - FEATURE: Added support for incremental download (slower but great for previewing) + - FEATURE: Added Tracker authentication support + - FEATURE: Defined qBittorrent fingerprint so that it doesn't use libtorrent fingerprint anymore + - FEATURE: Display an explicit error message when a download from url fails + - FEATURE: Allow the download multiple torrents from urls at once + - FEATURE: New context menu on main window (Add, Start all, Pause all, Exit...) + - FEATURE: Now supports one new search engines (MegaNova) + - FEATURE: Rewritten search engine plugin (by fab31) + - FEATURE: Rewritten parts of the download/search lists to improve performance + - FEATURE: Individual share ratio is now displayed in each torrent properties. + - FEATURE: Tuned default settings to improve download speed + - FEATURE: Downloading from an URL will retry 10 times if too many users. + - FEATURE: Now remembers filtered pieces in a torrent on restart + - FEATURE: Now updating pieces progress in real time in torrent properties + - I18N: Added Norwegian translation + - BUGFIX: Fixed a memory leak when pressing OK in torrent properties + - BUGFIX: Improved code so that GUI never freeze during downloading from an url + - BUGFIX: Forgot to remove torrent file from scanned directory when "Clear Finished torrents" is enabled + - BUGFIX: Fixed multiple selection in torrent content tab + - BUGFIX: Improved configure file (detects libboost-thread) + - BUGFIX: Fixed trayicon on some window managers (Gnome, XFCE) + - BUGFIX: Always set maximum limit for connection depending on system + - BUGFIX: Fixed Memory leaks in search engine + - BUGFIX: Remove torrent file from scanned directory if it is already in download list + - BUGFIX: Fixed possible segfault on loading due to columns size loading + - BUGFIX: Fixed problems that could happen with delete selection action + - BUGFIX: Fixed an arithmetic exception that could happen in ETA calculation + - BUGFIX: Fixed Isohunt search engine + - BUGFIX: Fixed download from URL function (was buggy) + - BUGFIX: Fixed download button in search engine + - BUGFIX: Fixed selective download + - BUGFIX: Fixed memory leaks in torrent properties + - BUGFIX: Fixed tooltip behaviour for trayicon + - BUGFIX: Fixed Ipfilter.dat loading + - BUGFIX: Not loading options every time we display options anymore + - COSMETIC: Now displaying the number of downloads in tab title + - COSMETIC: Redesigned download from url dialog + - COSMETIC: Added a message to warn user that we started download from an url + - COSMETIC: Renamed main tab from "Downloads" to "Transfers" + - COSMETIC: Improved icons + - COSMETIC: Resized flags in localization settings + - COSMETIC: Improved trayicon image + +* Fri Aug 24 2006 - Christophe Dumez - v0.6.1 + - BUGFIX: Fixed possible segfaults when using context menus + - BUGFIX: Cleanup up context menus code + - BUGFIX: Use best gzip compressing for man page + +* Wed Aug 22 2006 - Christophe Dumez - v0.6.0 + - FEATURE: Rewritten the download list from scratch (more flexible) + - FEATURE: Rewritten the search results list from scratch (more flexible) + - FEATURE: Rewritten the torrent properties list from scratch (more flexible) + - FEATURE: Improved and cleaned up search engine code + - FEATURE: Search results are now displayed in real time (not sequentially) + - FEATURE: Added two command lines parameters (--version, --help) + - FEATURE: Added a popup menu for download list + - FEATURE: Double-click on an item now toggles the paused state of a download + - FEATURE: Improved code to be more portable (Windows & MacOS versions should arrive soon) + - FEATURE: Allow to toggle selected state of a file within a torrent using double-click + - FEATURE: Remember columns width in download and search results lists + - BUGFIX: Don't use pkg-config for libcurl anymore (easier to compile) + - BUGFIX: Fixed ETA calculation when downloading while connecting + - BUGFIX: Download progress is now displayed correctly during first seconds of execution (was 0% before) + - BUGFIX: Code cleanup & optimization + - BUGFIX: Fixed sorting in download list + - BUGFIX: Fixed sorting in search results list + - BUGFIX: Fixed Parameters passing between instances + - BUGFIX: Fixed missing icon for clear action in infoBar popup menu + - BUGFIX: Fixed truncated lines in search results + - BUGFIX: Don't refresh download list when user is in search tab (save CPU) + - BUGFIX: Don't update Progress/DL Speed/ETA for finished downloads (save CPU) + - BUGFIX: Save selected search engines only when they have changed (faster program exit) + - COSMETIC: Increased icon size in toolbar from 24px to 32px + - COSMETIC: Display a progress bar to visualize each download progress + - COSMETIC: Size of each result in search are displayed in user friendly units + - COSMETIC: Display a progress bar to visualize each file progress within a torrent + - COSMETIC: Renamed 'ratio' to 'Session ratio' (makes more sense) + - COSMETIC: Improved layout of torrent properties window when maximized + - COSMETIC: Now number of search results is updated in real time + - COSMETIC: Remember last window size + - COSMETIC: Improved splash screen look + - COSMETIC: Improved default width of columns in download and search results lists + +* Wed Aug 2 2006 - Christophe Dumez - v0.5.0 + - FEATURE: Improved "Download from url" feature (now supports https, ftp & redirections) + - FEATURE: Added a torrent creation tool + - FEATURE: Display progress for each file within a torrent + - FEATURE: Based on new libtorrent v0.10 (lot of improvements) + - FEATURE: Now possible to clear log textbox (popup menu) + - FEATURE: Added two search engines (isohunt, torrentreactor) + - FEATURE: Now Display share ratio on main window + - FEATURE: Use OSD (On Screen Display) when a download or a search is finished + - FEATURE: Allow only one instance of qBittorrent (and add new parameters to download list) + - FEATURE: Remember last selected search engines in search tab + - FEATURE: Improved search engines status output (Aborted, timed out, finished, no results) + - FEATURE: qBittorrent can now update search plugin from qbittorrent.org + - I18N: Added Slovak, Italian, Portuguese, Romanian and Traditional Chinese languages + - BUGFIX: Fixed ThePirateBay parser for search engine (website had changed) + - BUGFIX: Fixed filenames for results from ThePirateBay search engine + - BUGFIX: Fixed unicode support for ThePirateBay search engine + - BUGFIX: Now search results are sorted by seeds + - BUGFIX: Overwrite nova.py search plugin only if it is outdated + - BUGFIX: Fixed possible division by 0 in ETA calculation + - BUGFIX: Improved ETA calculation precision + - BUGFIX: Fixed default tab in options + - BUGFIX: When saving options, reconnect only when listening ports changed + - COSMETIC: qBittorrent has now its own new logo + - COSMETIC: Display status "downloading" if DL Speed > 0 (even when tracker is down) + - COSMETIC: Added a splashscreen + - COSMETIC: qBittorrent has new cute icons + - COSMETIC: Display number of results in search tab + - COSMETIC: Added icons for each item in download list according to its state + - COSMETIC: Redesigned Locale settings + - COSMETIC: Fixed search engines names width (were cut on the right) + - COSMETIC: Moved search engines to the left of the window (better ui) + +* Fri Jun 23 2006 - Christophe Dumez - v0.4.1 + - Not counting "protocol chatter" in UP/DL speed anymore + - Download speed is now 0 when download is finished + - Paused torrents remain paused when qbittorrent is re-started + - Added option "go to systray when minimizing" + - Added option "Clear finished downloads on exit" + - Added option "Ask user for confirmation on exit" + - Added "Stalled" status for downloads (colored in orange, paused are in red and finished in green) + - Fixed Search window layout on maximizing + - Fixed a bug that caused upload limit not to be always applied + - Added Bulgarian translation + - Updated Translations + - Code optimization + +* Tue Jun 13 2006 - Christophe Dumez - v0.4.0 + - Added a search engine (supports Mininova & thepiratebay websites) + - Fixed critical bug: some options were not applied correctly to BT session + - Possibility to download a torrent file from an URL + - Added confirmation dialog on qbittorrent exit + - Enabled sorting in Download list + - Added Ukrainian translation + - Support urls as program parameters + - Added more actions to trayicon menu + - Fixed exception catching when retrieving fastresume data + - use Binary prefix standards from IEC 60027-2 for units (B, KiB, MiB, GiB, TiB) + - Iconification to systray when minimizing + - Code Cleanup & optimization + +* Tue Jun 06 2006 - Christophe Dumez - v0.3.1 + - Fixed toolbar layout (spacing) + - Added Russian translation + - Resume also finished files on startup (for seeding) + - Added colors corresponding to download state + - Fixed a segfault when deleting a download (if no scan dir is set) + +* Mon Jun 05 2006 - Christophe Dumez - v0.3 + - Fixed auto-resume (worked only once) + - Fixed BT_Backup dir creation on first startup (thanks Peter) + - Now min port and max port are inverted if (min port > max port) + - Fixed memory leaks + - Added qbittorrent man page + - Allow to disable max connections limit (default is disabled) + - Disable upload limit by default + - Added Menu Entry with icon (thanks Peter) + - Restructured directory, now Makefile is in main directory (not src/) + - Updated README / INSTALL + +* Fri Jun 02 2006 - Christophe Dumez - v0.2.3 + - Fixed ports checking function (user couldn't type the value he wanted) + - qBittorrent does not remove .torrent file from scanned directory anymore + - Check tracker errors list size and clear it if it becomes too big. + - Small cosmetic change + +* Wed May 31 2006 - Christophe Dumez - v0.2.2 + - Fixed missing icons + +* Thu May 25 2006 - Christophe Dumez - v0.2.1 + - Fixed "make install" rule + - Disabled debug mode + +* Thu May 25 2006 - Christophe Dumez - v0.2 + - Fixed a compatibility problem with some versions of qmake + - Added translations : Greek, Swedish + - Fixed Polish translation selection + - Fixed come warning because of two unexisting slots + - Improved "Apply" button behaviour in options + - Windows are now resizable + +* Tue May 16 2006 - Christophe Dumez - v0.1 + - Initial release (lack features & still need a lot of improvements) diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..630242323 --- /dev/null +++ b/INSTALL @@ -0,0 +1,56 @@ +qBittorrent - A BitTorrent client in C++ / Qt4 +------------------------------------------ + +1) Compile and install qBittorrent with Qt4 Graphical Interface + + $ ./configure + $ make && make install + $ qbittorrent + + will install and execute qBittorrent hopefully without any problems. + + Dependencies: + - Qt >= 4.5.0 (libqtgui, libqtcore, libqtnetwork, libqtxml, libqtdbus/optional) + + - pkg-config executable + + - libtorrent-rasterbar by Arvid Norberg (>= 0.14.4 REQUIRED, compatible with v0.15.x) + -> http://www.libtorrent.net + Be careful: another library (the one used by rTorrent) uses a similar name. + + - libboost 1.34.x (libboost-filesystem, libboost-date-time) + libasio + or + - libboost >= 1.35.x (libboost-system, libboost-filesystem, libboost-date-time) + + - python >= 2.3 && < 3.0 (needed by search engine) + * Run time only dependency + + - geoip-database (optional) + * If qBittorrent cannot find this database, it will try to resolve countries using the Internet but it will be a lot slower. + * Run time only dependency + +2) Compile and install qBittorrent without Qt4 Graphical interface + + $ ./configure --disable-gui + $ make && make install + $ qbittorrent + + will install and execute qBittorrent hopefully without any problems. + + Dependencies: + - Qt >= 4.4.0 (libqt-devel, libqtcore, libqtnetwork) + + - pkg-config executable + + - libtorrent-rasterbar by Arvid Norberg (>= 0.14.4 REQUIRED, >= v0.15.0 ADVISED) + -> http://www.libtorrent.net + Be careful: another library (the one used by rTorrent) uses a similar name. + + - libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization + + +DOCUMENTATION: +Please note that there is a documentation with a "compiling howto" at http://wiki.qbittorrent.org. + +------------------------------------------ +Christophe Dumez diff --git a/NEWS b/NEWS new file mode 100644 index 000000000..96b13e5a6 --- /dev/null +++ b/NEWS @@ -0,0 +1,4 @@ +See Changelog + +******************************************* +Christophe dumez - chris@qbittorrent.org diff --git a/README b/README new file mode 100644 index 000000000..aa9ad0a8f --- /dev/null +++ b/README @@ -0,0 +1,40 @@ +qBittorrent - A BitTorrent client in Qt4 +------------------------------------------ + +Description: +******************************** +qBittorrent is a bittorrent client programmed in C++ / Qt4 that uses +libtorrent (sometimes called rblibtorrent) by Arvid Norberg. + +It aims to be a good alternative to all other bittorrent clients +out there. qBittorrent is fast, stable and provides unicode +support as well as many features. + +This product includes GeoLite data created by MaxMind, available from +http://maxmind.com/ + +Installation: +******************************** +For installation, follow the instructions from INSTALL file, but simple: + +./configure +make && make install +qbittorrent + +will install and execute qBittorrent hopefully without any problem. + +For more information please visit: +http://www.qbittorrent.org + +or our wiki here: +http://wiki.qbittorrent.org + +Please report any bug (or feature request) to: +http://bugs.qbittorrent.org + +You can also meet me (chris-qBT) on IRC: +#qbittorrent on irc.freenode.net + +------------------------------------------ +Christophe Dumez + diff --git a/README.os2 b/README.os2 new file mode 100644 index 000000000..be931ae02 --- /dev/null +++ b/README.os2 @@ -0,0 +1,62 @@ +qBittorrent - A BitTorrent client in Qt4 +------------------------------------------ + +This is the eComStation (OS/2) qBittorrent part of the readme. See also README for more general information. + + +Building qBittorrent +******************** + + +Requirements +============ + +- gcc based build env (recommended gcc v4.4.2 or greater) + +- Qt4 for eCS (OS/2) dev package (see http://svn.netlabs.org/qt4 for more information) + +- libtorrent-rasterbar for eCS (OS/2) port (see http://svn.netlabs.org/ports for more information) + +- boost for eCS (OS/2) port (see http://svn.netlabs.org/ports for more information) + + +How to build +============ + +First you need to create the conf.pri file in the same dir as this readme.os2 is. +the conf.pri file has the following content: + +##### conf.pri content beginn ##### +PREFIX = . +BINDIR = ./bin +INCDIR = ./include +LIBDIR = ./lib +DATADIR = ./share + +CONFIG += staticlib +INCLUDEPATH += x:/trees/libtorrent/trunk/include +LIBS += -Lx:/trees/libtorrent/trunk/src/.libs \ + -Lx:/trees/boost/trunk/stage/lib \ + -Lx:/trees/openssl \ + -Lx:/extras/lib +##### conf.pri content end ##### + +Of course all the above path references have to be adjusted to your build env. + +It should now be easy to build qBittorrent: + +Simply type: +$ qmake + +Followed by: +$ make + +If all works fine you should get a working qbittorrent executable. + +If you have any question regarding the eCS (OS/2) port of qBittorrent you can meet me (_diver) on IRC: +#netlabs on irc.freenode.net + +------------------------------------------ +Silvan Scherrer + + diff --git a/TODO b/TODO new file mode 100644 index 000000000..c79698771 --- /dev/null +++ b/TODO @@ -0,0 +1,2 @@ +See https://blueprints.launchpad.net/qbittorrent/ + diff --git a/configure b/configure new file mode 100755 index 000000000..5fb52934f --- /dev/null +++ b/configure @@ -0,0 +1,1652 @@ +#!/bin/sh +# +# Generated by qconf 1.4 ( http://delta.affinix.com/qconf/ ) +# + +show_usage() { +cat </dev/null` + if echo $WHICH | grep 'shell built-in command' >/dev/null 2>&1; then + WHICH=which + elif [ -z "$WHICH" ]; then + if which which >/dev/null 2>&1; then + WHICH=which + else + for a in /usr/ucb /usr/bin /bin /usr/local/bin; do + if [ -x $a/which ]; then + WHICH=$a/which + break; + fi + done + fi + fi + + if [ -z "$WHICH" ]; then + OLD_IFS=$IFS + IFS=: + for a in $PATH; do + if [ -x $a/$1 ]; then + echo "$a/$1" + IFS=$OLD_IFS + export IFS + HOME=$OLD_HOME + export HOME + return 0 + fi + done + IFS=$OLD_IFS + export IFS + else + a=`"$WHICH" "$1" 2>/dev/null` + if [ ! -z "$a" -a -x "$a" ]; then + echo "$a" + HOME=$OLD_HOME + export HOME + return 0 + fi + fi + HOME=$OLD_HOME + export HOME + return 1 +} +WHICH=which_command + +# find a make command +if [ -z "$MAKE" ]; then + MAKE= + for mk in gmake make; do + if $WHICH $mk >/dev/null 2>&1; then + MAKE=`$WHICH $mk` + break + fi + done + if [ -z "$MAKE" ]; then + echo "You don't seem to have 'make' or 'gmake' in your PATH." + echo "Cannot proceed." + exit 1 + fi +fi + +show_qt_info() { + printf "Be sure you have a proper Qt 4.0 build environment set up. This means not\n" + printf "just Qt, but also a C++ compiler, a make tool, and any other packages\n" + printf "necessary for compiling C++ programs.\n" + printf "\n" + printf "If you are certain everything is installed, then it could be that Qt 4 is not\n" + printf "being recognized or that a different version of Qt is being detected by\n" + printf "mistake (for example, this could happen if \$QTDIR is pointing to a Qt 3\n" + printf "installation). At least one of the following conditions must be satisfied:\n" + printf "\n" + printf " 1) --qtdir is set to the location of Qt\n" + printf " 2) \$QTDIR is set to the location of Qt\n" + printf " 3) QtCore is in the pkg-config database\n" + printf " 4) qmake is in the \$PATH\n" + printf "\n" + printf "This script will use the first one it finds to be true, checked in the above\n" + printf "order. #3 and #4 are the recommended options. #1 and #2 are mainly for\n" + printf "overriding the system configuration.\n" + printf "\n" +} + +while [ $# -gt 0 ]; do + optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + case "$1" in + --prefix=*) + PREFIX=$optarg + shift + ;; + + --bindir=*) + BINDIR=$optarg + shift + ;; + + --datadir=*) + DATADIR=$optarg + shift + ;; + + --qtdir=*) + EX_QTDIR=$optarg + shift + ;; + + --enable-debug) + QC_ENABLE_DEBUG="Y" + shift + ;; + + --disable-gui) + QC_DISABLE_GUI="Y" + shift + ;; + + --disable-qt-dbus) + QC_DISABLE_qt_dbus="Y" + shift + ;; + + --with-libboost-inc=*) + QC_WITH_LIBBOOST_INC=$optarg + shift + ;; + + --with-libboost-lib=*) + QC_WITH_LIBBOOST_LIB=$optarg + shift + ;; + + --disable-geoip-database) + QC_DISABLE_geoip_database="Y" + shift + ;; + + --with-geoip-database-embedded) + QC_WITH_GEOIP_DATABASE_EMBEDDED="Y" + shift + ;; + + --with-qtsingleapplication=*) + QC_WITH_QTSINGLEAPPLICATION=$optarg + shift + ;; + + --verbose) + QC_VERBOSE="Y" + shift + ;; + --help) show_usage; exit ;; + *) show_usage; exit ;; + esac +done + +PREFIX=${PREFIX:-/usr/local} +BINDIR=${BINDIR:-$PREFIX/bin} +DATADIR=${DATADIR:-$PREFIX/share} + +echo "Configuring qbittorrent ..." + +if [ "$QC_VERBOSE" = "Y" ]; then +echo +echo PREFIX=$PREFIX +echo BINDIR=$BINDIR +echo DATADIR=$DATADIR +echo EX_QTDIR=$EX_QTDIR +echo QC_ENABLE_DEBUG=$QC_ENABLE_DEBUG +echo QC_DISABLE_GUI=$QC_DISABLE_GUI +echo QC_DISABLE_qt_dbus=$QC_DISABLE_qt_dbus +echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC +echo QC_WITH_LIBBOOST_LIB=$QC_WITH_LIBBOOST_LIB +echo QC_DISABLE_geoip_database=$QC_DISABLE_geoip_database +echo QC_WITH_GEOIP_DATABASE_EMBEDDED=$QC_WITH_GEOIP_DATABASE_EMBEDDED +echo QC_WITH_QTSINGLEAPPLICATION=$QC_WITH_QTSINGLEAPPLICATION +echo +fi + +printf "Verifying Qt 4 build environment ... " + +# run qmake -v and check version +qmake_check_v4() { + if [ -x "$1" ]; then + if echo `$1 -v 2>&1` | grep "Qt version 4\." >/dev/null 2>&1; then + return 0 + elif [ "$QC_VERBOSE" = "Y" ]; then + echo "Warning: $1 not for Qt 4" + fi + fi + return 1 +} + +if [ "$QC_VERBOSE" = "Y" ]; then + echo +fi + +qm="" +names="qmake-qt4 qmake4 qmake" + +# qt4 check: --qtdir +if [ -z "$qm" ] && [ ! -z "$EX_QTDIR" ]; then + for n in $names; do + qstr=$EX_QTDIR/bin/$n + if qmake_check_v4 "$qstr"; then + qm=$qstr + break; + fi + done +fi +if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then + echo "Warning: qmake not found via --qtdir" +fi + +# qt4 check: QTDIR +if [ -z "$qm" ] && [ ! -z "$QTDIR" ]; then + for n in $names; do + qstr=$QTDIR/bin/$n + if qmake_check_v4 "$qstr"; then + qm=$qstr + break; + fi + done +fi +if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then + echo "Warning: qmake not found via \$QTDIR" +fi + +# qt4 check: pkg-config +if [ -z "$qm" ]; then + str=`pkg-config QtCore --variable=exec_prefix 2>/dev/null` + if [ ! -z "$str" ]; then + for n in $names; do + qstr=$str/bin/$n + if qmake_check_v4 "$qstr"; then + qm=$qstr + break; + fi + done + fi +fi +if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then + echo "Warning: qmake not found via pkg-config" +fi + +# qt4 check: PATH +if [ -z "$qm" ]; then + for n in $names; do + qstr=`$WHICH $n 2>/dev/null` + if qmake_check_v4 "$qstr"; then + qm=$qstr + break; + fi + done +fi +if [ -z "$qm" ] && [ "$QC_VERBOSE" = "Y" ]; then + echo "Warning: qmake not found via \$PATH" +fi + +if [ -z "$qm" ]; then + if [ "$QC_VERBOSE" = "Y" ]; then + echo " -> fail" + else + echo "fail" + fi + printf "\n" + printf "Reason: Unable to find the 'qmake' tool for Qt 4.\n" + printf "\n" + show_qt_info + exit 1; +fi +if [ "$QC_VERBOSE" = "Y" ]; then + echo qmake found in $qm +fi + +gen_files() { +cat >$1/modules.cpp <= 4.5 +arg: enable-debug, Enable debug mode +arg: disable-gui, Disable qBittorrent Graphical user interface for headless running +-----END QCMOD----- +*/ +class qc_qt4 : public ConfObj +{ +public: + qc_qt4(Conf *c) : ConfObj(c) {} + QString name() const { return "Qt >= 4.5"; } + QString shortname() const { return "Qt 4.5"; } + bool exec() + { + // NOX mode + if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) { + conf->addExtra("CONFIG += nox"); + } + // Debug mode + if(!conf->getenv("QC_ENABLE_DEBUG").isEmpty()) { + conf->addExtra("CONFIG -= release"); + conf->addExtra("CONFIG += debug"); + } else { + conf->addExtra("CONFIG -= debug"); + conf->addExtra("CONFIG += release"); + } + #ifdef Q_OS_FREEBSD + conf->addLib("-lexecinfo"); + conf->addExtra("MANPREFIX = \$\$PREFIX"); + #else + conf->addExtra("MANPREFIX = \$\$PREFIX/share"); + #endif + return(QT_VERSION >= 0x040500); + } +}; +#line 1 "qt-dbus.qcm" +/* +-----BEGIN QCMOD----- +name: qt-dbus +-----END QCMOD----- +*/ +// see Conf::findPkgConfig +class qc_qt_dbus : public ConfObj +{ +public: + qc_qt_dbus(Conf *c) : ConfObj(c) {} + QString name() const { return "QtDBus >= 4.5"; } + QString shortname() const { return "qt-dbus"; } + QString checkString() const { + if(!conf->getenv("QC_DISABLE_qt_dbus").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) + return ""; + return ConfObj::checkString(); + } + bool exec(){ + if(!conf->getenv("QC_DISABLE_qt_dbus").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) + return false; + QStringList incs; + QString req_ver = "4.5.0"; + QString version, libs, other; + VersionMode mode = VersionMin; + if(conf->findPkgConfig("QtDBus", mode, req_ver, &version, &incs, &libs, &other)) { + conf->addExtra("CONFIG += dbus"); + return true; + } + return false; + } +}; +#line 1 "pkg-config.qcm" +/* +-----BEGIN QCMOD----- +name: pkg-config +-----END QCMOD----- +*/ +#include +class qc_pkg_config : public ConfObj +{ +public: + qc_pkg_config(Conf *c) : ConfObj(c) {} + QString name() const { return "pkg-config executable"; } + QString shortname() const { return "pkg-config"; } + bool exec(){ + return !conf->findProgram("pkg-config").isEmpty(); + } +}; +#line 1 "libtorrent-rasterbar.qcm" +/* +-----BEGIN QCMOD----- +name: libtorrent-rasterbar +-----END QCMOD----- +*/ +// see Conf::findPkgConfig +class qc_libtorrent_rasterbar : public ConfObj +{ +public: + qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {} + QString name() const { return "libtorrent-rasterbar >= 0.14.4"; } + QString shortname() const { return "libtorrent-rasterbar"; } + bool exec(){ + QStringList incs; + QString req_ver = "0.14.4"; + QString version, libs, other; + VersionMode mode = VersionMin; + if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other)) + return false; + for(int n = 0; n < incs.count(); ++n) + conf->addIncludePath(incs[n]); + return true; + } +}; +#line 1 "libboost.qcm" +/* +-----BEGIN QCMOD----- +name: libboost +arg: with-libboost-inc=[path], Path to libboost include files +arg: with-libboost-lib=[path], Path to libboost library files +-----END QCMOD----- +*/ +#include +class qc_libboost : public ConfObj +{ +public: + qc_libboost(Conf *c) : ConfObj(c) {} + QString name() const { return "libboost"; } + QString shortname() const { return "libboost"; } + QString findBoostLib(QString path, QString lib) const { + QString name; + QDir libDir(path); + QStringList filters; + filters << "libboost_"+lib+"*-mt*.so"; + QStringList result = libDir.entryList(filters, QDir::Files); + if(!result.empty()) { + name = result.first().mid(3); + // Remove .so + name.chop(3); + } else { + // Fall back to non -mt boost lib + filters.clear(); + filters << "libboost_"+lib+"*.so"; + result = libDir.entryList(filters, QDir::Files); + if(!result.empty()) { + name = result.first().mid(3); + // Remove .so + name.chop(3); + } + } + return name; + } + bool exec(){ + QString s; + s = conf->getenv("QC_WITH_LIBBOOST_INC"); + if(!s.isEmpty()) { + if(!conf->checkHeader(s, "boost/format.hpp")) { + return false; + } + if(!conf->checkHeader(s, "boost/date_time/posix_time/posix_time.hpp")) { + return false; + } + if(!conf->checkHeader(s, "boost/filesystem/path.hpp")) { + return false; + } + }else{ + QStringList sl; + sl << "/usr/include"; + sl << "/usr/local/include"; + bool found = false; + foreach(s, sl){ + if(conf->checkHeader(s, "boost/format.hpp")){ + found = true; + break; + } + } + if(!found) { + return false; + } + if(!conf->checkHeader(s, "boost/date_time/posix_time/posix_time.hpp")) { + return false; + } + if(!conf->checkHeader(s, "boost/filesystem/path.hpp")) { + return false; + } + } + conf->addIncludePath(s); + // Find library + s = conf->getenv("QC_WITH_LIBBOOST_LIB"); + QStringList required_libs; +#if BOOST_VERSION >= 103500 + required_libs << "system"; +#endif + if(conf->getenv("QC_DISABLE_GUI").isEmpty()) { + // Not required by nox + required_libs << "filesystem" ; + } + QStringList libDirs; + libDirs << "/usr/lib/" << "/usr/lib64/" << "/usr/local/lib/" << "/usr/local/lib64/"; + foreach(const QString& lib, required_libs) { + if(!s.isEmpty()) { + QString detected_name = findBoostLib(s, lib); + if(detected_name.isEmpty()) { + printf("Could not find boost %s library!\n", qPrintable(lib)); + return false; + } else { + conf->addLib("-l"+detected_name); + } + } else { + bool found = false; + foreach(const QString& libDir, libDirs) { + QString detected_name = findBoostLib(libDir, lib); + if(!detected_name.isEmpty()) { + conf->addLib("-l"+detected_name); + found = true; + break; + } + } + if(!found) { + printf("Could not find boost %s library!\n", qPrintable(lib)); + return false; + } + } + } + return true; + } +}; +#line 1 "geoip-database.qcm" +/* +-----BEGIN QCMOD----- +name: geoip-database +arg: with-geoip-database-embedded, Geoip Database will be embedded in qBittorrent executable (please follow instructions in src/geoip/README) +-----END QCMOD----- +*/ +// see Conf::findPkgConfig +class qc_geoip_database : public ConfObj +{ +public: + qc_geoip_database(Conf *c) : ConfObj(c) {} + QString name() const { return "GeoIP Database (optional)"; } + QString shortname() const { return "GeoIP Database"; } + QString checkString() const { + if(!conf->getenv("QC_DISABLE_geoip_database").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) + return ""; + return ConfObj::checkString(); + } + bool exec() { + if(!conf->getenv("QC_DISABLE_geoip_database").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) { + return false; + } +#ifdef Q_WS_X11 + if(!conf->getenv("QC_WITH_GEOIP_DATABASE_EMBEDDED").isEmpty()) { +#endif + conf->addDefine("WITH_GEOIP_EMBEDDED"); + printf(" embedded and"); + return true; +#ifdef Q_WS_X11 + } + if(QFile::exists("/usr/share/GeoIP/GeoIP.dat") || QFile::exists("/usr/local/share/GeoIP/GeoIP.dat") || QFile::exists("/var/lib/GeoIP/GeoIP.dat")) + return true; + printf("\nWarning: GeoIP database was not found at /usr/share/GeoIP/GeoIP.dat or /var/lib/GeoIP/GeoIP.dat\nCountry resolution will be slow."); + return false; +#endif + } +}; +#line 1 "qtsingleapplication.qcm" +/* +-----BEGIN QCMOD----- +name: qtsingleapplication +arg: with-qtsingleapplication=[system|shipped], Use the shipped qtsingleapplication library or the system one +-----END QCMOD----- +*/ +class qc_qtsingleapplication : public ConfObj +{ +public: + qc_qtsingleapplication(Conf *c) : ConfObj(c) {} + QString name() const { return "qtsingleapplication library"; } + QString shortname() const { return "qtsingleapplication"; } + + bool exec(){ + QString s; + s = conf->getenv("QC_WITH_QTSINGLEAPPLICATION"); + if(s.compare("system", Qt::CaseInsensitive) == 0) { + // System + conf->addExtra("CONFIG += usesystemqtsingleapplication"); + printf(" [system] "); + } else { + printf(" [shipped] "); + } + return true; + } +}; + +EOT +cat >$1/modules_new.cpp <required = true; + o->disabled = false; + o = new qc_qt_dbus(conf); + o->required = false; + o->disabled = false; + o = new qc_pkg_config(conf); + o->required = true; + o->disabled = false; + o = new qc_libtorrent_rasterbar(conf); + o->required = true; + o->disabled = false; + o = new qc_libboost(conf); + o->required = true; + o->disabled = false; + o = new qc_geoip_database(conf); + o->required = false; + o->disabled = false; + o = new qc_qtsingleapplication(conf); + o->required = true; + o->disabled = false; + +EOT +cat >$1/conf4.h < + +class Conf; + +enum VersionMode { VersionMin, VersionExact, VersionMax, VersionAny }; + +// ConfObj +// +// Subclass ConfObj to create a new configuration module. +class ConfObj +{ +public: + Conf *conf; + bool required; + bool disabled; + bool success; + + ConfObj(Conf *c); + virtual ~ConfObj(); + + // long or descriptive name of what is being checked/performed + // example: "KDE >= 3.3" + virtual QString name() const = 0; + + // short name + // example: "kde" + virtual QString shortname() const = 0; + + // string to display during check + // default: "Checking for [name] ..." + virtual QString checkString() const; + + // string to display after check + // default: "yes" or "no", based on result of exec() + virtual QString resultString() const; + + // this is where the checking code goes + virtual bool exec() = 0; +}; + +// Conf +// +// Interact with this class from your ConfObj to perform detection +// operations and to output configuration parameters. +class Conf +{ +public: + bool debug_enabled; + QString qmake_path; + QString maketool; + + QString DEFINES; + QString INCLUDEPATH; + QString LIBS; + QString extra; + + QList list; + QMap vars; + + Conf(); + ~Conf(); + + QString getenv(const QString &var); + QString qvar(const QString &s); + + bool exec(); + + void debug(const QString &s); + + QString expandIncludes(const QString &inc); + QString expandLibs(const QString &lib); + + int doCommand(const QString &s, QByteArray *out = 0); + int doCommand(const QString &prog, const QStringList &args, QByteArray *out = 0); + + bool doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode = 0); + bool checkHeader(const QString &path, const QString &h); + bool findHeader(const QString &h, const QStringList &ext, QString *inc); + bool checkLibrary(const QString &path, const QString &name); + bool findLibrary(const QString &name, QString *lib); + QString findProgram(const QString &prog); + bool findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs); + bool findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags); + bool findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags); + + void addDefine(const QString &str); + void addLib(const QString &str); + void addIncludePath(const QString &str); + void addExtra(const QString &str); + +private: + bool first_debug; + + friend class ConfObj; + void added(ConfObj *o); +}; + +#endif + +EOT +cat >$1/conf4.cpp < +#include + +class MocTestObject : public QObject +{ + Q_OBJECT +public: + MocTestObject() {} +}; + +QString qc_getenv(const QString &var) +{ + char *p = ::getenv(var.toLatin1().data()); + if(!p) + return QString(); + return QString(p); +} + +QStringList qc_pathlist() +{ + QStringList list; + QString path = qc_getenv("PATH"); + if(!path.isEmpty()) + list = path.split(':', QString::SkipEmptyParts); + return list; +} + +QString qc_findprogram(const QString &prog) +{ + QString out; + QStringList list = qc_pathlist(); + for(int n = 0; n < list.count(); ++n) + { + QFileInfo fi(list[n] + '/' + prog); + if(fi.exists() && fi.isExecutable()) + { + out = fi.filePath(); + break; + } + } + return out; +} + +QString qc_findself(const QString &argv0) +{ + if(argv0.contains('/')) + return argv0; + else + return qc_findprogram(argv0); +} + +int qc_runcommand(const QString &command, QByteArray *out, bool showOutput) +{ + QString fullcmd = command; + if(!showOutput) + fullcmd += " 2>/dev/null"; + FILE *f = popen(fullcmd.toLatin1().data(), "r"); + if(!f) + return -1; + if(out) + out->clear(); + while(1) + { + char c = (char)fgetc(f); + if(feof(f)) + break; + if(out) + out->append(c); + if(showOutput) + fputc(c, stdout); + } + int ret = pclose(f); + if(ret == -1) + return -1; + return ret; +} + +int qc_runprogram(const QString &prog, const QStringList &args, QByteArray *out, bool showOutput) +{ + QString fullcmd = prog; + QString argstr = args.join(" "); + if(!argstr.isEmpty()) + fullcmd += QString(" ") + argstr; + return qc_runcommand(fullcmd, out, showOutput); + + // TODO: use QProcess once it is fixed + /* + QProcess process; + if(showOutput) + process.setReadChannelMode(ForwardedChannels); + process.start(prog, args); + process.waitForFinished(-1); + return process.exitCode(); + */ +} + +bool qc_removedir(const QString &dirPath) +{ + QDir dir(dirPath); + if(!dir.exists()) + return false; + QStringList list = dir.entryList(); + foreach(QString s, list) + { + if(s == "." || s == "..") + continue; + QFileInfo fi(dir.filePath(s)); + if(fi.isDir()) + { + if(!qc_removedir(fi.filePath())) + return false; + } + else + { + if(!dir.remove(s)) + return false; + } + } + QString dirName = dir.dirName(); + if(!dir.cdUp()) + return false; + if(!dir.rmdir(dirName)) + return false; + return true; +} + +void qc_splitcflags(const QString &cflags, QStringList *incs, QStringList *otherflags) +{ + incs->clear(); + otherflags->clear(); + + QStringList cflagsList = cflags.split(" "); + for(int n = 0; n < cflagsList.count(); ++n) + { + QString str = cflagsList[n]; + if(str.startsWith("-I")) + { + // we want everything except the leading "-I" + incs->append(str.remove(0, 2)); + } + else + { + // we want whatever is left + otherflags->append(str); + } + } +} + +QString qc_escapeArg(const QString &str) +{ + QString out; + for(int n = 0; n < (int)str.length(); ++n) { + if(str[n] == '-') + out += '_'; + else + out += str[n]; + } + return out; +} + +//---------------------------------------------------------------------------- +// ConfObj +//---------------------------------------------------------------------------- +ConfObj::ConfObj(Conf *c) +{ + conf = c; + conf->added(this); + required = false; + disabled = false; + success = false; +} + +ConfObj::~ConfObj() +{ +} + +QString ConfObj::checkString() const +{ + return QString("Checking for %1 ...").arg(name()); +} + +QString ConfObj::resultString() const +{ + if(success) + return "yes"; + else + return "no"; +} + +//---------------------------------------------------------------------------- +// qc_internal_pkgconfig +//---------------------------------------------------------------------------- +class qc_internal_pkgconfig : public ConfObj +{ +public: + QString pkgname, desc; + VersionMode mode; + QString req_ver; + + qc_internal_pkgconfig(Conf *c, const QString &_name, const QString &_desc, VersionMode _mode, const QString &_req_ver) : ConfObj(c) + { + pkgname = _name; + desc = _desc; + mode = _mode; + req_ver = _req_ver; + } + + QString name() const { return desc; } + QString shortname() const { return pkgname; } + + bool exec() + { + QStringList incs; + QString version, libs, other; + if(!conf->findPkgConfig(pkgname, mode, req_ver, &version, &incs, &libs, &other)) + return false; + + for(int n = 0; n < incs.count(); ++n) + conf->addIncludePath(incs[n]); + if(!libs.isEmpty()) + conf->addLib(libs); + //if(!other.isEmpty()) + // conf->addExtra(QString("QMAKE_CFLAGS += %1\n").arg(other)); + return true; + } +}; + +//---------------------------------------------------------------------------- +// Conf +//---------------------------------------------------------------------------- +Conf::Conf() +{ + // TODO: no more vars? + //vars.insert("QMAKE_INCDIR_X11", new QString(X11_INC)); + //vars.insert("QMAKE_LIBDIR_X11", new QString(X11_LIBDIR)); + //vars.insert("QMAKE_LIBS_X11", new QString(X11_LIB)); + //vars.insert("QMAKE_CC", CC); + + debug_enabled = false; +} + +Conf::~Conf() +{ + qDeleteAll(list); +} + +void Conf::added(ConfObj *o) +{ + list.append(o); +} + +QString Conf::getenv(const QString &var) +{ + return qc_getenv(var); +} + +void Conf::debug(const QString &s) +{ + if(debug_enabled) + { + if(first_debug) + printf("\n"); + first_debug = false; + printf(" * %s\n", qPrintable(s)); + } +} + +bool Conf::exec() +{ + for(int n = 0; n < list.count(); ++n) + { + ConfObj *o = list[n]; + + // if this was a disabled-by-default option, check if it was enabled + if(o->disabled) + { + QString v = QString("QC_ENABLE_") + qc_escapeArg(o->shortname()); + if(getenv(v) != "Y") + continue; + } + // and the opposite? + else + { + QString v = QString("QC_DISABLE_") + qc_escapeArg(o->shortname()); + if(getenv(v) == "Y") + continue; + } + + bool output = true; + QString check = o->checkString(); + if(check.isEmpty()) + output = false; + + if(output) + { + printf("%s", check.toLatin1().data()); + fflush(stdout); + } + + first_debug = true; + bool ok = o->exec(); + o->success = ok; + + if(output) + { + QString result = o->resultString(); + if(!first_debug) + printf(" -> %s\n", result.toLatin1().data()); + else + printf(" %s\n", result.toLatin1().data()); + } + + if(!ok && o->required) + { + printf("\nError: need %s!\n", o->name().toLatin1().data()); + return false; + } + } + return true; +} + +QString Conf::qvar(const QString &s) +{ + return vars.value(s); +} + +QString Conf::expandIncludes(const QString &inc) +{ + return QString("-I") + inc; +} + +QString Conf::expandLibs(const QString &lib) +{ + return QString("-L") + lib; +} + +int Conf::doCommand(const QString &s, QByteArray *out) +{ + debug(QString("[%1]").arg(s)); + int r = qc_runcommand(s, out, debug_enabled); + debug(QString("returned: %1").arg(r)); + return r; +} + +int Conf::doCommand(const QString &prog, const QStringList &args, QByteArray *out) +{ + QString fullcmd = prog; + QString argstr = args.join(" "); + if(!argstr.isEmpty()) + fullcmd += QString(" ") + argstr; + debug(QString("[%1]").arg(fullcmd)); + int r = qc_runprogram(prog, args, out, debug_enabled); + debug(QString("returned: %1").arg(r)); + return r; +} + +bool Conf::doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode) +{ + QDir tmp(".qconftemp"); + if(!tmp.mkdir("atest")) + { + debug("unable to create atest dir"); + return false; + } + QDir dir(tmp.filePath("atest")); + if(!dir.exists()) + { + debug("atest dir does not exist"); + return false; + } + + QString fname = dir.filePath("atest.cpp"); + QString out = "atest"; + QFile f(fname); + if(!f.open(QFile::WriteOnly | QFile::Truncate)) + { + debug("unable to open atest.cpp for writing"); + return false; + } + if(f.write(filedata.toLatin1()) == -1) + { + debug("error writing to atest.cpp"); + return false; + } + f.close(); + + debug(QString("Wrote atest.cpp:\n%1").arg(filedata)); + + QString pro = QString( + "CONFIG += console\n" + "CONFIG -= qt app_bundle\n" + "SOURCES += atest.cpp\n"); + QString inc = incs.join(" "); + if(!inc.isEmpty()) + pro += "INCLUDEPATH += " + inc + '\n'; + if(!libs.isEmpty()) + pro += "LIBS += " + libs + '\n'; + pro += proextra; + + fname = dir.filePath("atest.pro"); + f.setFileName(fname); + if(!f.open(QFile::WriteOnly | QFile::Truncate)) + { + debug("unable to open atest.pro for writing"); + return false; + } + if(f.write(pro.toLatin1()) == -1) + { + debug("error writing to atest.pro"); + return false; + } + f.close(); + + debug(QString("Wrote atest.pro:\n%1").arg(pro)); + + QString oldpath = QDir::currentPath(); + QDir::setCurrent(dir.path()); + + bool ok = false; + int r = doCommand(qmake_path, QStringList() << "atest.pro"); + if(r == 0) + { + r = doCommand(maketool, QStringList()); + if(r == 0) + { + ok = true; + if(retcode) + *retcode = doCommand(QString("./") + out, QStringList()); + } + r = doCommand(maketool, QStringList() << "distclean"); + if(r != 0) + debug("error during atest distclean"); + } + + QDir::setCurrent(oldpath); + + // cleanup + //dir.remove("atest.pro"); + //dir.remove("atest.cpp"); + //tmp.rmdir("atest"); + + // remove whole dir since distclean doesn't always work + qc_removedir(tmp.filePath("atest")); + + if(!ok) + return false; + return true; +} + +bool Conf::checkHeader(const QString &path, const QString &h) +{ + QFileInfo fi(path + '/' + h); + if(fi.exists()) + return true; + return false; +} + +bool Conf::findHeader(const QString &h, const QStringList &ext, QString *inc) +{ + if(checkHeader("/usr/include", h)) + { + *inc = ""; + return true; + } + QStringList dirs; + dirs += "/usr/local/include"; + dirs += ext; + for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) + { + if(checkHeader(*it, h)) + { + *inc = *it; + return true; + } + } + return false; +} + +bool Conf::checkLibrary(const QString &path, const QString &name) +{ + QString str = + //"#include \n" + "int main()\n" + "{\n" + //" printf(\"library checker running\\\\n\");\n" + " return 0;\n" + "}\n"; + + QString libs; + if(!path.isEmpty()) + libs += QString("-L") + path + ' '; + libs += QString("-l") + name; + if(!doCompileAndLink(str, QStringList(), libs, QString())) + return false; + return true; +} + +bool Conf::findLibrary(const QString &name, QString *lib) +{ + if(checkLibrary("", name)) + { + *lib = ""; + return true; + } + if(checkLibrary("/usr/local/lib", name)) + { + *lib = "/usr/local/lib"; + return true; + } + return false; +} + +QString Conf::findProgram(const QString &prog) +{ + return qc_findprogram(prog); +} + +bool Conf::findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs) +{ + QString inc, lib; + QString s; + + s = getenv(incvar); + if(!s.isEmpty()) { + if(!checkHeader(s, incname)) + return false; + inc = s; + } + else { + if(!findHeader(incname, QStringList(), &s)) + return false; + inc = s; + } + + s = getenv(libvar); + if(!s.isEmpty()) { + if(!checkLibrary(s, libname)) + return false; + lib = s; + } + else { + if(!findLibrary(libname, &s)) + return false; + lib = s; + } + + QString lib_out; + if(!lib.isEmpty()) + lib_out += QString("-L") + s; + lib_out += QString("-l") + libname; + + *incpath = inc; + *libs = lib_out; + return true; +} + +bool Conf::findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags) +{ + QStringList args; + QByteArray out; + int ret; + + args += "--version"; + ret = doCommand(path, args, &out); + if(ret != 0) + return false; + + QString version_out = QString::fromLatin1(out).trimmed(); + + args.clear(); + args += "--libs"; + ret = doCommand(path, args, &out); + if(ret != 0) + return false; + + QString libs_out = QString::fromLatin1(out).trimmed(); + + args.clear(); + args += "--cflags"; + ret = doCommand(path, args, &out); + if(ret != 0) + return false; + + QString cflags = QString::fromLatin1(out).trimmed(); + + QStringList incs_out, otherflags_out; + qc_splitcflags(cflags, &incs_out, &otherflags_out); + + *version = version_out; + *incs = incs_out; + *libs = libs_out; + *otherflags = otherflags_out.join(" "); + return true; +} + +bool Conf::findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags) +{ + QStringList args; + QByteArray out; + int ret; + + args += name; + args += "--exists"; + ret = doCommand("pkg-config", args, &out); + if(ret != 0) + return false; + + if(mode != VersionAny) + { + args.clear(); + args += name; + if(mode == VersionMin) + args += QString("--atleast-version=%1").arg(req_version); + else if(mode == VersionMax) + args += QString("--max-version=%1").arg(req_version); + else + args += QString("--exact-version=%1").arg(req_version); + ret = doCommand("pkg-config", args, &out); + if(ret != 0) + return false; + } + + args.clear(); + args += name; + args += "--modversion"; + ret = doCommand("pkg-config", args, &out); + if(ret != 0) + return false; + + QString version_out = QString::fromLatin1(out).trimmed(); + + args.clear(); + args += name; + args += "--libs"; + ret = doCommand("pkg-config", args, &out); + if(ret != 0) + return false; + + QString libs_out = QString::fromLatin1(out).trimmed(); + + args.clear(); + args += name; + args += "--cflags"; + ret = doCommand("pkg-config", args, &out); + if(ret != 0) + return false; + + QString cflags = QString::fromLatin1(out).trimmed(); + + QStringList incs_out, otherflags_out; + qc_splitcflags(cflags, &incs_out, &otherflags_out); + + *version = version_out; + *incs = incs_out; + *libs = libs_out; + *otherflags = otherflags_out.join(" "); + return true; +} + +void Conf::addDefine(const QString &str) +{ + if(DEFINES.isEmpty()) + DEFINES = str; + else + DEFINES += QString(" ") + str; + debug(QString("DEFINES += %1").arg(str)); +} + +void Conf::addLib(const QString &str) +{ + if(LIBS.isEmpty()) + LIBS = str; + else + LIBS += QString(" ") + str; + debug(QString("LIBS += %1").arg(str)); +} + +void Conf::addIncludePath(const QString &str) +{ + if(INCLUDEPATH.isEmpty()) + INCLUDEPATH = str; + else + INCLUDEPATH += QString(" ") + str; + debug(QString("INCLUDEPATH += %1").arg(str)); +} + +void Conf::addExtra(const QString &str) +{ + extra += str + '\n'; + debug(QString("extra += %1").arg(str)); +} + +//---------------------------------------------------------------------------- +// main +//---------------------------------------------------------------------------- +#include "conf4.moc" + +#ifdef HAVE_MODULES +# include"modules.cpp" +#endif + +int main() +{ + Conf *conf = new Conf; + ConfObj *o; + o = 0; +#ifdef HAVE_MODULES +# include"modules_new.cpp" +#endif + + conf->debug_enabled = (qc_getenv("QC_VERBOSE") == "Y") ? true: false; + if(conf->debug_enabled) + printf(" -> ok\n"); + else + printf("ok\n"); + + QString confCommand = qc_getenv("QC_COMMAND"); + QString proName = qc_getenv("QC_PROFILE"); + conf->qmake_path = qc_getenv("QC_QMAKE"); + conf->maketool = qc_getenv("QC_MAKETOOL"); + + if(conf->debug_enabled) + printf("conf command: [%s]\n", qPrintable(confCommand)); + + QString confPath = qc_findself(confCommand); + if(confPath.isEmpty()) + { + printf("Error: cannot find myself; rerun with an absolute path\n"); + return 1; + } + + QString srcdir = QFileInfo(confPath).absolutePath(); + QString builddir = QDir::current().absolutePath(); + QString proPath = QDir(srcdir).filePath(proName); + + if(conf->debug_enabled) + { + printf("conf path: [%s]\n", qPrintable(confPath)); + printf("srcdir: [%s]\n", qPrintable(srcdir)); + printf("builddir: [%s]\n", qPrintable(builddir)); + printf("profile: [%s]\n", qPrintable(proPath)); + printf("qmake path: [%s]\n", qPrintable(conf->qmake_path)); + printf("make tool: [%s]\n", qPrintable(conf->maketool)); + printf("\n"); + } + + bool success = false; + if(conf->exec()) + { + QFile f("conf.pri"); + if(!f.open(QFile::WriteOnly | QFile::Truncate)) + { + printf("Error writing %s\n", qPrintable(f.fileName())); + return 1; + } + + QString str; + str += "# qconf\n\n"; + + QString var; + var = qc_getenv("PREFIX"); + if(!var.isEmpty()) + str += QString("PREFIX = %1\n").arg(var); + var = qc_getenv("BINDIR"); + if(!var.isEmpty()) + str += QString("BINDIR = %1\n").arg(var); + var = qc_getenv("INCDIR"); + if(!var.isEmpty()) + str += QString("INCDIR = %1\n").arg(var); + var = qc_getenv("LIBDIR"); + if(!var.isEmpty()) + str += QString("LIBDIR = %1\n").arg(var); + var = qc_getenv("DATADIR"); + if(!var.isEmpty()) + str += QString("DATADIR = %1\n").arg(var); + str += '\n'; + + if(qc_getenv("QC_STATIC") == "Y") + str += "CONFIG += staticlib\n"; + + // TODO: don't need this? + //str += "QT_PATH_PLUGINS = " + QString(qInstallPathPlugins()) + '\n'; + + if(!conf->DEFINES.isEmpty()) + str += "DEFINES += " + conf->DEFINES + '\n'; + if(!conf->INCLUDEPATH.isEmpty()) + str += "INCLUDEPATH += " + conf->INCLUDEPATH + '\n'; + if(!conf->LIBS.isEmpty()) + str += "LIBS += " + conf->LIBS + '\n'; + if(!conf->extra.isEmpty()) + str += conf->extra; + str += '\n'; + + QByteArray cs = str.toLatin1(); + f.write(cs); + f.close(); + success = true; + } + QString qmake_path = conf->qmake_path; + delete conf; + + if(!success) + return 1; + + // run qmake on the project file + int ret = qc_runprogram(qmake_path, QStringList() << proPath, 0, true); + if(ret != 0) + return 1; + + return 0; +} + +EOT +cat >$1/conf4.pro </dev/null + $MAKE clean >/dev/null 2>&1 + $MAKE >../conf.log 2>&1 +) + +if [ "$?" != "0" ]; then + rm -rf .qconftemp + if [ "$QC_VERBOSE" = "Y" ]; then + echo " -> fail" + else + echo "fail" + fi + printf "\n" + printf "Reason: There was an error compiling 'conf'. See conf.log for details.\n" + printf "\n" + show_qt_info + if [ "$QC_VERBOSE" = "Y" ]; then + echo "conf.log:" + cat conf.log + fi + exit 1; +fi + +QC_COMMAND=$0 +export QC_COMMAND +QC_PROFILE=qbittorrent.pro +export QC_PROFILE +QC_QMAKE=$qm +export QC_QMAKE +QC_MAKETOOL=$MAKE +export QC_MAKETOOL +.qconftemp/conf +ret="$?" +if [ "$ret" = "1" ]; then + rm -rf .qconftemp + echo + exit 1; +else + if [ "$ret" != "0" ]; then + rm -rf .qconftemp + if [ "$QC_VERBOSE" = "Y" ]; then + echo " -> fail" + else + echo "fail" + fi + echo + echo "Reason: Unexpected error launching 'conf'" + echo + exit 1; + fi +fi +rm -rf .qconftemp + +echo +echo "Good, your configure finished. Now run $MAKE." +echo diff --git a/doc/qbittorrent-nox.1 b/doc/qbittorrent-nox.1 new file mode 100644 index 000000000..2fcc644e0 --- /dev/null +++ b/doc/qbittorrent-nox.1 @@ -0,0 +1,44 @@ +.\" This manpage has been automatically generated by docbook2man +.\" from a DocBook document. This tool can be found at: +.\" . +.TH "QBITTORRENT\-NOX" "1" "January 16th 2010" "Command line Bittorrent client written in C++ / Qt4" "" + +.SH "NAME" +qBittorrent\-nox \- a command line Bittorrent client written in C++ / Qt4 + +.SH "SYNOPSIS" + +\fBqbittorrent\-nox\fR [\-\-webui-port=x] [TORRENT_FILE | URL]... + +\fBqbittorrent\-nox\fR \-\-help + +\fBqbittorrent\-nox\fR \-\-version + +.PP +.SH "DESCRIPTION" + +\fBqBittorrent-nox\fR is an advanced command-line Bittorrent client written in C++ / Qt4, +using the \fBlibtorrent-rasterbar\fR library by Arvid Norberg. qBittorrent\-nox aims +to be a good alternative to other command line bittorrent clients and provides features similar to popular graphical clients. + +qBittorrent\-nox is fast, stable, light and it supports unicode. +It also comes with UPnP port forwarding / NAT-PMP, encryption (Vuze compatible), +FAST extension (mainline) and PeX support (utorrent compatible). + +qBittorrent\-nox is meant to be controlled via its feature-rich Web UI which is accessible as a default on http://localhost:8080. The Web UI access is secured and the default account user name is "admin" with "adminadmin" as a password. + +.SH "OPTIONS" + +\fB--help\fR Prints the command line options. + +\fB--version\fR Prints qbittorrent program version number. + +\fB--webui-port=x\fR Changes Web UI port to x (default: 8080). + +.SH "BUGS" + +If you find a bug, please report it at http://bugs.qbittorrent.org + +.SH "AUTHOR" + +Christophe Dumez diff --git a/doc/qbittorrent.1 b/doc/qbittorrent.1 new file mode 100644 index 000000000..ee0ba0be4 --- /dev/null +++ b/doc/qbittorrent.1 @@ -0,0 +1,42 @@ +.\" This manpage has been automatically generated by docbook2man +.\" from a DocBook document. This tool can be found at: +.\" . +.TH "QBITTORRENT" "1" "January 16th 2010" "Bittorrent client written in C++ / Qt4" "" + +.SH "NAME" +qBittorrent \- a Bittorrent client written in C++ / Qt4 + +.SH "SYNOPSIS" + +\fBqbittorrent\fR [\-\-no-splash] [\-\-webui-port=x] [TORRENT_FILE | URL]... + +\fBqbittorrent\fR \-\-help + +\fBqbittorrent\fR \-\-version + +.PP +.SH "DESCRIPTION" + +\fBqBittorrent\fR is an advanced Bittorrent client written in C++ / Qt4, +using the \fBlibtorrent-rasterbar\fR library by Arvid Norberg. qBittorrent is similar to uTorrent. qBittorrent +is fast, stable, light, it supports unicode and it provides a good integrated search engine. +It also comes with UPnP port forwarding / NAT-PMP, encryption (Vuze compatible), +FAST extension (mainline) and PeX support (utorrent compatible). + +.SH "OPTIONS" + +\fB--help\fR Prints the command line options. + +\fB--version\fR Prints qbittorrent program version number. + +\fB--no-splash\fR Disables splash screen on startup. + +\fB--webui-port=x\fR Changes Web UI port to x (default: 8080). + +.SH "BUGS" + +If you find a bug, please report it at http://bugs.qbittorrent.org + +.SH "AUTHOR" + +Christophe Dumez diff --git a/install.os2 b/install.os2 new file mode 100644 index 000000000..0d5535dc0 --- /dev/null +++ b/install.os2 @@ -0,0 +1,136 @@ +QBittorrent installation + + + +0. CONTENTS OF THIS FILE +======================== + +1. INTRODUCTION + +2. REQUIREMENTS + +3. INSTALLATION + +4. CONTACT + +5. CREDITS + +6. SUPPORT AND DONATIONS + +7. HISTORY + + +1. INTRODUCTION +=============== + +Welcome to QBittorrent port for OS/2 and eComStation. + + +2. REQUIREMENTS +=============== + +* klibc 0.6.3 or later + + ftp://ftp.netlabs.org/pub/gcc/libc-0_6_3-csd3.wpi + +* openssl 1.0 + + ftp://ftp.netlabs.org/pub/unixos2/ssl10.zip + +* Qt4 dll + + see http://svn.netlabs.org/qt4 for more information whats needed and where to get the latest + + +3. INSTALLATION +=============== + +To install QBittorrent, do the following: + +klibc +----- + + 1. Download klibc 0.6.3 csd3 or later. + 2. Install the package by double-clicking on the WPI file. + + +openssl 1.0 +----------- + + 1. Download the zip file + 2. Install the files to your libpath eg. x:\ecs\dll + +Qt4 dll +------- + + 1. Download the package + 2. Install the package by double-clicking on the wpi file. + + + +QBittorrent +----------- + + 1. Create a directory for QBittorrent. + 2. Extract the QBittorrent package to the new directory. + 3. Create a WPS object for QBittorrent.exe. + 4. Start QBittorrent + 5. Happy torrenting + + + +4. CONTACT +========== + +Please send bugreports to: + + ecs@aroa.ch + +Only bug reports with a reproducable bug are accepted. :-) + + + +5. CREDITS +========== + +The port was done by: + +Silvan Scherrer aka _diver + +Thanks go to: + + * Dmitry A. Kuminov + +They either helped me when I had some nasty questions or did some testing for +me. + + +6. SUPPORT AND DONATIONS +======================== + +QBittorrent port is based on volunteer work. If you would like to support further +development, you can do so in one of the following ways: + + + * Donate to the Qt4 project: see qt.netlabs.org for more information + + * Contribute to the project: Besides actual development, this also includes + maintaining the documentation and the project web site as well as help + for users. + + +7. HISTORY +========== + +2010-12-23 + + * updated to 2.5.2 code level of QBittorrent + +2010-11-22 + + * updated to 2.4.11 code level of QBittorrent + +2010-xx-xx + + * initial port + diff --git a/macxconf.pri b/macxconf.pri new file mode 100644 index 000000000..ca8951e9d --- /dev/null +++ b/macxconf.pri @@ -0,0 +1,16 @@ +PREFIX = /usr/local +BINDIR = /usr/local/bin +DATADIR = /usr/local/share + +INCLUDEPATH += /usr/local/include/libtorrent /usr/include/openssl /usr/include /opt/local/include/boost /opt/local/include +LIBS += -ltorrent-rasterbar -lcrypto -L/opt/local/lib -lboost_system-mt -lboost_filesystem-mt -lboost_thread-mt -framework Cocoa -framework Carbon -framework IOKit + +document_icon.path = Contents/Resources +document_icon.files = Icons/qBitTorrentDocument.icns + +QMAKE_BUNDLE_DATA += document_icon +ICON = Icons/qbittorrent_mac.icns +QMAKE_INFO_PLIST = Info.plist + +DEFINES += WITH_GEOIP_EMBEDDED +message("On Mac OS X, GeoIP database must be embedded.") diff --git a/os2conf.pri b/os2conf.pri new file mode 100644 index 000000000..76850433d --- /dev/null +++ b/os2conf.pri @@ -0,0 +1,18 @@ +exists(conf.pri) { + # to the conf.pri goes all system dependent stuff + include(conf.pri) +} + +LIBS += -ltorrent-rasterbar \ + -lboost_thread \ + -lboost_system \ + -lboost_filesystem \ + -lssl -lcrypto -lidn -lpthread + +RC_FILE = qbittorrent_os2.rc + +# LIBTORRENT DEFINES +DEFINES += WITH_SHIPPED_GEOIP_H + +DEFINES += WITH_GEOIP_EMBEDDED +message("On eCS(OS/2), GeoIP database must be embedded.") diff --git a/qbittorrent.pro b/qbittorrent.pro new file mode 100644 index 000000000..d92342723 --- /dev/null +++ b/qbittorrent.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs + +SUBDIRS += src + diff --git a/qbittorrent.qc b/qbittorrent.qc new file mode 100644 index 000000000..6f10673f4 --- /dev/null +++ b/qbittorrent.qc @@ -0,0 +1,25 @@ + + qbittorrent + qbittorrent.pro + qcm + + + + + + + + + + + + + + + + + + + + + diff --git a/qcm/geoip-database.qcm b/qcm/geoip-database.qcm new file mode 100644 index 000000000..0bc2256c6 --- /dev/null +++ b/qcm/geoip-database.qcm @@ -0,0 +1,37 @@ +/* +-----BEGIN QCMOD----- +name: geoip-database +arg: with-geoip-database-embedded, Geoip Database will be embedded in qBittorrent executable (please follow instructions in src/geoip/README) +-----END QCMOD----- +*/ +// see Conf::findPkgConfig +class qc_geoip_database : public ConfObj +{ +public: + qc_geoip_database(Conf *c) : ConfObj(c) {} + QString name() const { return "GeoIP Database (optional)"; } + QString shortname() const { return "GeoIP Database"; } + QString checkString() const { + if(!conf->getenv("QC_DISABLE_geoip_database").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) + return ""; + return ConfObj::checkString(); + } + bool exec() { + if(!conf->getenv("QC_DISABLE_geoip_database").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) { + return false; + } +#ifdef Q_WS_X11 + if(!conf->getenv("QC_WITH_GEOIP_DATABASE_EMBEDDED").isEmpty()) { +#endif + conf->addDefine("WITH_GEOIP_EMBEDDED"); + printf(" embedded and"); + return true; +#ifdef Q_WS_X11 + } + if(QFile::exists("/usr/share/GeoIP/GeoIP.dat") || QFile::exists("/usr/local/share/GeoIP/GeoIP.dat") || QFile::exists("/var/lib/GeoIP/GeoIP.dat")) + return true; + printf("\nWarning: GeoIP database was not found at /usr/share/GeoIP/GeoIP.dat or /var/lib/GeoIP/GeoIP.dat\nCountry resolution will be slow."); + return false; +#endif + } +}; diff --git a/qcm/libboost.qcm b/qcm/libboost.qcm new file mode 100644 index 000000000..14167420d --- /dev/null +++ b/qcm/libboost.qcm @@ -0,0 +1,112 @@ +/* +-----BEGIN QCMOD----- +name: libboost +arg: with-libboost-inc=[path], Path to libboost include files +arg: with-libboost-lib=[path], Path to libboost library files +-----END QCMOD----- +*/ +#include +class qc_libboost : public ConfObj +{ +public: + qc_libboost(Conf *c) : ConfObj(c) {} + QString name() const { return "libboost"; } + QString shortname() const { return "libboost"; } + QString findBoostLib(QString path, QString lib) const { + QString name; + QDir libDir(path); + QStringList filters; + filters << "libboost_"+lib+"*-mt*.so"; + QStringList result = libDir.entryList(filters, QDir::Files); + if(!result.empty()) { + name = result.first().mid(3); + // Remove .so + name.chop(3); + } else { + // Fall back to non -mt boost lib + filters.clear(); + filters << "libboost_"+lib+"*.so"; + result = libDir.entryList(filters, QDir::Files); + if(!result.empty()) { + name = result.first().mid(3); + // Remove .so + name.chop(3); + } + } + return name; + } + bool exec(){ + QString s; + s = conf->getenv("QC_WITH_LIBBOOST_INC"); + if(!s.isEmpty()) { + if(!conf->checkHeader(s, "boost/format.hpp")) { + return false; + } + if(!conf->checkHeader(s, "boost/date_time/posix_time/posix_time.hpp")) { + return false; + } + if(!conf->checkHeader(s, "boost/filesystem/path.hpp")) { + return false; + } + }else{ + QStringList sl; + sl << "/usr/include"; + sl << "/usr/local/include"; + bool found = false; + foreach(s, sl){ + if(conf->checkHeader(s, "boost/format.hpp")){ + found = true; + break; + } + } + if(!found) { + return false; + } + if(!conf->checkHeader(s, "boost/date_time/posix_time/posix_time.hpp")) { + return false; + } + if(!conf->checkHeader(s, "boost/filesystem/path.hpp")) { + return false; + } + } + conf->addIncludePath(s); + // Find library + s = conf->getenv("QC_WITH_LIBBOOST_LIB"); + QStringList required_libs; +#if BOOST_VERSION >= 103500 + required_libs << "system"; +#endif + if(conf->getenv("QC_DISABLE_GUI").isEmpty()) { + // Not required by nox + required_libs << "filesystem" ; + } + QStringList libDirs; + libDirs << "/usr/lib/" << "/usr/lib64/" << "/usr/local/lib/" << "/usr/local/lib64/"; + foreach(const QString& lib, required_libs) { + if(!s.isEmpty()) { + QString detected_name = findBoostLib(s, lib); + if(detected_name.isEmpty()) { + printf("Could not find boost %s library!\n", qPrintable(lib)); + return false; + } else { + conf->addLib("-l"+detected_name); + } + } else { + bool found = false; + foreach(const QString& libDir, libDirs) { + QString detected_name = findBoostLib(libDir, lib); + if(!detected_name.isEmpty()) { + conf->addLib("-l"+detected_name); + found = true; + break; + } + } + if(!found) { + printf("Could not find boost %s library!\n", qPrintable(lib)); + return false; + } + } + } + return true; + } +}; diff --git a/qcm/libmagick.qcm b/qcm/libmagick.qcm new file mode 100644 index 000000000..6e82064ab --- /dev/null +++ b/qcm/libmagick.qcm @@ -0,0 +1,76 @@ +/* +-----BEGIN QCMOD----- +name: libmagick +arg: with-libmagick-inc=[path], Path to libmagick++ include files +arg: with-libmagick-lib=[path], Path to libmagick++ library files +-----END QCMOD----- +*/ +#include +class qc_libmagick : public ConfObj +{ +public: + qc_libmagick(Conf *c) : ConfObj(c) {} + QString name() const { return "ImageMagick library (libmagick++)"; } + QString shortname() const { return "libmagick++"; } + QString checkString() const { + if(!conf->getenv("QC_DISABLE_libmagick").isEmpty()) + return ""; + return ConfObj::checkString(); + } + bool exec(){ + if(!conf->getenv("QC_DISABLE_libmagick").isEmpty()) + return false; + QString s; + s = conf->getenv("QC_WITH_LIBMAGICK_INC"); + if(!s.isEmpty()) { + if(!conf->checkHeader(s, "Magick++.h")) { + return false; + } + }else{ + QStringList sl; + sl << "/usr/include"; + sl << "/usr/local/include"; + bool found = false; + foreach(s, sl){ + if(conf->checkHeader(s, "Magick++.h")){ + found = true; + break; + } + } + if(!found) + return false; + } + conf->addIncludePath(s); + + s = conf->getenv("QC_WITH_LIBMAGICK_LIB"); + if(!s.isEmpty()) { + if(!conf->checkLibrary(s, "Magick++")) { + return false; + } + }else{ + QStringList sl; + sl << "/usr/lib/"; + sl << "/usr/lib64/"; + sl << "/usr/local/lib/"; + sl << "/usr/local/lib64/"; + bool found = false; + foreach(s, sl){ + if(conf->checkLibrary(s, "Magick++")) { + found = true; + break; + } + } + if(!found) + return false; + } + conf->addLib(QString("-L") + s); + QString out = ""; + QStringList params; + params << "--libs"; + qconf->doCommand("Magick++-config", params, &out); + out = out.replace("\n", ""); + conf->addLib(result.data()); + conf->addDefine("HAVE_MAGICK"); + return true; + } +}; diff --git a/qcm/libnotify.qcm b/qcm/libnotify.qcm new file mode 100644 index 000000000..4a9e45485 --- /dev/null +++ b/qcm/libnotify.qcm @@ -0,0 +1,60 @@ +/* +-----BEGIN QCMOD----- +name: libnotify +-----END QCMOD----- +*/ +// see Conf::findPkgConfig +class qc_libnotify : public ConfObj +{ +public: + qc_libnotify(Conf *c) : ConfObj(c) {} + QString name() const { return "libnotify >= 0.4.2 (optional)"; } + QString shortname() const { return "libnotify"; } + QString checkString() const { + if(!conf->getenv("QC_DISABLE_libnotify").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) + return ""; + return ConfObj::checkString(); + } + bool exec(){ + if(!conf->getenv("QC_DISABLE_libnotify").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) { + return false; + } + QStringList incs; + QString req_ver = "0.4.2"; + QString version, libs, other; + VersionMode mode = VersionMin; + if(conf->findPkgConfig("libnotify", mode, req_ver, &version, &incs, &libs, &other)) { + conf->addExtra("CONFIG += libnotify"); + for(int n = 0; n < incs.count(); ++n) + conf->addIncludePath(incs[n]); + if(!libs.isEmpty()) + conf->addLib(libs); + QStringList incs2; + QString req_ver2 = "2.0"; + QString version2, libs2, other2; + if(conf->findPkgConfig("glib-2.0", mode, req_ver2, &version2, &incs2, &libs2, &other2)) { + for(int n = 0; n < incs2.count(); ++n) + conf->addIncludePath(incs2[n]); + if(!libs2.isEmpty()) + conf->addLib(libs2); + } else { + return false; + } + QStringList incs3; + QString req_ver3 = "2.0"; + QString version3, libs3, other3; + if(conf->findPkgConfig("gtk+-2.0", mode, req_ver3, &version3, &incs3, &libs3, &other3)) { + for(int n = 0; n < incs3.count(); ++n) + conf->addIncludePath(incs3[n]); + if(!libs3.isEmpty()) + conf->addLib(libs3); + } else { + return false; + } + } else { + return false; + } + + return true; + } +}; diff --git a/qcm/libtorrent-rasterbar.qcm b/qcm/libtorrent-rasterbar.qcm new file mode 100644 index 000000000..ecb8ded0d --- /dev/null +++ b/qcm/libtorrent-rasterbar.qcm @@ -0,0 +1,24 @@ +/* +-----BEGIN QCMOD----- +name: libtorrent-rasterbar +-----END QCMOD----- +*/ +// see Conf::findPkgConfig +class qc_libtorrent_rasterbar : public ConfObj +{ +public: + qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {} + QString name() const { return "libtorrent-rasterbar >= 0.14.4"; } + QString shortname() const { return "libtorrent-rasterbar"; } + bool exec(){ + QStringList incs; + QString req_ver = "0.14.4"; + QString version, libs, other; + VersionMode mode = VersionMin; + if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other)) + return false; + for(int n = 0; n < incs.count(); ++n) + conf->addIncludePath(incs[n]); + return true; + } +}; diff --git a/qcm/pkg-config.qcm b/qcm/pkg-config.qcm new file mode 100644 index 000000000..287de5a35 --- /dev/null +++ b/qcm/pkg-config.qcm @@ -0,0 +1,16 @@ +/* +-----BEGIN QCMOD----- +name: pkg-config +-----END QCMOD----- +*/ +#include +class qc_pkg_config : public ConfObj +{ +public: + qc_pkg_config(Conf *c) : ConfObj(c) {} + QString name() const { return "pkg-config executable"; } + QString shortname() const { return "pkg-config"; } + bool exec(){ + return !conf->findProgram("pkg-config").isEmpty(); + } +}; diff --git a/qcm/qt-dbus.qcm b/qcm/qt-dbus.qcm new file mode 100644 index 000000000..1448c8d4f --- /dev/null +++ b/qcm/qt-dbus.qcm @@ -0,0 +1,31 @@ +/* +-----BEGIN QCMOD----- +name: qt-dbus +-----END QCMOD----- +*/ +// see Conf::findPkgConfig +class qc_qt_dbus : public ConfObj +{ +public: + qc_qt_dbus(Conf *c) : ConfObj(c) {} + QString name() const { return "QtDBus >= 4.5"; } + QString shortname() const { return "qt-dbus"; } + QString checkString() const { + if(!conf->getenv("QC_DISABLE_qt_dbus").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) + return ""; + return ConfObj::checkString(); + } + bool exec(){ + if(!conf->getenv("QC_DISABLE_qt_dbus").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) + return false; + QStringList incs; + QString req_ver = "4.5.0"; + QString version, libs, other; + VersionMode mode = VersionMin; + if(conf->findPkgConfig("QtDBus", mode, req_ver, &version, &incs, &libs, &other)) { + conf->addExtra("CONFIG += dbus"); + return true; + } + return false; + } +}; diff --git a/qcm/qt-svg.qcm b/qcm/qt-svg.qcm new file mode 100644 index 000000000..d968aa69d --- /dev/null +++ b/qcm/qt-svg.qcm @@ -0,0 +1,31 @@ +/* +-----BEGIN QCMOD----- +name: qt-svg +-----END QCMOD----- +*/ +// see Conf::findPkgConfig +class qc_qt_svg : public ConfObj +{ +public: + qc_qt_svg(Conf *c) : ConfObj(c) {} + QString name() const { return "QtSvg >= 4.5"; } + QString shortname() const { return "qt-svg"; } + QString checkString() const { + if(!conf->getenv("QC_DISABLE_qt_svg").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) + return ""; + return ConfObj::checkString(); + } + bool exec(){ + if(!conf->getenv("QC_DISABLE_qt_svg").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) + return false; + QStringList incs; + QString req_ver = "4.5.0"; + QString version, libs, other; + VersionMode mode = VersionMin; + if(conf->findPkgConfig("QtSvg", mode, req_ver, &version, &incs, &libs, &other)) { + conf->addExtra("CONFIG += svg"); + return true; + } + return false; + } +}; diff --git a/qcm/qt4.qcm b/qcm/qt4.qcm new file mode 100644 index 000000000..c718dc882 --- /dev/null +++ b/qcm/qt4.qcm @@ -0,0 +1,36 @@ +/* +-----BEGIN QCMOD----- +name: Qt >= 4.5 +arg: enable-debug, Enable debug mode +arg: disable-gui, Disable qBittorrent Graphical user interface for headless running +-----END QCMOD----- +*/ +class qc_qt4 : public ConfObj +{ +public: + qc_qt4(Conf *c) : ConfObj(c) {} + QString name() const { return "Qt >= 4.5"; } + QString shortname() const { return "Qt 4.5"; } + bool exec() + { + // NOX mode + if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) { + conf->addExtra("CONFIG += nox"); + } + // Debug mode + if(!conf->getenv("QC_ENABLE_DEBUG").isEmpty()) { + conf->addExtra("CONFIG -= release"); + conf->addExtra("CONFIG += debug"); + } else { + conf->addExtra("CONFIG -= debug"); + conf->addExtra("CONFIG += release"); + } + #ifdef Q_OS_FREEBSD + conf->addLib("-lexecinfo"); + conf->addExtra("MANPREFIX = $$PREFIX"); + #else + conf->addExtra("MANPREFIX = $$PREFIX/share"); + #endif + return(QT_VERSION >= 0x040500); + } +}; diff --git a/qcm/qtsingleapplication.qcm b/qcm/qtsingleapplication.qcm new file mode 100644 index 000000000..ece9978c9 --- /dev/null +++ b/qcm/qtsingleapplication.qcm @@ -0,0 +1,26 @@ +/* +-----BEGIN QCMOD----- +name: qtsingleapplication +arg: with-qtsingleapplication=[system|shipped], Use the shipped qtsingleapplication library or the system one +-----END QCMOD----- +*/ +class qc_qtsingleapplication : public ConfObj +{ +public: + qc_qtsingleapplication(Conf *c) : ConfObj(c) {} + QString name() const { return "qtsingleapplication library"; } + QString shortname() const { return "qtsingleapplication"; } + + bool exec(){ + QString s; + s = conf->getenv("QC_WITH_QTSINGLEAPPLICATION"); + if(s.compare("system", Qt::CaseInsensitive) == 0) { + // System + conf->addExtra("CONFIG += usesystemqtsingleapplication"); + printf(" [system] "); + } else { + printf(" [shipped] "); + } + return true; + } +}; diff --git a/src/Icons/3-state-checkbox.gif b/src/Icons/3-state-checkbox.gif new file mode 100644 index 0000000000000000000000000000000000000000..f7918e84ce2f365bce7eab1f632432240dfe871a GIT binary patch literal 322 zcmV-I0lof5Nk%w1VGRH$0E7ns98rKFp&{|{@9*#I`T6+l?CJCK@&Et-_xJYo_4MWC z;^^q*`}_L-{{GzD*W%*d;NaW+{rukE+4}nV{QUdk;@#)x<>le^_4EDx{o~`` z|NsC0|NsC0|NsC0EC2ui01W^q000HYARvw;>6{YuC`&O2BC4{kV8rR#zD6SEG+qKB zn(b^uf=E~EAqWgn5cy<8L`Nqy(hxP1*2Y03ta1-y0Cg)ym)`KWs6yXhESKiIV#hZ# zbA5R)0U1O9f;9mFPa<~#ii-pjB6y1eivg1qB6*pT6BHU=grK5b06ZC*p&DW$Hinz7 zZU6?dt!-&?yl^KDKu0ma5XD(ID#Z{&KQqcyMJo!^1l83`3ZI!!QVZIWR{%#5S}{rU-#^xW|9%5S{`_G8k=zVG=|5luWB>#JF#yj01oZa& zTu&JQ008~}|NQ&{0055x0sR95`v3p?1_t~7{`v!N`v3d-{`&g=`T6amqXIBA$0h)T zKokWRkpoMx|Go@O4FvhR>O1p+i7`B6t^3)y2dJ<#?4I?d4x-E}Az98Z`2`TmzkmP! z{`(J9{pauh-+zJD{JOYLhW+QSzkh#x`Y&wke*WLjpZ~u9`2XuCr@{^OJ|MkZb_UGR@Z=V>fB*iaq<8P{*B}2u-uMnu#J~U$KrBDL0bT$1_irEqiZcM6WEF7g<|*+% zzkjHi-TwRc=f7_t9|K*?`1?07lmG&V<)V$@{}>pUYZ(~+fDw@M3(WY1!T<=sp}f-o0K!lJ3<>Jc!&VtMslE3ph2^H3FGe(F z4|^}slF1@l1Nxc}^5hjjU=0la|37)k@b@neJ^1|l@87?_{{z(l6@kcKe}Db@_Y267 z<&g#201!YdV6*>2R0EZ*bYA%%2Vi7me5m>mAb?naPGtnD20MY__n-f`0mzg8{s9CK z*hzmtW)s%H$oS{aAAkS?JLxaT`2W9u;n%DD1Q-B%#%TuGpFSS|0000&5HW|5#c7{r(N){s9YCi84$~U|{$Glm>AD0*K|^yLU}ZO+eP) ze;~;4`#0mCzs$dX{r~-&?f370zkUTM{{OB1_1E8DKmYz*JbN)f0I>i8Q1#1Kum1f0 z{pZggpt}FRe*ORX>;JEx|9}4c_w(m__W!pfKK=atLxM{ZXbC_7vHbh@@9*EgK-ECy zzkh)Y{?EYhFEQc&-#`EN9{7Lq7*OE*@9)2U|NQmmC(vO40VtezBLF}U2%?OI(TG)& zJC>!~;SYmN-)zb6gc(7A-^Q(#z0vHb9!CJ#T#ii{@&pjek8j`pfX)5|H00+GpnLvt za{MtfWBC4qk%R63j~{=2{QLgr`wyTb*amx2hce{;{QL3a|BhWh#6A5bKmf5of*%NgdVm^$Zuo!gI_LQd|G=96g51yWl0Agf71rLE? q3XWqq@&Lw?Iyk0*94-cc00RK~MQKxxUU$F%0000= z`}|7!`YQYT5C8xIh~*yx1DgQ1_jkSr_QgN{Gn)!7=zkRT=l(yS{y%^Jd$>%yrP!)vVq~xpZ~xA{{HjZ>hB|)Z~OQoBLBm{yCqA0{k;C`&+mV~|1$jj15^wU zKukakbkF}kzkmk({q_6zmUTZaUWBOraqa5!?(V-pgMR}R{04?0&`AIR#PSE^hrdi> z;*7t4gLVFSJ$J5DTibsorq@%ai5h7B2l^1G@*gM=fUW@uAjYc<48V{DX@ijvE(11_ dg@FMezyQzuBHsGv+i3s*002ovPDHLkV1jTADB=JB literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ai.png b/src/Icons/flags/ai.png new file mode 100755 index 0000000000000000000000000000000000000000..74ed29d92616c86757d3c0ec04378301c8f591b4 GIT binary patch literal 643 zcmV-}0(||6P)ocPy#thD++(+#W%SS0Qvp^`1%0+_yGC)0QUL-|M&m^ z`T_tk0M7pe&iDc7fh@K74M*k&0{8f*88BG;;GY6ve?;&4{{Q>_{{8&^`u+g@|Ns5} z|C?Nv0*Gb#mu+n4z6ZW~#qjy_|6ji&ZeIEMk16oyzH)i@Pk$MNxLARR?a#kwpMS72 zF)}cG2M8dRUN*~81wCz%$A2$f`_IL|A|w6j^RHtc7{2`lYG-KkQ{(*knSqh%3kzr7 zs%s1kKL7#%F#yj00-^B^D;pD^^AqC)4C(?1m>@q26ceiU4*2{4`u_d~@vQ*ykp&A1 z3h$o${r~^~`vQo?Pm-bY@cm79zVQG5%l!B6)Riap%L`bGemnT<@2|iAfl64!%YWS~ z`p0YY_dig_cYpw5WYAmG*lPLk!;jy8|NZ#~MF0Q%{rCG1ko^Di`(Fhkd3F{?py0c9Vg{{gA~^#>F<|Nj5KapBR^@Bf~CXSi|t;lF=C z8-4)<5DUX^V9+rDCI3RuUy#}V{s46X!}R~}@4ug&fA|+@;n!b(1zCZ900KKMX({{sIILBZE*UQbc|SngJt$+`m9Kz!<;5 dBm+Qz0RWL%NC2%sdjkLf002ovPDHLkV1lARHI@JX literal 0 HcmV?d00001 diff --git a/src/Icons/flags/al.png b/src/Icons/flags/al.png new file mode 100755 index 0000000000000000000000000000000000000000..92354cb6e257be2cade71cb825027ce8d9efc06d GIT binary patch literal 600 zcmV-e0;m0nP)PbXFRCwBA zyv)hK@{fUmi2(>${xJOc&A`II@PmN?BKC`c;SU)710$d~Kmf4-r6niy16BY3`}g0! ze=L9h&Uybegp-Ns@87v^zGQMU|NZla@z1Y+zkdVKmFbHB0*HkH4F0@)&iwE1;&GRLuzkX(OGXMMa``@o$|Ni_2x(y(Jn3#TnHT?el|IhC;U%pHK`}6Df z@2@|9J^lXU=Z~KvfBzi*^!4A*U;lv`e*Fge3Lt=(82$q_`~m9z|ND;$!(WEqze~6o ze}X|JFO$H(U+VvX#{c{avi3L7@c;n?3L&6l7=Hix`}emN<6i~#|7+iUWBL8-&##}m zKKx5zXJr5LA80nvkwCM6egFs{po9Y?& zL6B;olm7ns#=rm&Kp-3b{RIXY(1{??Ha=$NKfkS+|9@us$Mfg+93j@fzkY#y2y!;i z&kO(o1PWH5>zPHwn7|>;0Mz;WPl13iP!Y(WKYy4&4hBXMSPugOKmaiw2gk!dq!|4J mj$lZE0R~eis zC&uN{cDQ8`!@ZNLOqwtoG6nhzPx}SV-d6yzFfcIz75{(rngJyDkKrFw8iaoThHCr$ zo8k9wMhS^O3=9AP!~%5B|9}4(ASQtkLN$m1CV&5705X362095KfLKJhW;OjWdGY7l zzrX*$DuLu*pcFC#NdEr)SL!$SY=)lz0mSm_*B_u)|AM4JP)(}33zy1Lc&_o7? zKL7y)bkd){fBym<_v`mxpbeRs`+WRVot-5A{r$IX$CJFg13u{3eX_{0R++j zR}GCkSy{&4zk!krKoTg(2n-k?g31B}5JW!NMq0d0000q< zM7LZb@rX?|r)2RP-+aO3(7q?c3+$-Vv0E)PxM3SDV%@s`#GkZvw_x^WBa~uq3^l}t zWdf(j(=(>^SgETc#5#EZT(4ObRkfxbzP9G;yza0;Ygc8-_*?EP(ca#`l6-Z6D0{tL zQ4|~MCSi!9Q9YkW=V$ix#EqZ!rc?eWA0TwdVID+3aqrYUXUhCI)Ad5!(cP!BhhW$Ayb2&r8kK!bz*2`~UE W(Ndrek0Jg50000NL7TW{{R0! zJP>i}(MpzaSkj z=eqvqa`^|6{{QbQRQ11q3~Vg_kG}Z}5I`(hw}ncX8D4$|h64jUK>or*=^r$dfI%n0 z$3MKz;!F0w91GjkkV%_X`@4 wKR^hm`X5LwD9*v?4;TUC6Bz$&3;+QJ0QLcJ=WT{TU;qFB07*qoM6N<$f>3bX%K!iX literal 0 HcmV?d00001 diff --git a/src/Icons/flags/as.png b/src/Icons/flags/as.png new file mode 100755 index 0000000000000000000000000000000000000000..32f30e4ce4eedd22d4f09c4f3a46c52dd064f113 GIT binary patch literal 647 zcmV;20(kw2P);Rmc0RI30 z|Nj5|{Q>>`0R8>{{QLs@`vM01^D6+%Ap+Y10Qw3Sr3ED)s=c}b05Jg0{{#dC0RR60 z)z$y}`~dv>0Q&p?0Q>ne0Khr|#}EMN1`-ttJvaFq6VTDg`OMJS*4F}vg#m0fQ1$QM z42u6QTCg3Kt8+Li1J#Y_zUd>4Lw{URe1tEjLbKmY(S0M7pd(g2qsJ0|z;{R`~d z`n<6E*3bb41p*Zr{{R344LkeqyaMyV01O!W0PZ0+TjlEQ0st`p&i?@b0Q{Gi0m{n% z`T6-B``1JQx+4kM0{rp_FfRy7P6Qq%_1|&<`|JPx`Uew8u)+%h2+ zdiAI7xt}_}e|$CmbI9$2>u h*D)|iF)#oG7yty8`q2#I8zBGy002ovPDHLkV1j5VEF}N{ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/at.png b/src/Icons/flags/at.png new file mode 100755 index 0000000000000000000000000000000000000000..0f15f34f2883c4b4360fc871d7105309f1533282 GIT binary patch literal 403 zcmV;E0c`$>P)@|4`Xj5kLT%`al?B=W5I`&prl$WjwHQRjfmQ&G0jUOA z@&|Dug_Rm`2Y251|$~)1M2@@6mI}!8O6olw6y^Q z5X--d7nzS8`+x5q12kBmVFD!~j6c5_fMKno0(1^Q0I>i=is|LjXX40RRttS6cG0UZ?;7002ovPDHLkV1fxUnjZiF literal 0 HcmV?d00001 diff --git a/src/Icons/flags/au.png b/src/Icons/flags/au.png new file mode 100755 index 0000000000000000000000000000000000000000..a01389a745d51e16b01a9dc0a707572564a17625 GIT binary patch literal 673 zcmV;S0$%-zP)>fJ3En$GhGS>sbE%%m3$AD)q?8M9y>88-}kR7#RKlk!P~Y_PLuF7~U~3`~nC7 zF#yj00ZUDdpLsm{7ajP|&HwoK0Usg|6%f4L_{`Mi{rvv-`ukf=Ed&Gs-sA7L!Q7*a zj{*QO0M7pb%?Sw^g@yy{>ihEY{`vU@3=8@G0rvO$i3mOL`~mv-`W+b$Mmr&io5dg< z5v!7q0*L95jt`TzK8Kd(Utv)OSp_aLv){6ccV+Z`{Q2+asKUU&aO3`Kpz6wW8wp`< z28M3{0mSqnB#A*-c*8%1=RD#sSOwMznKA3=e&iEzwo{cA=PgXK`2OQ}gqId83!|%* zA_Kz@fB*n70M7pdECCwp4H&@R`1|(w-}M5x*74i)0}%fAt;XafA{48))#>Z>?CD#}*e}Ret0tl$#*RMZ7}Jl7Z|M45`5*URzH9L z{rmSnPy;{!u>dsyO%meg+00000NkvXX Hu0mjfN{&}S literal 0 HcmV?d00001 diff --git a/src/Icons/flags/aw.png b/src/Icons/flags/aw.png new file mode 100755 index 0000000000000000000000000000000000000000..a3579c2d621069c8128d7cf16440d5e45a3ab3cd GIT binary patch literal 524 zcmV+n0`vWeP)^}0h@W9fA9JOn#opKkr#VO<{LPm{QLg}EdH3Vb1Zzpp zqiZ+XNBm%5{`ViKi{bCTe}Dh~2a+HyfB%6Q|9}7eKVjxEfB<6Q<6r}-{{7;G=hB{; zLB+p+|Ni^;|DXT={s75;AoBO$f4@PDf8sps4FCQC1Q64wUw^h*hy4HZXO3U)@85qw zD*pci8U|DWQu_BVi2MUWKoOv;00M{w=;|*lY_o%kegGx^{`&*A{SSok_usF-P)oof z|A86+0*K|;FQAM6fB*FtoEI&bZG5mq328#as{}<$F zWDQ{Ffz1MH001phxCBNdC_2H6U$AI~GQbEJqg*Ti0R{kQ(yH?TRrCY^ O0000^@RCwBA zRL|V|7QjV)*ul;Rlceqc6W0{`~_8AeMg& z|LUXE8U8c=`}dziv6P|mEu%JjM}pqh@65md|Ni~w->=_)fBgZXe?Nc!ot?WGAOHX{ z0M7pe`uG9>{{ZXo`u+d?{`u+u=j#9V2j%Sc^797z|N8p+{rLO+`TP9&`u!FW2mk>3 z0#G;xDFDDQ2vg|)-@5Zw?JVTrAxNs~5&|AZ;5uWfQ`vUsMGm`>aGWoI7=P|oW>%~E z|Kk8dq@aG@HzdsB>fj@shYzX-a%=q<(frSYmfLIv5{HbzQ${~M_P_y6C&m>3uU0*DFd0+8#0#Gk)^|NLQBRAyCBeB9H+Wn{=Mr@*PJ_ZKV< zB>w@GFfafF5Ks>TBP0ZV{bBt5_ve*sKkwd`OiO#eX6=u=cfX!E#rX3NBT(umNC7Yu z0Ro8S7X#4ce?Xr63$phg)Bk64X8r&5``_O`AFf^jc>p5y?+^38KVKLa00M}`wU!~x z=I_1Fe}Df4D*yZI@1I|PfBgnRptt`0`2{iqMpRNPo|?TW>MPOFW(r1_!xlT-yep5|G*@e%^SFxf#DC32@n7=0M7pe00011 zNe=7o{FIuhzQ(sjF~t7>`T+s_0sj00{`>*}`~Uy^|Ni?^Z7Tcx|FW0O0tlpm;s5{T z+df{s^E1rDZN;v4VP>0|8GkY`{`&t1s2YfV{r~st=KUYCl59Xr00M{!Xv@F<41fPH zoWA^R$>xvtF5yd$xc~X{7o-}f=ig7DY9RXc``_>1K-c{N2q2&ahQEIq{`~z1RCDs; zw*~7zIJ!sAKj8J}&!7K)enC|K{|nUc|Mwq|27mwp*#K1f8;Jh=2byv8+}GKw-@AGz z%-rMu^XK3HKtBLA{Qvdq*I%FsKn(x^1k&&qY(LP_Uw?q)|3jz0PF?=a(?4bU?qHzN z5I+E=z&88?2q2IKpz*){`~&I%+VJc5-=Dw#?LYB#!lHLRL7BZ8-NZ5x*TXaKmf6TZ20qEQj`^F;~x-W z05U+*fBxNj@_W(7kJ(ujGnWgh$g%(Z2hso#K#U9wI~hQ+`3Dk_7z`j1tL#*2FTcgW f@C+EF009O7>dRn2w6d?H00000NkvXXu0mjfueTzu literal 0 HcmV?d00001 diff --git a/src/Icons/flags/bb.png b/src/Icons/flags/bb.png new file mode 100755 index 0000000000000000000000000000000000000000..0df19c71d20d7fdc06e1cba01028983439b2bdae GIT binary patch literal 585 zcmV-P0=E5$P) zj51&U|NhG$_=oZTA7 z0mJ{l|Ns2{|Nr-Y#^3*c{=WU_!>_-;fvROCxPdkR1P~M0Xa=C_KR`47{sXG+pY!Yf zqu=)*{%)W0>;M0szkdJy_507SKYxDz`3KYh5I`&-cY{^``2$3Z|NsB`^ZWO@y}$qd z{r%_nFQBC$4Is{6hz5WF0@(mI8^j0N`~Tl>LzQ1Ye}a&q>MtPo*RQ`|OMu4x1!@2Y zAfSdne}TsT{`c$8-(P?J0c~)w`~?J`zx?#Dg*yp^z&88=2q2IKpt(TRKniTbum8-y z1bBWi0e#F0wgIH{FVJ|Pxj-8L0tgsNfByUdJMs7b-@h3^8h-!E3i%CU{QCW$1*GB6 ze~`2PfHeF82q2&aU>N+96yg32bmdP5238q{|Gydk0=52OVEN6!@<&OA7Z~7wL16>b z@DCt>7#SFn85mf=5eY;LZ#OUe_l@D-2Zn#Y82<4v{9|E|jkRQ8_`$&N0jL_N03g5s XX0T^_9W~6o00000NkvXXu0mjfXpthO literal 0 HcmV?d00001 diff --git a/src/Icons/flags/bd.png b/src/Icons/flags/bd.png new file mode 100755 index 0000000000000000000000000000000000000000..076a8bf87c0cedcce47099c6b74b59f2c9d1dbce GIT binary patch literal 504 zcmVCcfPV}OzZe+)fYC1)`hmpw%>WR9L@~Dk00x0r!@5ksR;+hV0>ZLfIcBS@orh;x zv}95za5W)x_7^}bV3YqpdH?h;NZnuSC%?V#{+0gl`~RQckJx{&l>NO~;@7XgzkdJz zEh{VwR0LSuiyWGR{aKQ z00-R5+27mwp+3@G@Um)kt zzdstU{yWl9SIB_0ft3II3)BD*KrA2|{``^Tm;4PDy`=a1tTre>fEI#8 u{{2z<2NVVaum*qtVq}m+iAaI~Aiw~?reC_kVQV=60000gsB+3J~Dn`pdxgmx19A{hgns>oXkhsL8>j&wfIu2Rsv+R_ zAB5T1GyoL?1Q1BWpFe+p|Nf1n;TJ-~Kd@?uhChFRHUI<=#0HS!U%!8$YJib28yLY( z0tg_G2B7i3e*FSj@aq@44gY_`jRywQ69xu=0D?FP=vyd&x*M*V6|CV8P{Uu4OBfgc z0tjNmA4y3`us8lPG6H?}8%zRafgb(Cp!5f*6oP{xAq} rF#LPR@IoIX4%E%Yz;K6w0U*EtuUcjA`-_J300000NkvXXu0mjf+>pV; literal 0 HcmV?d00001 diff --git a/src/Icons/flags/bf.png b/src/Icons/flags/bf.png new file mode 100755 index 0000000000000000000000000000000000000000..ab5ce8fe1237a18d6809a5570024eb108cb14a3e GIT binary patch literal 497 zcmV@|4`Xj5kLT%`al?B=W5I`(ov;U*021-Lr1*!W5(gW7O z@cTDV13&<=05Ky_HBiN$KMcQt819e>gHP`g_|Np;&&;0(C^$RHS>olZ*Q41X9v27}ar6#W9}0h{^{OajIK0?h(y z_zOe~zZd`lhy{p$|NA4!EeST}?;nUxkP49VfMx;1;V%&U|N9rH;SU2q05LM8GXV8K n(H~UyA0);fa6B_H00bBSQ>$p&WfB*UmB!B(-`wPhZ^#?@C^U5EbbPyl_g=3Hc01Sh${{P9=HB%4| z34*<3-m=C?^;L%miR{xQv2*hU;8+Y&0Dxf-W~KjsusWFAC4@j0#9_j;X5z6SjRhH> zd}sd(7FPhVFdSi!*Zj@;_Sc`kfByUdk|3A-`STmZ_yb~qxIp9o{E-p)bLt=iKmf7) z+|Ix(`{&<1pm88mK&}8g1WG~}e||Ik`OB#Cw~m1UAb?na(Zlrn4}+v6P!1@{@CT$5 z&-#|8y{IY2iKmf5omHz(^qAp)ym^JhN+jk7Vet{H$(Z8=>|AV=V zva&!M00M{!p&AHub^kXuF^G#pRQ&(-8^nMkpk@XJfB<6o_wOIv5C1P;X6Wwu|KUB< zc%X*g2-OTg#J~U$KumBafq;(A|A`a+OH08N{X($;=pP0KfB<5Fs|GR7oM!0i{{QYB zSm|$=!=N@Wf}I2qKuka<{f7YtBjf)QCj1u{`~UM7nrdKh0c`*VF+c!8{Q&j%sZ;-Z zd;dRshENS5{{S`og~Sg)05QIL^-54s5b7kL(8GuS8yfz9{>%Ui`+q-vfW*P*^_43C z0mK4S`s2qBh&}(NP5W0_$$%QQ@R)`GfB*vkck5Jby^kNv00000NkvXXu0mjfy0pt~ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/bi.png b/src/Icons/flags/bi.png new file mode 100755 index 0000000000000000000000000000000000000000..5cc2e30cfc47452d5bef949628e955a522d59e50 GIT binary patch literal 675 zcmV;U0$lxxP)$wbBBJ zMTk#;k4<3e#ePFE;{?TciOx=-NpIdg`t|#dcz^$YFqm+of7AU<7UGr+0t^5F#PsJM z(2)${Jd)SmT+KY5@!|h>po)L5-!r~>3uJux|0`&Jz~QGy6a*CiGyVtq1|Wc#zWw|0 z_y6C2|NnAvaR2)A>-NX%|3Ci{R?!hvH~jzU``ypCK7Rkq&&~h)FDNvCApj5nF#yj0 z0_X_*{{Q{_|NQXv@Av-qBMmR$teo!O*6-%u-J+8r3n~2s`s?uP{Qmp>{`~+900M{! zNC9;}eE(3IS9-C{62AZc<>Jx>%af}0@?r&05Jg0 z{{#T;0Os`NWh`ko4>SM%|Kw(60099Kad7|t0qcf^`tR-^sIP`Fhru7lkI#w#>Hq?W zkzqQ+@08y_|9v}t;{CEE%)%nTc=-MC@P)7S@!~g$((Ud|+28Q224FCZIGXF0FQ1zcbfB*dX_lJRr z;s3wCNa|2D02KoSAbE^!0Dxf-mZ69ApkCb5fP^9ydGO$cm6w`kGj(t#`M{tFlLo%j z*4%mm2&CaJSn02SzkrtfWBLcO;r%bLy5Gnoqrh)qC;VKmZT`F#yj00W%wG zw4zx17##T6*Z=hN0Tvey7!|wG?K;V)0{r{_`}_X<{Qmp<|NQ*_`}@YSvI2-@&cAgG z*R?p0?_>V(@&EVlEP?{x|1esA`||VNU68t8zyJRJ_3zg&hTp&0WMzR?0R#}s1|E|% zRV}tRkH6o2#3;(nsVMXI-pgBmh17ms`TzTu!pfBl%*_9R;OEbWDJei#0R#}sGpDd$ z96Spi@~bn7G5z{~^_!ZLy2#s;5B~o8&G`G*|6f0Ap0WS=_rFd2C(ubi4FCZEF#yj0 z1a!1=2e0}MwgDi3SU@2S4mePl{012eQ4J-3 z|Mm`933BS6zyJRJ1;ztF0D(08|NVzmQWB*4&)@%$um=Y`lmy1W-@hDx{{qQh3=9AP x#JH7#;TJ3-|G=X54_FW_j)5c_0|P*S0RT0dOSD~(4;cUe002ovPDHLkV1hfJDkcB` literal 0 HcmV?d00001 diff --git a/src/Icons/flags/bn.png b/src/Icons/flags/bn.png new file mode 100755 index 0000000000000000000000000000000000000000..8fb09849e9b5712e9cdd8a2c25035da201535cf5 GIT binary patch literal 639 zcmV-_0)YLAP)8n_8%|dG+hlCr-g% z|9<~wU<9iE{r}%DMphZ1Jpcj3%*DZBWo-@72DFWlk(-gj@!ngb-$#D&C_i9e{QvLY zw|{?r|NHlgiHY~?^IHG`05Jg0{{(k=dF}7->+9=cXlNG}79t%T{rC3_t(pA#`tSX# z4jKOh|NsB|;rr`({{a5__y7Wk5omBxQSrlv5B>nb??0VZ8qCZrpS+?}gatn>o%-+B zPl=+||6st##PspQ2Y>)#{Cu5(QJ~_^?faD-pMV;E|7MwLubjQ@B-gLso$mVYgECpU zxpfp2fEt*XnBKpC4-fz`0M7pb@zVeZ8g>5r-~k2r`Sbhd;{WmN02I(80QmHEv)Ik{ z>H7Nm`}_MdF)?FhWi>T50*LYBMFw`s0-y$le?J(QfB$Fr_2c8e-`_!j`0PG|ckZ*_ zzkY$-`sc5Tips@{7Xbo@1sGC5IYwrQfB%2{|MTZR!ygX*-%McG4cZmTY ZzyK0(F$K@T-Dv;-002ovPDHLkV1la=J3;^e literal 0 HcmV?d00001 diff --git a/src/Icons/flags/bo.png b/src/Icons/flags/bo.png new file mode 100755 index 0000000000000000000000000000000000000000..ce7ba522aa7e948d581478432643c230eed1a658 GIT binary patch literal 500 zcmV^3LvnC{|x`%yaFl$ss8ha0V@6XKS=c-5cwO(_{}IL0ki=i zfLOjo{AE-9^-mn=h(G`Tfz|!{{r?|W+uz?{^yeR#!Nm9NlRN`J0I_^YV&Ikj@%Q)F z|Ns9m{0FN3^Z!3k!*8HnFvf4N5xas50L!z?-wXsAPk7$ ze<1l+iQ((fPYeJ7#KQ200VpKFA^{3Nph^G!{9^b86oDW}(Ek1R7ZiL9e}Ret0*H}e qBRB&8AR!3%7c6cef(%d+Aiw~vBYd|xMihYn0000j-HAXl7XJGjM{~r+i{r~sxzrQwG-&h#_Y&p;L z=ieV7_s^f-zyJOD{rC5(+EoAn1k&)I;s3Kw&;LT?{{2}P{Pq8T&j0^^J4?LvUd;UK z&+k8ffB*XXONL(tXahh1fi?X94^$0Q>Z$uRRO)Y4)uapmB!2(-ul(c1=C+V!kAF`) z$PCo;`_FHns{jIs3Fu;wy-Z(c2YwAz{&V4aXk?bejFO*Op&u`@i~PecqBpL@DIoojb8mb+WHGK%fG2>)a3=iVf_~v+`s?*1;!`?Kmai^I3i*ZIYtpN f{g(k500bBS@Ns{bTs^2gCr95H^s6Fo1}O2_S$Nfl}4;<}o-r{^R8Q_xtzX z|Nnu?|Ni^;2gm@D3=F@4EC#P1& zzuV{ie)#0qf2Lnh)j(~3VeG$ufPMl9Aczeh3x56n#l!R`HRQLfpFjVwfkN;%I39k( zVgne^e?jDThF>oL0*Hk{T6(^^8pGqq44*zhqZ1OZzkZ>_F(mFeH~<0+0A4S6=>Lb* QN&o-=07*qoM6N<$f&=*Yr2qf` literal 0 HcmV?d00001 diff --git a/src/Icons/flags/bt.png b/src/Icons/flags/bt.png new file mode 100755 index 0000000000000000000000000000000000000000..1d512dfff42db1ea3e7c59fa7dd69319e789ee12 GIT binary patch literal 631 zcmV--0*L*IP)?&DC3JV7l?ccjcgB=Qq4l4w|Q;eOZ4z|IjsEI`#PYSloM|AFHF zfy)2>XZQ=$@t;lU|F1tRzpnmg{PUOLH{-8A|F{4CvUU?d0I>k|0TuuM^_1cNUy$nm zzZn?*{^!*ACzSEy$NyhHzB0Wn`TXRU=!%=n%Ci4h82|!^32gR%glZtk^6USnb00o@ z{`LDW>%U)&BK_|-y-75RkKVi&O=|xC<=6keK+72b0*D2q;Xlai|Ns9mF#h@fM(h;aV>^!x1-zNu02XV-n@ zm3imZ@&EI0hChG)|NZlafdL?Zn1I0yH26P<=DUx29QQsc%}izF;QV-S-hYOl|1V4z zX|a-<=Kf#g*Z)7i{{y|szyJ_HEKEEM|C#>$KmJzoZa)M2-~Wm-e7Cl+vi)L|kY`}} z&A$F20RV*|BkB*O Rz6SsR002ovPDHLkV1m;fPLlut literal 0 HcmV?d00001 diff --git a/src/Icons/flags/bv.png b/src/Icons/flags/bv.png new file mode 100755 index 0000000000000000000000000000000000000000..160b6b5b79db15e623fa55e5774e5d160b933180 GIT binary patch literal 512 zcmV+b0{{JqP)O=a{vExMP2%`MCSoB^FIcLe_%lf;|~%E5I`(IQNh}3Ao>6Q|DFUXMn*>AqQd`w z|1kXd^B;tM|Njjl{{hM0zwd6?1Q0+hV1xeud-4=Wy?p-%sO`^#2S61Jzk!N?s)6X& zzhA%p|N6}=D+{y%Ab`Lc{sL9~1=0UN4*CD*7s%9KAf+JHKs~=eB-8KTKvw|-5R1&; zzd&a|ob(5%^Z$Q=wHy9p13+aOpFRNu5F>N&`Tk_-7w>=n{RejQzkfh&Kn{rf10?_b z{tFTZibx5v&dxav5I~H7|Ney-|DWN1$%1FyagzUW0464;_wU~W1Q5$TW@eGxtUvee z3vAf*8|igK9~@*rr66bh|NrkNM8z+V zAV?>O@ek;bKfu6d00k6 zPW&$KB`I@TtA?2x@Q~7pdcWi#1>DDZ2>MuG0I@IumHuaV^&7|soAMvT0IK){RtF@1 zgH;3B;_Qq-34j1%{P^)BFE1~|NkA(gBv!!4$aw$$eSiRB1ga=2D|__l(H|iA4T2Ex z>lc`SQ9x2&UjE?0g8%`<0`lvhzd$}*14J4{IhY2@0~G@V5J82%q9;EBlXu0U&@_82I`BfBC|Yn~P8llm?myQ3_K18=`^X_ivyEfB<6p_xd%%#*GZ! z-C&_V5IGPDK|g;X*gypg3;+Sd!XPTj0Q7fK5>&$Y{sHB| zjK9DB00sa3QR4q|tc?L6fSCSm+3>HW`NxbYpP7GsX8sK%KS9yYPfWi)GJ)AFzdp14 z{>t>1fsFwmfLQ*Ci!yxq#8guv=_mQ;-(Rp{AoSPbXFRCwBA z{KboB21 z`ppP*BG3|`!vO*asNvt=e_;3gWsp&PA@E<2jYs6ilRy6-zmSku5?~OOP=5aV@4sI_ zSN#QP00zQ!JD>SpAKYgR_QStF|9~F;2M|Ck zz%U1e+FyoWe;B_0VVclq;}vp_kNy3hKMWrj7*{kqJbMcaQ;_Pve;I)x1Q0+h46j}> zeiN4E1lkA+>|e|*mzJsW^M3)l^W_^hf&c&c`Mv->`48yHFF-%s0|+3-*GLfwiRNz% m3}3(u4lrUsie?}H2rvLBbQv(L;??y40000e`b1WGV} ze#gbd^&bp=ef-GykAYc$@BhDltSqdeSy?RXJpcawy+5fJAb?mHcsPJ&{d@EF@4HtJ z)qno||1xd*zaM|Ot4f#|8A1AQ-~Pubz$7IBv;-i4SQvovfB*ge{fFVtAE4aNE7yPi z`^Eg=5yP(^Ur(Q5`TLjM%#`8#_rHuB|9}1hItd_vSpNO`#qjs<|KGp=|NIHm@MXqK z79K7}ZvOwQ9Df%s{`~lX*xI%KzW-!k{Lc96Cr|@G0I@Lq`0?-epMSr9|NHeD?&umBG}6iH(DSogJte zDERNk_kV0Zng09%Itd_vSb&=T{rt@+B*66dJ0my{fpNkvBm!jpV_;xnVgd@XDk?Dx zh=IJyzyJ_HjJJUrz)|>#fr0nRl^;KTz#|yK`2G9$BS%LzureS32rvK^u`=B;c)+&+ O0000Vbu`-)NXk-Y`p?2$B#e1 z{(buQ`}e;;zyJNd_UF(2w_nb@VUiUP2igD-Kuin_BL6vl`zgIQV*mR8|8G|2U!T7I zn`-)Ow$bxne}9LGfB5z5*XcJ*K(;aeSD>o^0st`p&i@1e@&c~g4N@7~{}B9V!5sbp z`j|K8<@Nq-&kt=P>@pAZ`T7Q#;RiPl^j;kSgdzX}05Jg0{{#R8=f>y-z~LG0`u_d< z{QLg=2?6_k)DH^)`=sFo8YTUi-v;{r`o8J{6Wj>^)c^vB2^cJY|Nnmc_5b@He}DY@ z_51JdufKoSslWR1>-W9)3`r;XfsXn0`_Fc($H!lT!V@5Xn1Igu{qOIuf50&L{qg7D z?|*(LofMGa_%_k-*{}b_0g?9mMSwvE)Bq4bEIr*1})*zF_+U)&LMdEMOb{Nb-vOh6FrNC(tkd{&4;N%g_D$&)>g> z0^hO}m?z%iIsOJ1mka;_#K>R{i_RZNQ42x8VJSe8f#Ern2@qfa%&RHCyvg>Q00000 LNkvXXu0mjf=TkSf literal 0 HcmV?d00001 diff --git a/src/Icons/flags/cd.png b/src/Icons/flags/cd.png new file mode 100644 index 0000000000000000000000000000000000000000..5e489424884d2ec9e429f70d69af00edf242a077 GIT binary patch literal 528 zcmV+r0`L8aP)JkPqeYl28iLgD=0{><0$P44T5yOrT$dE?(KkwMFdoG^-J zGv9P)Kk|i5`lcNgUUAbboca5{hI)v&h!9!~`Yg)Ld}$VwYqqXn@gVLi>3LSVGm1W? z3qnDJAk6chH(u7f~FohUBCxfQDx8?5BQsCcprAnfVhO SHC~zk0000@|NZ~|iEi8i zh~?j3h8^dV0y&$fY|i?}`2XK;hJSzm|G$6#|L@;V)&KqZ3sU;$?>`_ZF38C6g#jRd z7@s_ODJ3Nev=9gw8UKSQhX4P)z5oCE{eQ>y|1j|H-+x9%#`EXT0R#{W1H*5i5@u$g zs{agN2m-%;fixfipeaCQpFe*F2q2cU!)f`}`5%6M06O*WzrTN({{8*;CkCkD_wPBk z=llWket~@P=ieVecEOTuB>(}$vTge|RYlbYUmpDW_v_E!KfnL|{{8n?G|>28zowm@ z_UrGj-+zAtrGTUoztWctUjPD#h2amw@BhDn5OHz(52cFPg zot=T34qlT?57Mzkg5?0ssOG0Ftp>paW8OyZ`_I07*qoM6N<$f+2k} AjsO4v literal 0 HcmV?d00001 diff --git a/src/Icons/flags/cg.png b/src/Icons/flags/cg.png new file mode 100755 index 0000000000000000000000000000000000000000..a859792ef32a02b41503b5ab5f216191af397e02 GIT binary patch literal 521 zcmV+k0`~ohP)i@P`2b{=v9^Ktp0uZ001fLMSM)r!?%mH+B91 z=ii?+(ckX8zrd=&8g~5t-|*}I50LQ;KzRlRfB=Hn08;wv->)Q*Kc0LLgTdsU-~VfV z{r~#=|1XdRMzE6r0tlo5X#B6gzhXrG`18Y*0!g6iieLY~Kvgqz}`W zLWO>Z3Lv@r7+CdZpiy8Ae}EeP0z(_<2Y>)#Vfe-1#`njMUlORAfdMG=o8iiD#%aG9 z#Q!h|feZ$rzkeYJ=p=vuV)VVru?7U|?FE@Zm|i>fBlzF zc~M_qKf%h=bAcoS;}NE7f8|yFe%B9?;;8%o@BeG_!|(4qhyo=(h-XBmKHXpc{~y!A z`THH3fsDVeudko)ARzm9UL&JI!+~uEM*rBES1=kd6zV%LH0J*N$gIQAc0y}k9qTFv z4h1oVG?rB#zNY^8{QUp5wE>>R#S4NZQd1i@F)*?OF@6y}@zmk^!Gr7L9asuAf!ae1 z{{CbBBH^Az=(+fAb?mHzA!MjRs*H~|NF=I z{~td;@BjZG-hUVsqZ#w(|L@=b|NQ>{d(*K^00G3pzycQk`jp|{UxvSb;p*Vv_V?Sr z{{Q;@@3$6WKrBG#F*5vR z`2XiW&+Xo6{KsbP_-SF+DJF`pL$*;0gaz z7NKVhyo`U;4*0+SK#>rfFFfafF5DUYXKh;r+@n*scPQUy6`!63S zGXn!71H*qtMn-04W+o=4|487=moEST#KiEAA;m(3;Xgy1iO{3BKc9a12~-UM7^Z`) z1qdLZI~bN-c=z}J|D88K{QmR*&tHcBxB*ZDKmf5Ya0q<-!`is-{h$8~f7m(x{QZSX zH3Jv`1P}|uy*o^wIGI2G`1kie)4zYe_&EQ6|NftW0ohon1}3I|Z{7d|5aVBMp0ssVo0Ek~;W>Z#0SJsA+2j`G% zv|UVeYYs-#Sn6_J90h1VosR?LBU7{U1rQ6+R0f9sPrg3=`~UA>#=n0a|7Q67_y6zT zP{j57|G!`V{{zu)Mn+knB>(|98e;E17s>tTLaMG-~Y>h{r`!g0jL-tfS4HmF#P%V_xIo5zyJLP zk|2W%e*G8w^1X|KC618W{eAoCFX+EI literal 0 HcmV?d00001 diff --git a/src/Icons/flags/cn.png b/src/Icons/flags/cn.png new file mode 100755 index 0000000000000000000000000000000000000000..89144146219e6fbec7eaa89e1bf4b073d299569e GIT binary patch literal 472 zcmV;}0Vn>6P)$bmtfBa_T{rmsVufH!rO2O)W0!b+P{TrwO zAb?mv&i(NBbu;G`sX*)cv$d*%>MiL-(QdhpkjakVmyu%k;sfcNRj;yhJaxT5MTg0u5&QfH8#Bf O0000XbC_7v4G9~kE;3? z$h?1GrT>4y7{3|*{r>Zd0U&@_82$jY{AFPH^Plk#hy=QU5o|Ds0oDLyFn~2M0QE2c z1P~*G;PKK9g@-SH{rUU<_aC4k|G@~v`1Kn|{`&=C|M{yZ!G37cNq_)iVfexD=MNA8 zh5p0Hf4_c1v;p<}|Ak}_F!%rh2&CcXZ-(!`82&@8$XA^gF6?xq}zd#y5N`WeVBbyB+frxZH0- literal 0 HcmV?d00001 diff --git a/src/Icons/flags/cs.png b/src/Icons/flags/cs.png new file mode 100755 index 0000000000000000000000000000000000000000..9439a5b605d82713decf23aba9c63c8d719cc200 GIT binary patch literal 423 zcmV;Y0a*TtP)R-T)##NTdjqb^wzQ(`1@?t)Ix4MUXz556teM9A7Ic zq_@itH|pv>q+zrjZJ^Hx5bj=fD{5McI3ol<@^-l_@~tZGV7p>1CU&qG~{YccyC-q z$8~P)6sG{nMmQy85K$E6L33rja$x-b9$ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/cu.png b/src/Icons/flags/cu.png new file mode 100755 index 0000000000000000000000000000000000000000..083f1d611c94a535e02954711486da244ec3c5d0 GIT binary patch literal 563 zcmV-30?hr1P)bRVNjfdgKH->)<41fMG{Q1Z53yA)}NHF>VM86o=*Z=~EMTLRklg;&|8vY-+ zh5rBh|L@=bKM?ZoKOp1JpMQV<{rmmr|L=eQfFkpA_5cJB<7Wm2?&_*f&z|!oCH%Iq zVPN&@1^xa7gnxhi`TP6#zh6KNfByZH;9_972M|CY z4S#m*VEXjw_teQhfB)LctFzlGTKpda#8eRa1F`|=V+j!s1_l{`0AhU0z`&K2_5c3; z?|=UACdB;@3Hy%?Ffai9!1(6P8-M@;JL%7#4}bn}Wu*W1^8Nqk|9@zxfJk8Yg2Rge z5=!5G`~e6c79IwMkAMHSMfCl8%kXF6O^EHl82Alg`~}6s-@pI={`>#;Kf}J}IRF8~ zc$$I1RCFdZQi0L={}0epF!T#d{sWT?V3G+SzyRi{Q|!NXWpDrh002ovPDHLkV1m+z B7Bv6> literal 0 HcmV?d00001 diff --git a/src/Icons/flags/cv.png b/src/Icons/flags/cv.png new file mode 100755 index 0000000000000000000000000000000000000000..a63f7eaf63c028615b2ded5878b5e14a7dbe962f GIT binary patch literal 529 zcmV+s0`C2ZP)*82p^=00=`tlmIeOf&y&dk@6oT z&CV8YCOfMzZ7b-;WHc4ffO0*K`UGc#9pHKW{n=1`s=Y4`sB0UGuD|F2(+4xFrs{6A+r|Fh*S$P>SRGs(%l z+O-QHfEa)O{tdAK=ovi517(5A-n@AO5I`)f0sl(Vm><0RZzq2;(QtLuuFT6X6;y@p zb-8u)9gSFj-3}5^z@SqUX4qfA01!aT3<}j|#!Osn3@^V(zxysO&hx#~ZN`f)vS*$d zpLlA?$HBnM&cM&k$j1o^^oKjY0t65vgZ)>ehy*ei5K#*ZyWju7F%Ll?01#jRixNU5 T4U6zw00000NkvXXu0mjf>cZT~ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/cx.png b/src/Icons/flags/cx.png new file mode 100755 index 0000000000000000000000000000000000000000..48e31adbf4cc0074f40e95f87c1f103b91fe270e GIT binary patch literal 608 zcmV-m0-ybfP)Uz~~Q*L}q{yKmai^Fs!d`Rbj9@@=xl~KZbvQ|NZ^*|L@=bfBpc` zKOp-38^rz{DEepVv)`L`Yyt=%76t}3hHqR?<~aN{I`!9n&u`}MKs~?z|Ni|Cihlk3 z1w?Q7fI4M?HUI<=3&<7!82Y{{Q;@?^mDN?|=V) z{r~^ll=rtu5CcE}F#**BRkyY(adR>Mc_H{~T5^XRV~oVFSgBv#s=t2z{grn0SJIVV z|Ni~D^5u8)5(a<(0%_pmV<{@S{pr)+Nt0E6|KyV7{&xHKulY}Z0S*2Ic2cIyuhSoY z&3*a@=p=vu0%~ALNs$10lZEA9e*W!WzkWV{%9A7hYlh}ewm<)V{rd@2{rBIm&Idr} z{RV0P2mmnv&i?}d08{q%2kh+oUtbt0DGA2L@2{yn^Xv%Q%_4hjZ2Q{KfBuh*0fWjOcoPYi>{Qk`ejtlm`TPy!Q@c0|K1n4Ay00P>u ul!4(JQe+}W>@P40kp+Sq42=5$0t^6?P(4CrvcmZQ0000s1`2Y9I{~ve$KWO@Yukru?KTxgz{s9CK3*7Y} zZC_6Qf4TJkuQ&gHzW)Di+kXz$|9k=eg(Cm|XMz~|=g%L20Ahjo4`KiVr|y5|U;qEV z`p@?NKb!P_9;^R?@o<+hfSm*oKp+h;f&YIQ*bg)L>I;A4WVP82*P-nR{;Wu@%{Vvyu7@~4txIf`R>OD+-01E zIfRil07L2S-Mat*#Q65@TRuKMWMi;}EJy%|ff@h;2;_%%@7_UT@edf{0+7H22rvMY Ws9gjvbyTka0000? z0048MLcfb{@Lpld*gfdL?Z zSQvhRtN^J#x6%GQNHxSfxHgc;AD{-1tAIKH0tl!9q}uD*5!1Kl8Kk6va!f$;fJ%WL z`2Cv^NdEc54D$xi27mx!VfgXqT8ME7!~2)OPy-`SXu#NiAkhzFFflLy1Q-A_8F>@M S6G{sJ0000h<6BFn%a z@b8~2SoNP@zd$;E{sbbRuHQd?{QCI=sNwhbA3*&Qe}GP900=;09NYi^fU@pUdVa9*13;+Sd!tjgXKhXQEMobL97(p6<{RLvMGBN!7 j!N9=G@a-1^K!5=NcXWu!7_DDe00000NkvXXu0mjfeQx^H literal 0 HcmV?d00001 diff --git a/src/Icons/flags/dj.png b/src/Icons/flags/dj.png new file mode 100755 index 0000000000000000000000000000000000000000..582af364f8a9cb680628beae33cc9a2dbe0559f4 GIT binary patch literal 572 zcmV-C0>k}@P);we;9uK`S<6~zaM{qBL9B<0yBR7V`E_e2q4D) z|Nnpa!Ep64!{fLA8NdLj;oraifB*mg`;Xx-kn#6Fhzn-q&in!pKrBENJRA&WD*ySo z7*5@0`26EP69WTC_22)0z>5C-g{l_hVFa245I`UeKudt6h7^Mc@BgDW81BCO4-x~L z`sXhc{R3+I%fRsKA3y*x{R6rHsA1>M|6jifb2E4w{z{xB{`~z5CPC;Y7bk|9<`c2PXgjR$^CT@Hzz$KrBEfF#?VC z^aSdB^z+g5SJMxCJOGqNsQwQkfr0#&=?~CJ009Kjz|71H^!MIRd#Ajb^76;aUyQ$y z%m(TN#spBq-#`C>zGeUjAdrR+|30kwu=eoBL!3-pGMq9%bs!`E|ACMovw

4;Zk2 z8GbPU1Q5%#7t@Nb6*GKbU;u{yA29j{CVzn$|6qa)V3LCYAiw~8(_SNKujRx50000< KMNUMnLSTY(1rd4x literal 0 HcmV?d00001 diff --git a/src/Icons/flags/dk.png b/src/Icons/flags/dk.png new file mode 100755 index 0000000000000000000000000000000000000000..e2993d3c59ae78855f777c158a6aae6c1fb5c843 GIT binary patch literal 495 zcmVh!ZNvLM`<}kPiIA3?K?Zl!VJuS0ABN12uI2v;s z000mK68GQM4oDR3?|C6;zBc4LR82Q1eETXSa+3nD0Ad8%4|Ml`Fn}2U{~ypshW{9V zk%{T!hYtV&#KHiVV*o?2zW>+&Bgm+K00G4EikX==E9>w5`yf~S`o*<00G4K6dZ++hy)_Bw{QPEdi2K7 l5H1Kw2asrHVqgFWFaQRwS@oh;XP^K8002ovPDHLkV1foV*8Tth literal 0 HcmV?d00001 diff --git a/src/Icons/flags/dm.png b/src/Icons/flags/dm.png new file mode 100755 index 0000000000000000000000000000000000000000..5fbffcba3cb0f20016c9717614127b89db4c9664 GIT binary patch literal 620 zcmV-y0+aoTP)yt}{r~U(pZ|aU z{rk@#!dhJXj+vP`D&$&!2yPR?Jud5I`&tqo00z_V3?cpb$_)%#~li z5Bw?p&G@T5&5h~tB<;UIJ-`3_mgbQL+5iwhOdtm^{QZlh+Tg>NcGo{qR#UR9ewx4g zlzHy^uRp(j{rmOj?;oHBfB*n70M7pb{ow!s5r+W$=Kufw0RQ~_o$a1N^GPoTT-yiw z&XGVBSbe$r0&xrf|M~#~9P-zx0st`p&i?@b004Y@cH`sX`~3X;`}>j`1PlZ1WGkKd zF1~FN+w&9T}cJeJULy4V8r?0tNHM6WN&<2126ppbC05A-~q$vMCOd&N)3^rn&3WaiZo>@dB zxpL5=L>h@#UjVT%{Q39iA58Ths0J3s|NohoLF&Lt!8(8c18V>XAjZFc|1vT%{s#lF z^Kb%2CZ>-cJ^%y|<6Q;@;r#qR4;}z*|Nr|B$h_ab1b6QI%fu2>dIV_O?>~RRu82tM4=f|&Ke}8;oX5+eBw}y?G6)5=s|Nnnr@aNATAPEpaEN{Mj=m^OD z&%p5S|G&Tg{{H#<7bL;LEGj9<&cFmz{_j5mJbLs9Ab?m{m{|TZ{D1lB9Z2clKfnI{ z`ThHs^2c9)q;CF`l>Eoa3N#g>nv07INCE^93jWH3lKe}28-VENu!{qxMpm&svFOiawo%#4hT5U&FS z5Yzu(KY%Xz`RDh~-yl6N|NT~b@qz9A2lm1$Hf43G`D-AmnZXVNY5)izCWas1fbRMA z8?52ykLBVV-&q+tkKFpbbOC=r`2SzOfQo=l0_p*hfB*gk2q2IKpzD7Eo%H+Hk6%A8 za57|Q3rv;f;d1r)FDv_xg9F*eKs^8f#KQ37)2~0jMR){${rwHH2k3S7pO3`Z{#jf7 z{|`16Y&=9YkOT-IMh0&|hF9+yelRe6V}O#tcxPkSx96}BCoe=1&?OKCkOT-Y05IoG U$(*n^qyPW_07*qoM6N<$f?|9Y@c;k- literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ec.png b/src/Icons/flags/ec.png new file mode 100755 index 0000000000000000000000000000000000000000..0caa0b1e785295d003869330fc4e073dce07e7f6 GIT binary patch literal 500 zcmV1sCzZm}g`N!}J$oTi?|G$4gL7*^D3`7C}Kmf5Y{CmeN)&f@km*M|^ zrvE_l-~a!AA&BAspa1{=fXIJ9!9O2vbOQts3j+fX{b%^|8m0my0Yd-4N`WN9@BjaR z=no^SIM8~400P%s(0a|A0FHhM?*o#se9Q zEZ;b|7ytr@MWm#zEz$bb`!9d~{{Q>$@1MW_!07MqKOpw+zkh)g(B$8L|49h*Ov!x= z5I`*NZ%IAX?Fbu$UUAQCA3`wxix_2=I& zAouq_SzðCcuS!~%52Kai0?gF&VORsRAR2~rJG2PFT1^!)w@)C_d-AAkU2Vc75Z z*R<@y`9z1vevIh)-p7{p`5C+7f|6l;f1_&?! X)GmJPc-xs)00000NkvXXu0mjfGFPrC literal 0 HcmV?d00001 diff --git a/src/Icons/flags/eg.png b/src/Icons/flags/eg.png new file mode 100755 index 0000000000000000000000000000000000000000..8a3f7a10b5757b006948ea4436fb242d02dc9a4e GIT binary patch literal 465 zcmV;?0WSWDP)LAHVtk{r`=k{y)(2e*gi*sIRYISXlV_^=qKp{(!;n-+xj9 zUjemETFMXP0$m6sfwJP_;%#kh009JYeOg-Dy?gh5gTXH_fG|KLm<2Qhs6|CZ<>JMQ z009IFR-loRl9E6vpeV=!FaTTi8)D~Q7yv2;2q2OXK!5=N{?|@pNV(X=00000NkvXX Hu0mjfG@sA` literal 0 HcmV?d00001 diff --git a/src/Icons/flags/eh.png b/src/Icons/flags/eh.png new file mode 100755 index 0000000000000000000000000000000000000000..90a1195b47a6f12c70d06cb0bd0e4ea88d7bfb03 GIT binary patch literal 508 zcmV`hKmn*~pz%QT=MPXRKmaj;?1ifa0xhloNlE|L zuK&--1mwx?-uoV+`qwW8u#*4+i1F_GyFwg7fByafIr{%Uh)$p>Ae%w(|Nq~=m~|`# z{`_H7QhIal96$iEC^sml1*F~kc<(nb4FCQ91q_kDz!3TkBLDsd`Sky<|4qNomi`s~ z`xoeVfB<3v8uI)9A4wibp!A=AfB%5B0nwj-e?TNKsQ>@@`|oeijK3Q@{{o!^5I~F! y*$fQd7#Mzm(H|HCnf(WhfND7yc3x%x2rvM-AWsdQI)rrq0000&(jx%j7OGE_~DVuFcQkgj@33fJv($pjj zgoNxWFM>pG#K4X+%S_Ys!f>f$mib36%ekHNec$;y5njB{!+Y`YzVGwA&4mTVh%ikU z03gD2Hn&LPeNu%hDG7PUvzrphs|^(-as$IIo1LmPya%Hc0Qn*6qc4XX3oKoa+Z)_XBQk8 znPA)XelBh#6J<)fj|w>7X+~Yun^@Bp4$+N z6L8rb{%QnJN{fql*fJH1L*2YjUlB~CXS&&LY)1V3h&68|x1_5-(4l3HUgs~3JvLXI z$_D=zL{dTnq9RK`-w~w|sCYqqA;@OoAE0!{9Gi+cF%zA>5*8OAiXWs z!A~!@Tb_6WJ;mn(q~>CYJ~Oq(|Mc`miY)G1d$)?S_lf*=dz3nd-8+hwz5w#U=!7L- z+Ve0W8Werm#o=KvYxRVVNtM9!poHk%m;Y{gxKdXC|Y{ fc0^aUlspXz7vm>S7OoCUZUIwXLGJ6E%Z+~lY(hhH literal 0 HcmV?d00001 diff --git a/src/Icons/flags/es.png b/src/Icons/flags/es.png new file mode 100755 index 0000000000000000000000000000000000000000..c2de2d7111e3cb59cf6511dd2ab045e824bdb43e GIT binary patch literal 469 zcmV;`0V@89P)@|4`Xj5kLT%`al?B=W5I`&pe;NKW0^Ri&h`xRJ_x;0v zUa?=y?0^3M|NZ~}FE9c#{{3cP{Qd6}13&;Vf!z&M{pZWqKYu4MFm$tgedF}w=P#IQ z7-9gT-$11R0mKA$(qEu4%ok$*y!^wMRm*x;`R7|k6yu?K{s8?55I{^|9{?Tjhec2I zv+6&FhFWG_BbNVc|Ns94tNRJp!0`V!Py;{!F#$2enB#XZaohg-5%Tlk#oa&nzQW9g zl0Y{D4gK?n0U&@Fe=;yIr=|V7caH%YEYL84k`Tt9-wc2LGODP&y?7BIfLMT@X8Qey zK~fSFpuiXa$^kk7RCwBA zWQbH``0|MX0{;DB`1Ob3-!Fz=zZw28fY1*HhF@R=VQ?@21P}|ur+3w` z_wT=dfByab`{x&s{PXYspTB>919^Y{{Qd`I{N9v10U&@_7=ExZ{APUe{`KE~Al1MB z{rb!Jhml3<_uqeCzux)%bv7|NkFAvw@aK@N+YWG5`bsF#yj00sZ{|0ReUZ0OJ4u`~d&_lgxzd z_7grGtKje;)ax=32IqJ>VE_O6|Nr{|0Uz@6!2*a0?AgCSJ_s@V{`!jztXlEUzkg2h zOW%AK0ILQg2A~)NKmdU>0L=y=29PKt(~s@sMWK)O87MU|4G0ImPt*+y7s`{{I1L_{;G9FVHyv z0R+;(^!pEkq$JpwzYKqVGyVRp{reTr#sB4{{{Q&{G@Ah!GGGK$3=lw!Ux87Egcwk{ eXi`7`5MTfy3O%OUuKb?>0000FP2AE)Ir2{}>qlLBSs|`Qg(SfB<4)VqlOE;Q=cD|Nnn$ zna02W|Nj1E&`=Tpav_4q;M$#E00G4E4{SI@`q`VGKvVzz{r4XmU}R+c_2(Zz0I~c7 zs`v*r?Dty(;z&PFFXX zRA5t=4x{1SIibD)Vqy6A2V^D4P_SySA|L?j2ip1XFA)9%V~_%1r~w2J3=}{2Oiu1 f7(RXZ0uW#T>&I!FfdIJb00000NkvXXu0mjfj-u42 literal 0 HcmV?d00001 diff --git a/src/Icons/flags/fj.png b/src/Icons/flags/fj.png new file mode 100755 index 0000000000000000000000000000000000000000..cee998892eb316c3293ef2d52afec9218bdbbc03 GIT binary patch literal 610 zcmV-o0-gPdP)2C05Lr?a%1G+Sb3M_ z-f!*)-&mJ@lxC7weD@!u;s2li|9<}wjr{Zf&o8mqKR`Cn4*&rGF#yj01QaSLwCD}R z0w(ww8v*|PzTN}jB`Pj8{QK|!{{8;|gOCLd|L9jy6{oELG6Dcq@B)aDq496GGsCmb z5T7wXTnzN$?|=Wl{r{i6vr6{G)xV#={AXc)t!L+QBoiQjSb+Zc`=1dU2n>I~p8E|B z6OfY_{`1$ji1Pn`9_T5yZrhJfj0}g~00a;V(9A!7nZZWFG{8az7^c++|9dI@cmDl* z!Nvb)UorrL86bdIfbsI1fk}{;;V;BV|AE?oY(}v2K-{x07*6Kx`SfB<4-V2A|A=r2_C101z~ iU~vp#0R6xN5MThlzdwv9U#bcK0000}CO1*!he@c;k+ zfB*mg{rg{#hxPwIh8G{d0|o#7{Raep|AEAFCm#U_AQp((@4x;AD*Xo({rB(3@4q1y z(m>63@(hzyJPYWMEi%>@iRTXyxzU zAo>qT2S^W413&<={Q1WKlmMyz`(Hzv@8AD_R~~+N^7b200Z@m&0zc4{Q@7rNwftxJ z^$Q??fEu9g1Db8CAq;fMkDq@pJa`8*&sI~^TtyHla^%`8uswf)HUI<=3()%@Pl0^! zf8Ui?K|l%XeRX{Qd(n@juAHz(D*15I`UefB!>$cK-hRUqIf!|Kj}Y zKt+#Ue>r^ZHOMRf{y`i940V72V*2%m0pg)Q5O4ka4>U8*PAAEH2(%ZZ;ol#C0AiF(UW*)& q3=s4Oj6m#vP&UxAe?ZIt5MTgFMVEBke8_SD0000BE0lK=nzFYgc)d0A2*B+AFf z2joHok-@WP&j1351!6Wt`q9fjf1W;g`1ALFY=DuG5oiNI0I|ST{|2JJ|Ni~?`|A$_ zRt*pr0t5gt0M7pe4IJopi4@}M{rvp?{Qds``}+I+|3-D|`uqR;{Qmm<|NHy?`uqO- z{Qn;q1i_Qs0*LV@1A}N|@t-FT{{IC^{`vn0sPGp^)o&2vABgb_!eEtCyu9%!Kmf6* zGhfda5_|CT&#%8A#S0%rhKer*8VNG{57cZ3sU*g7is3Rq0I|G(Bf-nd3vr@r@vHy8 ze*OIQ@9-oMOb-A(eJ@7=Ab?mP;SCW2x*O<#U%#>Y7zqCS`2!F@APw*!ml9!S{vjhP z$_zA&0R;fLP(1(v#Q5^%OL#2G%0Af7VC%@R_vTF*lgG%);U`26kn-@hOg zU%!6+4+cOs(0HIde9xZz`}Onxub&LUB0x(30+2WcIRJn#2ut|?gWYu1Cf+!-K%B8# zdf?1WA}#uZ8oj7u>$I1i0Al&`=O0k%-@icgAIJnM0xA6maSq6BK-ECw|NZ*S`0Lj% z1_pot6puj;05Ax`F!=umqj7^frO?t|3^&I1kxUq9yECc+jQpY84SWH_0#pxl$?v~F z@*hy-KN0|X07U)z`4{NpU%#2aHUI<=%a31wK(7Du52Oc(|3O^?R1IN+RRjI-n*kVB z3=9AP#PZ|EACPLGJ%9cJNh|>9B%spYzZw7h1%?tp0I_@ndg9MNE>313@6R75NcceF zkr51-#U+7;F#`Sf7i0rK0I_`g_NQ&Zk)EZ(2O=d>QH$KN3zEi7S9u{+2K>GX4ds`2QcM z=+A$K-~a!^(JwH9Fn%*K{{Cdb01!YdV9)*qi~a#?`wdg{8%Z^Y!NB>w;@|&31~6!UgVU(k2*|8J(R-+sudaynhucHbwAMTnor{mwqO^w7JHzaBsT z{O^B8RYf5+LvDs&KmRKVd78=o{`1#HTiEo_OolaGleS)G+IQ#sUI`b*pv<`1zCJ=H0jd{{2S>p`ri%{LsXJ%FbMS z$#S`6f|?OG!^Jxczkf6Q`UNF{l0Sd`ad7zm>({^EzyAS6{{CgrkluOb3l1A>ZU2~A zK+FZ=zkmP!`TOVhpFbzBzFaPmD2$N3;+$pK?>zdet`f0002ovPDHLkV1gy;I?Vt8 literal 0 HcmV?d00001 diff --git a/src/Icons/flags/gd.png b/src/Icons/flags/gd.png new file mode 100755 index 0000000000000000000000000000000000000000..9ab57f5489bb9ebb6450cb27f4efe0cfb466144e GIT binary patch literal 637 zcmV-@0)qXCP)@|2i2MUNJEAGBA`g{QJZ3ub1IpEW7h{~Z4K zJ3#Qa=Q1XS-;5h0el2+U>(Te$zyAID&HDTIKad810Ad2W{jW5`@9y)AKr^5J{4Kqa z;cw*UKQW)B)-pW&@%z{RUqB7N{{H&&_Ycr?fB*vd;rG8kGw%JlqX`uK!_D~nn&&T_ z*-Q+-7;nUX=6mt$`7e;3-;BTi{QC{m01!YRC;j>JdmqEEKMa4Icz%Tm{+4F_^}h({ z_1{sye%WyRp84|E^4Gur0Kxx1e;6150*D2Oe>41%=Kmef^V^IA7&yOx!2%AYU;o*D z%dq`!;`!w)_PhDb-(PS30!;@9Adn3rpZ_$9NHVegX88Y?;V;N+#{WPzFy?-P;*ar< zJ?CFrnZE^h{{CWM00h;Fvzl@K2fHp9I6dqaaxb00=Mu XLcuQ~?TP?t00000NkvXXu0mjf`7udf literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ge.png b/src/Icons/flags/ge.png new file mode 100755 index 0000000000000000000000000000000000000000..728d97078df1d07241ae605dff2f2cac463be72e GIT binary patch literal 594 zcmV-Y0^8x|9^h-OG^F+g7@$L?BC01YQ`Wbb?43;K=s|G$6#bNnb!1Cx>Qe>QfY2m>?Izi&U8 z1o&Rm*8l_%%a6%3nS?}u4*37)&;Q?l7=Q-<`}?1Z>;KQLY|KmGQ@ZWEch0Jnt zUmm{%2p|@g=ujpTGX@n^21dqzKYxO4`1a@2NuYivJ4XgKw*UYBFf%g!{qd7YP>5~& zE`R_4F#yj00OjT7{QUg;`}^~|xBB|}`T6Q!vcs262Lz;t$n|1+qbnVARhhy8{z5C(*C%JTg?tEV3%;s64O@&5h$(1-*>2%Ak`A87BFlP7^( gh&l)WvH=1N0MfQja}g1cO8@`>07*qoM6N<$g4hNuZ2$lO literal 0 HcmV?d00001 diff --git a/src/Icons/flags/gf.png b/src/Icons/flags/gf.png new file mode 100755 index 0000000000000000000000000000000000000000..8332c4ec23c853944c29b02d7b32a88033f48a71 GIT binary patch literal 545 zcmV++0^a?JP)lgG%);U`26kn-@hOg zU%!6+4+cOs(0HIde9xZz`}Onxub&LUB0x(30+2WcIRJn#2ut|?gWYu1Cf+!-K%B8# zdf?1WA}#uZ8oj7u>$I1i0Al&`=O0k%-@icgAIJnM0xA6maSq6BK-ECw|NZ*S`0Lj% z1_pot6puj;05Ax`F!=umqj7^frO?t|3^&I1kxUq9yECc+jQpY84SWH_0#pxl$?v~F z@*hy-KN0|X07U)z`4{NpU%#2aHUI<=%a31wK(7Du52Oc(|3O^?R1IN+RRjI-n*kVB z3=9AP#PZ|EACPLGJ%9cJNh|>9B%spYzZw7h1%?tp0I_@ndg9MNE>313@6R75NcceF zkr51-#U+7;F#`Sf7i0rK0I_`g_NQ&ZRCwBA z{Lg>@|4`Xj5kLT%`al?B=W5I`(ov;U*021*0XgD3^5{teN< z@cTDV13&-@;@|`T5QYI@3O)ok?1DO<2trehc#kXh!0Z4iC6of!=I9L4Jz5Qk(jP`l zJOKo8(qFLXAF#IH8`u5XwDI@PAHNy@|4L4RsD^0x1N0+605O4m05bkR14QCiMDQ;; z>0h$aKjWi;+@CNFzZm}i25JBZAQt8_hOB_!_dovn^Y72^zrTL{{r&6TuiuWpfB*e$ zwD}j1{Ph<^0%eu?|D0`P00`k|9}4iHT+`$2p~p=WCoxfpgkZGj{YEt g{DC2GLI4Ob02tU}a;hkw5&!@I07*qoM6N<$g4!w08~^|S literal 0 HcmV?d00001 diff --git a/src/Icons/flags/gi.png b/src/Icons/flags/gi.png new file mode 100755 index 0000000000000000000000000000000000000000..e76797f62fedcbfca8c83c51951680d6a6e9081f GIT binary patch literal 463 zcmV;=0WkiFP)VoB37QQ+R{;bN6GSUi z+kb{HA3p-oUOth}-@kwP{0U71P%%INK{Y@H82)oDp3V0Dt?T`39Pi$;RTl%zL?{P4 z2_S%&kW~Z0x6qjPzkeV9`s>}VU!Q7P|1&Wm)PrpR2q2b!5Hle5FfeebsWZ)5spT9vc*+3O2}Iw&|Nr{sqx*C2&8&?7c>c4n{QvVC zD9-TjFQbI?+i42`0*K|`>)%Y*uQL4o{r~rGhChE9{`~$Pz`@Ka$@uLpb; literal 0 HcmV?d00001 diff --git a/src/Icons/flags/gl.png b/src/Icons/flags/gl.png new file mode 100755 index 0000000000000000000000000000000000000000..ef12a73bf9628ff5a67b81bd980d9c5d2b2c0f05 GIT binary patch literal 470 zcmV;{0V)28P)J{teTOL@z0+>00G1VRSiT77W_YWkm2*^|KGm- zfAHXcOY8ruSJ7+$Itd_vn4oTd_U!+mLkz$F{Qvdq|L@-*^6S_C%a&nk00990)`(*=-xesBS%qG0|gf?f~#iu^9N|j9|i`10Ac}ZUz>% literal 0 HcmV?d00001 diff --git a/src/Icons/flags/gm.png b/src/Icons/flags/gm.png new file mode 100755 index 0000000000000000000000000000000000000000..0720b667aff506d7892c5c301af04e6bbf932751 GIT binary patch literal 493 zcmVwRhhvIeu00_fCKU~B)yH$s9sXS^B!W{?M(W&}hPbMwO z;*cg65E@7haJ!!XVgYOW|Le(9kkY?@fpY);{sqc`6amR!K*q2CzkUI^Y_hUI(*XjA zMdSH%VNp?r|Ns620Z1T|}fB<6Q zlw#oF`Oo_sVk+2%KTsoq3?TP6gz@)3Ki_`_=6?VI#CZSdeQ9y&f57m8xf%uh13`xW zAjrhTbmsgSfB<4-$Y)3kNW1sx-tWJ^f#}!YUqA$5fJva>FJQR-`S({vK;>fVMSuWe z0mcW=Ig;FxKxv@ppTFP`1*!N0BL9M&0|dYz`1hCL7Xv^5F*2kxF#KQuvOqEU3km&! jiTr^fV1zR<00bBS-TrJ5MX@2w00000NkvXXu0mjfGz`_@ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/gn.png b/src/Icons/flags/gn.png new file mode 100755 index 0000000000000000000000000000000000000000..ea660b01faefde01ad2527a6abcf7d1a5c1b0526 GIT binary patch literal 480 zcmV<60U!Q}P)@|A6>41A`El{SSoRd}EL3@|NdrR`1}9=ZwUJP z@AvHwzkdDu1yn7|BMY<#Ab?oFX8(t({tZ$6>;L~hU=2XVuU~(E|N0Bk07O6y00G1T zbT=bV^`Afg|NLS2{ReI~M8m&-NE-fuGynt;*hzmtW+Q3%1=j#1fvO=I{`~y|)Bq4b zU?=?r84r{KY4``%041R|`~%zYhXEjfz)k`h|LYgXRlk0r+3@c_)IERx{rUUv4^RU@ z0D&|xgN*;p0Mzyy>QQ8EKn=iP{qyfH5CNS85I`UeOuzpyNJ@hA{P_#yFfjaPWc&?| zr{By>f0X$D{QV0G@4r9|{}=!Qi18~pg5ikaD#Jf9Xfy-Svu_Nh0nj)GNi#731Q-A_ W8E1tdJ(&;y0000P)fLk0D%}*I7ff3uKv?i+N*~ULWZ>4 zW5%k%a3T{@*`z6pma6eF$JtK+F@C*&o=d^t|Ns9GOCXH@*Z?CVuP#7nB5Y|1kmu|NQ^=?>FP0zrYX%2q2aZH;)P`n*#-K1r9WbfYOYN z??RUX1P~*`M}`*mir*mb{sxCVG>rbhqT(MY2L1y54rHu+wi6(L7#SX-$0bVa{(;3h egu%oB5MTiLH(5{VMZMqv0000u-`~Ig{`~p> z=MRwl_xtx>F!}G#@4vq{&D;bKKrBFA+{}CzK0Nsg1pog2{{I_D14*DX1pWH^3y6RW zSzcL&Zwvqd#Pa7K10w^wlkmIISh(4kI3GTJhN2$mzJLD! z0*D0|DC|s(0(}1j8UFtJ4HA_S5@P=M@9)2VV#30}-~k05FvNkXnV5ck`2-L^EDTKl zn1259n3DG7^QXUm{{H**3#f!E|`n6Mz6>fhdBj29g(UfB*aM-=Dw#|NaG$fByXc1LXhxFC@THKjjKQ05P&# zA9gbr+SsEBRPB^?1!&T?30hEBFhHFGv5AR^>DH}B00G4E=NHV45I6k$@0N4rAH*g9 z{zDN+_&*OP%Y{RC0Ro8e#fvv0A_7PTA~XKMG0?q08}8kE2oOLl>koag&}IJi^WT4% zN&g{c!yE%t3}J9_Fdy0V1t5S}4xV|TB*XjR%dfvcU;YDm6wdeu;Q~GU4JP)J`S$qz^!f=A3G?{>83*rF;63vB|NHv-`~3j>`uzF%_#GV;x3_Tu z05Jg0{{&$2KZ#9J4f5RdzRdzC6Ae5p=(o+T{uB7y^ZNSwN=h$cVmJ#62-nx+ob%l!TKAE1V~I16T$|E1+i#l`u&y!03t z7ytqQF#yj01Tv_Ick58z;rzG}_y7F-%)*RRAv1X@1^f8;`}+eA4+yBm#PKA>w6y_L zQ&a!|00ICp0M7peY0>I$KneW(?7rp&{QCm?`vUdU)NRiG`uYI-`}gbY@;Dai8vP{| z4h7uY=>Px#0*Hx$0pxvffc*LW3+PFp{}_J#0ty11^n2!vLjod>mX_Jy|Cz2{eHy3% zAb?mH7=HZ$2N_TWSP@V&gaITO7A`uvc=2f<_uIFxDk_pd4FCZI)bI_+mz3lOl7E0f z{^u`PGlT&Y`3GeD{rm6lUtS;y)Bq4bz=+dkVE6#Ehk@Y-82x6z3jhKP0OI&0DF;s+ Q-T(jq07*qoM6N<$f)`^cRsaA1 literal 0 HcmV?d00001 diff --git a/src/Icons/flags/gt.png b/src/Icons/flags/gt.png new file mode 100755 index 0000000000000000000000000000000000000000..c43a70d36424b66f1627216ad988cd23a4be9285 GIT binary patch literal 493 zcmV|9}7f|M~m>&%ghRD!%{(5DNnfNcHoNKp}=7 ze;EG#|IZ9j4hBF)cVB@t{Qmo2T96TF4?qC109^ty;2+Qi2B0xObN{1)Uw^{8{`KJ4gZ0H zP(J{D2s9NSfWR7{27t^!x8NVhN&g{E`Ueb#e*ggla?+pwj3Cv27=VUhwE^V&zaVoN z82$hR5DUYve}Dck14V%vK+Z)23?LgAK*7ZT@-zbjKmf4-BkT7+CNVw+pd~+kF)%WM zL>VCz0|PT7gS-eZm>Gd?16jcE4PH%g~!@=<9&!2x_@aEGW jS9>vVD)6R*AQp(xFW-Wt{{mJ2|NHk};Jc-)O#kPzME?5A`1{ZQ-#|To{!0im{$XGM z2p}eq*?*y`{{RjC%V7Pj<(}hvo^Z>=hrJ-xK=d0#0&M^~2_S%&fR6tAp8=>2$p8C? z0q7F5H=q9h`}OesIT^OczkdG%sRkpU6i@>|0I@Lq1-k@j0La}yZU2}V|JX_T{{Q!% z>EEtDfBydd!vuBJUq+w?fB<6o2X+#W53~WS;s2M<|9d72Yseq)`11cZJHs!aS-+wF z1}X*!ASNLG{ST%Ze}QTk7ytqY@{}>p)on&BOV)*xm;om>72$%sP!HhqD7ytr@1teTu4J7{m`^Wh2AGglm{~UiA z82u;s5_9PZ|FH1)~3de={)r1*?FgUtsi`kx>?C4?qC1 zfX)8@|LZe*d2K>lZN0{{I4*^b@QIr~;(tA5`a`e}Ddhy$ldQAPvkwr9kh3`~WiS7Zcc2 zh-#qDKOj^7{QC<;3||-k0tlpm>GvN7NlB2NKYyjTe{-?^h8PLd@aHekus?tQg2Ee! zfN=^CK#X6(5e!Gd)(i|h;JEn(j5jcXFhHq*fkB7?Aiw}&uW^ngBcx#f0000J&k9ol;AaCAG*Vvs6lsG2f+AJUecp&K4&zS7@MzJZZ+RCHJO2~-cn~)8*ZB# z%#~(Seaqctb3On>xdArM!+zLfe2=iS%3k1HK82I)yo62#|&;D2*%o~N(LQ$HrxFU=@<#wgQDty7s|5?>qxBTrc>UoBZ!}1le z#)a`Pq~$aEPO=D0fO80I7h5SSMqU=q48*j9Qb*%7#+Pi|ervSf?0bSFwKsAPn1FO| zKH_&kh#AJmvOUSnl~!1AmcaNJM5awz`0DF46>zWZuCh$z(7uBp0to4w2iu-uj zV9oc#M;CkJ!OT_8;~(;r&Cw`0K3r=(%@VWyiIA#;S}+n)^}q>|)QZ|IaYyyY!;frq z6mATysX~aM!z!n$rJ$=27fpoIr3iB{q|Gr32uDRa3PcNj==OQGHve|07^1DbtUgzuEQ=j%rDF literal 0 HcmV?d00001 diff --git a/src/Icons/flags/hk.png b/src/Icons/flags/hk.png new file mode 100755 index 0000000000000000000000000000000000000000..d5c380ca9d84d30674f05b95c2f645b500626c07 GIT binary patch literal 527 zcmV+q0`UEbP)00;JD`K-EmLvOuK( z0R&e6?>|)a-@i;iz|8zVIqAQ;I)|_@BNM~FU%wy-s0ZjAfB<3vx(uZH&mV?Ae;64V zIcsYEzkmP#{)7J;N}0Ju0muUq%~ z^Jl0Zz)k`PASO^y0(FCg{s2v4J zf4+RlSW)rg;lp2_Kl2?q^5yYkpazCNzyJOD%k=jzP%%INf#Tuc?>~%^l1w0DfWH6z z1E^V4lvz;l%d1x`a&jQQ{ROE8h7C|LKmaj5WMKG(8n4KVKd5of#=rm&U;y%qJ?5>3 RVzdAN002ovPDHLkV1mTk^F06n literal 0 HcmV?d00001 diff --git a/src/Icons/flags/hm.png b/src/Icons/flags/hm.png new file mode 100755 index 0000000000000000000000000000000000000000..a01389a745d51e16b01a9dc0a707572564a17625 GIT binary patch literal 673 zcmV;S0$%-zP)>fJ3En$GhGS>sbE%%m3$AD)q?8M9y>88-}kR7#RKlk!P~Y_PLuF7~U~3`~nC7 zF#yj00ZUDdpLsm{7ajP|&HwoK0Usg|6%f4L_{`Mi{rvv-`ukf=Ed&Gs-sA7L!Q7*a zj{*QO0M7pb%?Sw^g@yy{>ihEY{`vU@3=8@G0rvO$i3mOL`~mv-`W+b$Mmr&io5dg< z5v!7q0*L95jt`TzK8Kd(Utv)OSp_aLv){6ccV+Z`{Q2+asKUU&aO3`Kpz6wW8wp`< z28M3{0mSqnB#A*-c*8%1=RD#sSOwMznKA3=e&iEzwo{cA=PgXK`2OQ}gqId83!|%* zA_Kz@fB*n70M7pdECCwp4H&@R`1|(w-}M5x*74i)0}%fAt;XafA{48))#>Z>?CD#}*e}Ret0tl$#*RMZ7}Jl7Z|M45`5*URzH9L z{rmSnPy;{!u>dsyO%meg+00000NkvXX Hu0mjfN{&}S literal 0 HcmV?d00001 diff --git a/src/Icons/flags/hn.png b/src/Icons/flags/hn.png new file mode 100755 index 0000000000000000000000000000000000000000..96f838859fd2aed975f5f4134050fdbc0486ce1e GIT binary patch literal 537 zcmV+!0_OdRP)yNpn^YtfB*U? zE6K^g@B<)#SlTBTcsfda`|@_0R#{e$UZ3l|Ic6l=B#}T zWCl5lg}RFY8S^$g{qgfJOdc2ve*glAv3c@IFK6|y-~NDH^$#cn3{a5k!L9^_5>O@B z$^W^zSlTD;0tg^R28Q0WdbfK|zW)9V43odV{`~*->+kR1AO=tbO#T4}-G3E1?u#4x z0Ro5x7#++k42m+GppXWk{}2W^;6Y*k7i(1vOT1`b$6{=&w9#5#oJ b00=Mu*}Zhb7k&Za00000NkvXXu0mjfKokPk literal 0 HcmV?d00001 diff --git a/src/Icons/flags/hr.png b/src/Icons/flags/hr.png new file mode 100755 index 0000000000000000000000000000000000000000..696b515460ddb670acb7e9de4438aaf21fc5fb77 GIT binary patch literal 524 zcmV+n0`vWeP)@|4`Xj5kLU3fF!G{fyDoR{}_Q36Vv~H|Ns5{^Z)NZrr*Dqe*gae=g)r_`DNuw zfB*t(VEF(4$y0{Ee}M=nS{mB(NB;kxJOBSE{F_{n`2Y8>|G$0##TjK~fi?gH5EIz! z|8Uj6|NiY-l-<0|OxA@1MWlzkmOI;leLR z$De1;{4g{7^y$;LZ{NOt{rct07a;lk`E!5(f@%OM1_PkhC8`eE9egqWbga z&p;hdpFRZ$Adm)#>fe8W4*Ct02B|hR1*-n0rS<;(dx&bFRY1n$$BzL5h>;=uaC^Mc z(+@v?|NZ~x@4w%F|9yUZW7+yTpo@LH>e(bUfFghX{rmIxzpNnpimU?w0mQ=a>kp9s z8>AGffmuv7DrFgv!3yU7{`2q8f1ngFoPlxn4AoS-S!;e2821p2q{((sbfB+=MK@k8U5Cg$|VB~~? z2XKWZk_lAZtGhi{|56nPieMKY$Bq=4KgZ0muK;2JYWn}5;nka8K-GUCa!{rJenZIL z|9<}gF~mh#ftCOS5DU<%|Ns8~1)2?0{RgZLWF&|Ls)lL+iU2hL1Q5&LKMX(>AUTM^ zNU9+S#0FXN@8@rz^Zx+^5DWL07wmsTIe-5EX@IBzTJ`52%kO`z5F362$-h7b*KaNc zh6exv#P}EJiR%3Sk01R1^NZmZ(C**=fB*Xb3rzn04HN{CU^bJS()(Sf00M~R4FdxY z(0f3MKYtkh0!g5OAQFsz{e$TF`x|H}%fCO*7#IKo2o$W~FaxWA8VofRr202h8w1#j zz=!|{Ah3qte;CCj89_$={rBfLBSbS$5J>(7`GW}-*g)q41Q6q6a2)=FMdm+9l%onl dL?8elzyJ+{hsuy4pm6{I002ovPDHLkV1hP90PyYjz{{0J*12TXlP$`i71!VmC|LYf!%PK1iv=Z0I@Lq zVgLrRB#$I8Q2qeT`3KSlX8!?(3s3+U9e@9T1Mx3N13&;VGFUSJ^?=Y13Wr{r~&-|6d^ahvDC! z|G)qK`}^nrA0Ybu|2K$nd)6X=0AgWa1{?O`IRi-PU$8V7{r&w9sOb0ae<0Pr|Nr{M zEF}%J0U&@_82&N|Y=e#y>zg27mx!0Xgp5*S}vr z{r~fq0csvl>92pk!P<5VDfB!NI2#TFQ3lKnzfB%Al=06ZHfFW+c#KiRe{d<4_V)^&)A0s0pNIe5S)eu>r zF8~6F38(?TQZ#J<0R*xEXct5e0}KG|WIzExE=U%r7$AT^8h-rv@ecwRzz_$3Xaxu` Y0RLik?wUgPu>b%707*qoM6N<$f;0ZTz5oCK literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ie.png b/src/Icons/flags/ie.png new file mode 100755 index 0000000000000000000000000000000000000000..26baa31e182ddd14106e67de1ac092a7da8e4899 GIT binary patch literal 481 zcmV<70UrK|P)1Ab?mHSU}=WzCQi??=KL1`SXRBmG?g! zeExSVgb4YXfjasA0Ybs`#&c5^XvcLUqDM3{{9AP00d^^H2e48-+%sM)d02u=%hct8G!N( z3;+QH((o5-_OE}xfO;@2_y=+i*h!3FCjkTyNW*WSt$#tPfB*dj3@CIxKqoQ$2DuvO z1O^6x00KJ+r1UogVe!Ksu!etsL5P6?Ab?navG)7lA4zUWkT?GPWdcP410y3N0|YR! zFo-FE!v&-P=p=vuVq_>~VE6=zV^DnmVAx)=U5ZNz6vaS)0m(NHWW2-wfs+9Q00bBS XO2cxg3=*#z00000NkvXXu0mjf|9Z^l literal 0 HcmV?d00001 diff --git a/src/Icons/flags/il.png b/src/Icons/flags/il.png new file mode 100755 index 0000000000000000000000000000000000000000..2ca772d0b79b255872cde2fb29060bbbbad950f2 GIT binary patch literal 431 zcmV;g0Z{&lP)WlqUuh`uiUU82D1+EBLb>EWz|Nj3k zj6%@>aVJ0ku|Ql5RsEk~{?`9D9{=ZO{V&1vKX2lHHJSgJ0SFC1p8y096I?Y|?05b{XcgblKTHZ zfByjpAQrd=h&?HOAa>`R|6Hv9XB30N3RxDY7$AV4en1PH(j<7uAT&Tc4G=&q@-F{c z8i9e$01Rv(35=ybe;NM%WdxES!M~uG0dj%y@b5pvikg1_0mOLw_HE>d#AF}?ph|!M Z0{|%qc@l5wel7q2002ovPDHLkV1m6PxaI%= literal 0 HcmV?d00001 diff --git a/src/Icons/flags/in.png b/src/Icons/flags/in.png new file mode 100755 index 0000000000000000000000000000000000000000..e4d7e81a98d705da8d7054e77e7d311805659678 GIT binary patch literal 503 zcmVl^KlW*80IEmzVa(K3*_6 zG7fg0I9Zj&0woGah`r_&Kwu3FK=xChQigwjfh>?7kc!_h@)sEWW@MKI+5iwhEdRtz z89B8WSj7JS|MwrL=l|b3uZ7Osk^B4auaUxSRgtG4v;Y11_x}$gi|9Y8?EnG9`1|i) zCPv2p|ADsrhuF4k`@Nr^zUpfTpS$xp!A}Wj4A3Yb2~_s}<0pUsVqyY2p8>1`g1&zJ zsVvR4Yya)fUw{4wtNss>0tLxGfB<5GmnRH!zxweH8<(Mq0N7e&^ba6_ z7#WHgIs!VLeti1p-=9B!fB*jb=l8$ge}LrQ-#`%%`S%Y9{re-sFSERHIY0ohF#KVF z2*K4Ml>Ykz*ZJq)UtlmW{9*tIAQm77@e!0?Mfa}mS!7%=x2KmY(S z0M7pbTSu9imq`K?75n7n_u%3MB_szB3#hl|A07@E6$<6-<>30S5egmg@cSkZL+Ix9 z0st`p&i@3O7{&wE8wU3C1oia^`T7CwI=ckcau@Q71iA1L?!*;{7^Nm*&$?GLJd|NjPb3=0E0KfCb4 z#nAu(05Jg0{{-+tQ26`)!^rI-{P_e371QGlF%9qW_x;Sb;QRdk{r*xJJ*zy?_rWgu z&$=$1lYjzR(%pFe+p|Ni$IOoG{eTR0XemVUia$~;LXXZeDO z0096o0M7peXKyl1N+90g@dyY5ARP|N&gc{s2^<#+#>?j*9u48*^A9U5-*(6(kqBPq zC^|QM0*Gbi#3NFYyicBf1{wyk;Wx-spzFb0kX0fvuWZ`CzyHEKd)}3G%ew&r05Jg0 z{{dZPvvzMc=Kqyj=IHYZ2nGGUe(f)J7ZwZK+v5TV s=!a5B6v9X#`iH^&14cjw13-WQ0BQ>oQ(TIK+W-In07*qoM6N<$f`&OQ@|4`Xj5kLT%`al?B=W5P+gNxB&nJfgpGfTOih;e`=>T z5jZ8;?_>v5xi(~iU^udv!6f5$jpNVh2O?$m1OPDr&i?@Y{r&#_{`vm=wBfh>{Qda+ z{Pz3$!R5rm=Ee2+`0e-d?)LGV)1LD5^!4@i=jZ1F2;wA$U5|F$_;B;f&rf1p(qbG! zCte(9VPa-y5lGpbZn4ZFhzcT9$vfdqmuG z@j$ZG>u9())mkwqmYHSd7eFi*FJ3%$?AX0~_kM%HFED^GKqQ#;=g)7T_f%9=fX)F3 zAdr)QMoCIaf{X{6{|BNG$o>N%f#5F;02KoS5XlH2zyJ$0KZ{``H1_}i002ovPDHLk FV1nFR>VE(L literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ir.png b/src/Icons/flags/ir.png new file mode 100755 index 0000000000000000000000000000000000000000..c5fd136aee534ecb59914e336cad18d18ead2a4a GIT binary patch literal 512 zcmV+b0{{JqP)r;gUH{1e{Y(x2_S%2fSMQ?7@vH7`tSc=xS~J*|Ni>>`_JFszyAFKs{8d9NdA)L zm1AIH00;mv0M7pew_3Ln1`-ek5ajjb8VVZW^Whu|9pCfc910uY_2L}~8{YEX9t$4Z z@!Kj9D)d(L0*LYN-@lBEj6f&-|Nox>4F7-s`Ty{t|Ns8~x3>Pz!S){pfXY67`UDU_ zOc38f#US*GW&hv2{?Eqpf6;>f$N=n5fB<4bR}BO)G5?=F{eR-b|HMQT_5c3^H2?$< zb1geNgNn-kGiMln{`!CM;{TsNL8PAke-;*?JV+Z*eYOvhv$==KunT1sF?AKYlWZiGf7_{AKv_o8k9wMiBcC z1B3*kzkfmK*Ds)AfB<6r3XWMgVnF4hNdW;sfB^vU;z%SnI0)(h00004s{hykP}!$Xp8x`g@iqg4NJaUd z$B+Mm%>4cD_iu*Zzrl=O|9^qF|9<`Y547mdFIIVlOMCYL1Q5sui18rvfj0Ph3vJwt z)dnUeruXmP0|XEYv&@95W{1bGfWG{@sKWZ+FOVO6s`df7U=M&0& zKrFzJ{`2=AL>j0Rra@ocD)4hB}-f* zN`mv#O3D+9QW+dm@{>{(JaZG%Q-e|yQz{EjrrIztFq(O~IEGZ*N=lh=;=qSyMwWku z27eMOW_|f0uQeek^e_9g7KH|eq{JVG0^UaP2Jy4}|L^JL_3uCblfVD@mnS9t`~UCn z|MT(+KT|KOfz%~1cG~~^_2vEk{SFNQ?Cjg~|NsBWy<%2im{vp^YdeS=hk-Cyo6U`Hgs{l4FR(w#{P`G0;a3G2@YSmzI~fu(ZE1> L{an^LB{Ts58L6#6 literal 0 HcmV?d00001 diff --git a/src/Icons/flags/jm.png b/src/Icons/flags/jm.png new file mode 100755 index 0000000000000000000000000000000000000000..7be119e03d203695325568174b72522124bb2f12 GIT binary patch literal 637 zcmV-@0)qXCP){QLU}0{l%6`#}@@_VD{9F|q;xF#yj01gpgWJ+A*m zGUYZW{T>4SpXmF{^Zon(`}_X;`}_MY3j1pm`Wy}V&B*(tydCWT00ICp0M7pd0000m zGd#J&@cQ@tG$8vu6a54J`qTCN{{H)06Z&u*`VIU0o2UAMn)~_v4c^|~0*D2u;qTwS zKYspMz5CDEtAAp>e+Mf5)@1$t_wR2Fu3uNK{_0!&`}CDxK-+|V{{|`s2p}dP{`2SW zZ!oxe=XdSY-}fK=Qse!l!T0O_!(X}WAk`4?=MOLh7ytr@32Xz9{pZ*3U(#Z~DiVIl zOa8j^;n%JAKjo!$j^Xni)Y$z6WB&k?3JlvV7}WR}00ImE Xyv9Bjb9W)}00000NkvXXu0mjf@Xt#6 literal 0 HcmV?d00001 diff --git a/src/Icons/flags/jo.png b/src/Icons/flags/jo.png new file mode 100755 index 0000000000000000000000000000000000000000..11bd4972b6d5f134045d4e8ce134601ea9b5654f GIT binary patch literal 473 zcmV;~0Ve*5P)M00|Ni~>`!`VeZ#eh`f&K#;fdS|pfB*tJ>FU-06DIsWc#z@uumAs9{`&>~&q~MQB#;&cfB*tH z31sk|Jq+K!KjiuK-^&B5YLK~LCjkTy3s3{|pFco7yH$Tr@L>D>cm1y|D}MvS>F@7f ze}Db{_vg<)5c|)+zsmedM_Y~p1Q1BWd$vDo!X?isvq}Pk|KA^w>VH5L!1(y{_x~TD z9$-NK{r~sxzrPHB7ytr@v6F$JJdlAwh=Ji34E;f3{DCq4fk_4ifB*vkxQ1J~H9>i| P00000NkvXXu0mjf0T$ba literal 0 HcmV?d00001 diff --git a/src/Icons/flags/jp.png b/src/Icons/flags/jp.png new file mode 100755 index 0000000000000000000000000000000000000000..325fbad3ffd3075a4a84d8d898ad26ef7d3e0d56 GIT binary patch literal 420 zcmV;V0bBlwP)9whYk?f=!Q|Ns8||JN@lTD;`{R1ZWk|EGa3dAO8ObDh3E3Cb;oH_5X#1 z|NHy@|M?558b}5Q|Cf`4hZv9q2p|@?lb|{i68>{>{ol0lx`{mi O0000=G`P)0NEt6k^VGA)9E1hT9ocRoN>wSfaWv)?-raRm?)Slj<6Po6w} z{P+i;{`~nD6~!ec29@~tkBNo($fnHz0mS%{fq}QS{_m4#|Ns2?|K~SQUHy-* z`HU>AfB)8feAoK(-@hL}|Nr_0bQ_Dj+^xMk00K}f2RQ&hFc1JYLgN3=lsJ)M+p3uR zWC5ydAM*!ly4H1hsiEFvIU^1)HH_GYz!QMsIYt5i1c4ZMLC4DfztdU-q)WGxxg;|L zi3%uAJ2fm~N8&I2%AdL;`{4^9#;e!&D=C-&Lk8;9|NlO`c*HPy9@C${KeOWnB;`P2 zATRu9VP-jSWFD-S8kh{*zoh2aO#pT8A2W0o(w3 z|5bef!~)j#|KF3RAf-U``!@sYUq;#A42-}3UHtv;%kTfcfBpOQ3nmTE<|1vNq z0ns0zZx{dq2xP;5h!=kY&G_~A;V*`-zy9<8Vi5ZI|I4p`PkusG11$kMn1KNxfWUtE z{TpHc!>?a|&i!W8{>5bQ`~TnHf3N=fz5nHq%!z>% literal 0 HcmV?d00001 diff --git a/src/Icons/flags/kh.png b/src/Icons/flags/kh.png new file mode 100755 index 0000000000000000000000000000000000000000..30f6bb1b9b6c5bf355f67a17531fa73beafa6639 GIT binary patch literal 549 zcmV+=0^0qFP)P;@arD~1pHxO_zPr1&>t9y%wPZrAQpyS3=Ms1K-T|%K*j%o>i_=z2W0&D^Y8ax zhQELQ{rLl7|Ns5_-|C4+00M}Gf#D0s|6k8u{RAokD*W^JKSaeZAp18+HBcQ8{rdA) zTAYJ{;SE3lu^j&CtN66?*W<_k{(=kvTJiVSPc{h&pyuy)ZZrJ(`}gOM|G$0#rP$=; zY#H_d1P~L*>3>1SGXDMzbOE=49-9EaM0J&9T`emwH;=g~P!Ocy*DnU30tNVGcpOKXK;IXGH`G*aB%Pig@_cF{AXeP^XnG~{rU5QfdL?ZSim;?VE{Sy z7c(ax6CWR+s|%BWAkauYPfsQR0VXz9sPSMM00M{!7+@fO0fqklmFn#S3Nf;>{s#gU z7DjgV{|pRrOO`MKef9?wUO?vn1P~(w!@{x_lZQ{f0d@UhVEX<0FF08K{sNMJKnNIa zzrX(mdR{@6d*A9+009Ja65pra?7SkZU^!3-{)PrTC`>`Y0b%_6|LHH#J`sQb0@|>a n0T_AEh(trkF%3aX009O7j5IT?Rho+J00000NkvXXu0mjf2r}#E literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ki.png b/src/Icons/flags/ki.png new file mode 100755 index 0000000000000000000000000000000000000000..2dcce4b33ffe1f40d490cb1a2e03efe22ea56155 GIT binary patch literal 656 zcmV;B0&o3^P)8t@U|NsC0_uv12fBrK4XN%za&+zB_ z{P)aXfBpaa=ii?{|9}7d|NHmt1seeZhy|?e|DWei8UFwK|L5=jKYtkh{P{kK2}m(L z`||tm?|;94|Ns5#-_IY+QnEm+00M{!r2OxHhJR4iK=k+TZ>A77)*#lue}Db^^$Tb= zko*TE|NI8J3LpSOb8Z9x2m%4nC$a{*Gqe90@enzQH`ta%tA$7d{Sv5iP&~x@8dMF~ z(;dfh&fyCHF#yj00oRR-9sTeJMNR(n^YxvS3U`G57YhIQc>VqR{rPSM@(uBDU=5F+ z{|5&5hj_*A{sI6o0M7pbe|x2IYDAmA_)R$v7XIy^!u#*~18PtP{r&xWnDPVw`hiji zey{rM^8J)$5m8%@0*JA9=57`qRaXnayHCFDJ@r1pR}vUfQ&&Fu_xE3Vu+-%{U$!58 zQy3!)avcufO?mzv0@a%gl z1HS+N7!IC&H?5`#AOHX{0M7pb00(zPR4BWp;5AJa{{8^XwcY>#`eSh{`1tyzm&^bF q{8L{tuE6I1;oe7AG|b!z0t^7P6ga05`yJ%~00001r;P)}L!W`0l>rF;|7So3KrTcC!ho;=0*Gbf0S0@;YBwbYEs=i=3_$ev|Np-X41fOr z{{tp}0~v7g%iT=?0mQ<{9!@# z-(SD~{`vL)_wRqdfBpaan?+XX#@15+0mRIp%kY{1qrJR?xs-YLhQhSVzk_f6;`sgh z57Tc3#$ODKzZsZ*F#y?2e^`Y0-&}tV5I|5HD)yDjz7nmS1pU~~aVF#A6wD&YtO00ImETIDprOD_2B P00000NkvXXu0mjfKOhx^ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/kn.png b/src/Icons/flags/kn.png new file mode 100755 index 0000000000000000000000000000000000000000..febd5b486f3f90056637b23caa26d838fbadd7d0 GIT binary patch literal 604 zcmV-i0;BzjP)h(K@ANy8uaQvQ^_nWcs z*Z-GL)eL_?t_B7*Kmf7KbznHW;LqhtK<$TZ9ej=*TGLweOZn#S|EVB#AOzI#2dDw) z)4xDJ00a;t5ND<*{rU5ogY7p9)8EGU->gS|Gwk>cG!LX2Y%nmu8NlfEl`8-N#0ZOI q248)K1w0H4M?n#d6+r+%fB^s&Q!OA|2rzyC0000Cs@aq@DuRlQczuzDZ5@KTj2q4CTH~*`MftCON|DS>3-+w6c z9|(gO{~7-O`v>9vKX&5_Kmaj*WME|P@B8=S6~kYUnG7sU|G#_z>G}QV|KC3#^7rq5 ze}4b}^_xjb^7)+E00G1Tlwy4KiiwGVIVgltUY_yi&tI!o|Jl8p;n#15-@icU*KbCk z6Mz3^`1ON{fdL?ZnEnBs@%JyYzyH5mxBfr4|7*t%=AfYeY;6C2{Q{!DKY#uG1wwy- z+}}Xm3;+QH(!lWNFN3HElfM4XRjZk-tp4-xFo=l!{|(XrbkBdVP9XXJ&!0aG3;+Sd z1adCWtuJ2w-n@w=AmGpT?F`?)|9k%Y-_M^QML&N+RfBB+Dh3E3pdT0*fp#rf!j_o$ zUs8faP3>oG?f*A#7{O)(oeuE;(0C>wVqgFWAQqr4|9E)*J$m%5y#o|bz~KAxm4S=v zKP&4$usU!k0b}RSKS4oYgaHH)%c-;9wWL`3={r0|OreK!5=N4TMk7RCwBA z{P_JV0}}Z6?;n_iu%H+Q{s1vR05Jij`8c?M=-GouSI=K${m;n9!7aeW#m~(x$j!^i z%zXLG*~fS9it_V|2?zl-00a;V#NgMjUvJ&I^~3uQB4T37ii-d5-u?gQ&wmw_XD?o^ zUAsm=P*7M%NJdr`Xazt3fo%By|Nn;%AAbM-ZD?YwEG7BBxA%WR!T-FR|8><0Vxn$d zUT@yKdH&)BP#Mq$fB<3y`hl076R7Rgt5;mSyo`Gea7>-}|M%}Nf0%y${3VbO@hKwm zAWK?W z+TGp#<;$01Vv<1pdP-ancZ!Qkd3bmLHK?nrgX5I}Ab=R3zkQ1wk#LIP517FKVgLC9 eRt>}e0R{ktF&Q^6#MUGL0000@P)xg`upqGzh6Lx zERQVE2><~E((v!!|G%IA{@M07EI*V_ln=0RjjdN{oM|h)7EO z{{7?6U#34`ML_iD4-=RKMg|km5|FijfgS(|AV#2u+YAh13=HqUkqe1m1{eb(!T=Kl c0)PMm0G()MDW>>^I{*Lx07*qoM6N<$g4p`a`Tzg` literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ky.png b/src/Icons/flags/ky.png new file mode 100755 index 0000000000000000000000000000000000000000..15c5f8e4775b2b68e0360c1f4ff1f37e61611276 GIT binary patch literal 643 zcmV-}0(||6P)0{QUt82Kj15^L?rd`uqE`oNxjFF#yj0 z1e^fI2i-9Q(8&Vs@%;Dq2on+Z{QuwM00sm0@b~}!1OzrH#hk+X+Tt}E6bb+U_yPbi z0M7pcvI;2tA|wYPA^Z*x0300&EGqR875n@A_WS?(`uvdQq*oFTSt1&p=b-!h{Qv;{ z0st`p&i?}PGCBeX39IA)-~tZg`v#`;6$Tz2`uqI%`ThF(|NnA-^wR?L!uSAshx_~g z0000205Jg0{{tif814-hz}E2g`1#%M`@GEN)${-9=jr|Z1Nim(?*qH%B39iMC&AR2 z>ggNf+PVUWW##cF5^jI~{P}h24a1+`jKBZ?zJB$|uU|aB82|la`WF`1`0wBUe?VZ- zRnf8uXahh1u`n?Z4sYX?@pO{;x_8g;0tl$# z2T+})81L`j|Nel$KOpz_zrTNegN!(Tli}h6pb7teeq#K~3=Aa(fB<4-V9 d!wLWb3;+YKCC*ol*cJc)002ovPDHLkV1loTFLeL_ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/kz.png b/src/Icons/flags/kz.png new file mode 100755 index 0000000000000000000000000000000000000000..45a8c887424cff6eb0471f5a1535139b965e241e GIT binary patch literal 616 zcmV-u0+;=XP)g01!ZoKn?Fz`<^k#?O_Q1 z`=8<8e}=z6_5c2{{QvRuAM+0emcRf01JR%V|9}7gKjGLHfB<4)U|@L0AiL;yFw=jq zasNSbGXHKG{NMlfpWxpAK41Q^gEaj6FV4=$@arEy05LIu!2gi{Gync$`1$|;-~a#q z|NCw7f0xa__4fbPn*ZDO{onuJ|3JnA^#F|o2q31v4F4ql-&_7K9cVD)|KCjiesKSP ztM&iLe}uy71TZ z|DRv){|H?Bqoe!x=x?wkfBu3(0w91`fMN3Vzue;gQUCt^|MZVr;{RRU{|DCmOS=6} z@%2BU5C8a_|1a6~&;1YB8$b;J0mKBvKpP_e^#OhS_CN2(f86)~DtrE)Yx94t!v9OT z|MTDe69TJd_zQH>zdry01PrBrQvYt3|7!q-C@@&>{!_XBPnqZ6E6@K61pYml`M2uu ze+NdW22lI}1Q5_kK)3wPV4bt}e=;a?{xkdrMUmL?|7pP3c>kYY0b~&4U$AjN34j1% zWLW#P{SRLy(>r)v0s|Y${(}_LK*N79FfcIy1Q-CnX{(%t#68R664G@6GIJN-*24NrwB3rW+v!ydOp^Ef6{n_)(btIFVjHa=pdp6)} zz^!@$h^2tpKUmc4)64h&|Ni?2LVth#{QKwk-@kwU{{Q=j;qSk{fBpc`pWlD@C4}l3 zHUR_xF#yj01d}3g9TFqw{rUX<|NZ>{`TG464+L38761SLpR(uO=J){s0Q&s>`~3bJ z6bIb^kphT`;m^O{e;I!LWBmP>@yDNkj7*H>@iN-VTtHNrD96Ue^ySz8pMMxZ=pRTg zKmaiT)&Bj@@b3@E4ZnZ>72sjw}n?8s2>T{qV)lKMV{%|NQ?241(YPff@h;hz00Cp!a_N2HF7% zr}y9gR8D)C;wJ_Sx5=xYz5MWpi4mv-=yjk&KmiL7K#aZ&_9^w5@1DH=3l15e)xUl~ z-0=7B?|)4HL4sh3f5LL21siGr0*GY=!$H*K#ZR;BJ~dv8zS`wDeeIR3;>1y|KC3hK=RLTAp0Mf zWcc&@%EC-|_DIyI;S5 zZoa(f#*3@};Q;9GfBygi2&4h78pxV*WHQhn|Nk-k{`>pa-{0-~I{v`b{|EZ(4?qC1 zz%@X;G0|`0)6dV-R;K{9rJ5v|%9;KB_nVP{8R7~c2@pVx*BKb3t8)H6dH@UxP=NgY z{qNULVEFv`^^@@rIK+N~gX`}f7I~!;+fM-m5DPFa{(t+%C?E(7W+q^;{`t)a3di3} zzd^yz010JK%>4cT^&8LzfB<5=h#HaqkRlk)Wq^@D01#jR5K~0vg#SK#00000NkvXX Hu0mjf%Ubyh literal 0 HcmV?d00001 diff --git a/src/Icons/flags/lc.png b/src/Icons/flags/lc.png new file mode 100644 index 0000000000000000000000000000000000000000..a47d065541b0d998da832e1981b479097a9b36aa GIT binary patch literal 520 zcmV+j0{8uiP)#-NSZgwz{Qh@GSmETWyIzrrS!pkkqDDw`CEYY|A1Dxfxke?UP9EWUlaZ{K@! zXYTRdfWyFioqIm+xW_M=V(hYvbO?~5ZHkEt37xh?rY1@PqM%`P+i2w@_wXJJO#nzA zheNt~+w1B3H|fqGMx=x!lms6SMy;uqQ4R``NH&49%B_cditsDHI6DHXLNubec}E0~ zb8dy|txA`rTkZMN{rCM3FV`MqlfuwZrz$X1)+?ntF|UvTkD3M?FxSaem74ag}Vzy5sA+`s~GjvDl6>(E?=UGu{=w?r5#MJIwhn?GrT#s zeRSo}v&#TUmcjL&mxEF>2%EIxN+SI=O=izlM$T5JH;yv-C%^zTfK|9CLa`qJ0000< KMNUMnLSTZ|5$YcR literal 0 HcmV?d00001 diff --git a/src/Icons/flags/li.png b/src/Icons/flags/li.png new file mode 100755 index 0000000000000000000000000000000000000000..6469909c013eb9b752ca001694620a229f5792c7 GIT binary patch literal 537 zcmV+!0_OdRP)sI{|q~>>TZ2$qp!tjsj_dmuxH+6SkQv+K1^Dpafp!@&+{r#8W&u@@le*a|z zk$)I|{ss9HAb?mjKkZQc#wYOgBhb-*|NQ;?=l9<~e?U(E{r5MB3DgSYf*4|4g1Z=I z0R#}sfv@v<-|;cLeDMG8um8XQ{Qv#?|LOa4L zz5|hefaLFgf557NB#8Tm`R|`M3=9AP!~zPVKOloaN+E`UP5lQo8*B+s^WVQre?jpA z5I`*dz#16EB$cmd~05Jg0{{#R40Cvt10RRAw z`u+d`{`)-+^5ON`yb$y0|Ni^@{rvm=`~3g>{0I^G8ZGb(2;2e)q~Yi9|KETAVEFqN zi2na)xwe&yo%hS1uZ%yx{Q;WF%<}W+mp@!0-yWP|m)B$h2q2(_|NnsK|6hiGKudoE zUGn9{-`6*oEmQ72y~rUb^YQPmzn@?Idwh=T>wA{p3V#3shzY3p@87?_|NZ&@_cy~| zpmRZP`1kJ@JI^@8AFa{s9OeCZO+ts{j1?4b<=-Nd5zA z`2GL?FD{9%H@9*#{QvEce@o8hC9n7wpg7QIfB<3vS^!iHvfyK-U8V5ZH#le}4S|yXQB^Nt}W|`Q?5-JjKDn&hY;a$Df~n9-WqyG5z}b zHWMS`AAkU20!9tv|KD6JO#c`e|FbePFfi-*z4`Hxjg_16|9{rM|5*PsvHt$a@%k1I zzvO#v;hz8j#Q5o)BT__yf)$AVfxHBa6HpujodJ?%_y>%AV59*A7yy`5b5c`Z!JhyC N002ovPDHLkV1l?nIh6na literal 0 HcmV?d00001 diff --git a/src/Icons/flags/lr.png b/src/Icons/flags/lr.png new file mode 100755 index 0000000000000000000000000000000000000000..89a5bc7e70711575c1ee3b83cc2be7f0e1fb29c5 GIT binary patch literal 466 zcmV;@0WJQCP)2Y|A4{o z-@kwT`t|eY&mTX2eEM}Kp+i!_T03wQQEla((gZiC0cs^;{c3|jAkj>009Kl@aN){ zC);;k0UG-E&);Xo*&wq)roznr3pD=Ezu&)DC1p;}S_BY4jKAN$W)>8Nm;toyKW@Ot z#Ps&Y4S)b*xg;zq)7SR<*)x!NAa?^@4{|ZkY%l|8FPQu15397y$%U%{0*LYZ>zAxx z8}J(slm+_X#f@tK0mO1iR9wET{^!#tU}GSb{Q3uSG}s1+e?a74b~(9Y%Qpf95aZY9 zPuWDo(ENa58%O|%pI^NU5I`*FB&GkLM&}>Ys6}P~0YHEO0B+J}4VS0Fk^lez07*qo IM6N<$g3a05u>b%7 literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ls.png b/src/Icons/flags/ls.png new file mode 100755 index 0000000000000000000000000000000000000000..33fdef101f74e38e2422bb85dc8a31bbf1da326b GIT binary patch literal 628 zcmV-)0*n2LP)NT^udI6UX~&u_xA`izWBNXkIq%g^6Y%Pu{8|3yZC zlYxl^Ab?nacHcU-^!@XD|Nj5|`r(zVwkHE4BV6^xC+~{3+xxCp=yQ1PA~B|JUd6PoU1p;PCnS`uh0!`Wt}y4#)fi z@&Nb%0tn=Xmv@c{N@*}KFh0M&kIP1>YRmQG4?lbdn);9N*SEXB6{h}Te)Ie9Zy;d! z#Q+chF#yj01pfa18Ye&*C_n-K{_XVnU82h1@caA!0{i;;`V*Y{7}WX#^!xhz{Qms? z{`>&^00Ic4fsvW@|G$6Ruf6C#{P_EiKfi$f`+Dz}{FL7;Z+`vz4fMjFe?Sd?fe5Gp zAb>y`UVr&E@!c&!7K){sO`Ozkh)melY+9 z5KGUl3lpbYV0iHf6xF}JF{n*t;A3C_dhHtn&^!?O1t$N2Nj?UE00RIWZBXJNY9>Gc O0000 zKY#!H`S<7dzuzGA_xCRl`Rmu;Um!M^l;`6=xPSp5fLIuQF#P%V7sv;y25A5(1xW+7 z{Q_w~Xakza@Pz>&fLMUe`uqRSpZ|Y=>VQIE8-4+ehiC(l5cdDyKm=3_5I`(zTN!l! z|Nj0Es0O49Xx6_!5M^MM5b`fj@gGk4KbtNx00a<=83P0Vn?HYFf{Xx4|Nr&tKga?w z11|FC_y0eCSvdcCFfafF5XlYnMRN&=-B{`>{W0U03nA0WvHB!TYz`r< y{$OAL2q4DW;E4VQBmbdt8IZ(*2pDGo0R{jiB6maa(%qQ=0000! literal 0 HcmV?d00001 diff --git a/src/Icons/flags/lu.png b/src/Icons/flags/lu.png new file mode 100755 index 0000000000000000000000000000000000000000..4cabba98ae70837922beadc41453b5f848f03854 GIT binary patch literal 481 zcmV<70UrK|P)?-#?r-wgj45C|ZESQtLMVW?~Zs{a4) zALIXj41fOq2a1uNeOQW%&E= z|DQh$fB%40fEE4z10q3;-;ClCKpOx8h=su~@}N>;ErcnO|V^hXG82+5i4Q+5aFU0|N&GK!5=N X;lz1sunOP500000NkvXXu0mjf*7env literal 0 HcmV?d00001 diff --git a/src/Icons/flags/lv.png b/src/Icons/flags/lv.png new file mode 100755 index 0000000000000000000000000000000000000000..49b69981085ff54568907cd51a56a1e5d8b01ada GIT binary patch literal 465 zcmV;?0WSWDP)TuF);jrk;v#5jAUY900)zv`N|Ns31p}&9s{rUUv@1OsF{`>=? z-@pHYNg(_0@82^wZ2|}&78a1v|Gz$Y3Q`J0Kshi8lm?N%fQ(=Ne*FS+xn*U6mIDM3 z3(!4({{8=rtQsf{G!?8Agn$gN2Dab7KQS->1Q6rPlP7uPKoY|E^ZWmwzrbJwx)~sVSb)*-|Mwp*NlCCVfB*i0>4ZfB zFhYR-gakS;`Tzomv6O+~6D%TsAw}vh)M$o8KMw-~K!5=Nd?C`~#DJkl4QvBtQTT<=hAW5C&pkLRXaMS_oX@ePCublh%7`S0>4^BHJ{X z&jSWU1bzAnAdrUt4F8|~c=q?-U!ZD;3Wy>I`UNEa{sJFg8g4-`_wR00IcC z0c`wlknw+DNZ2$-$7NDlT|NlUo0ap!i1F~k2r~my1Y5)izkcK~h z{{rRU9);Krw*=%9uq;py&^Z7B1lI8X4~o-~jQ<6)85pKOHYf~%iU9%$qyZ=)&LIKv z04P8aRsoF!DgoLL3cdee4gVMb0*H~J5hWs_B!uw~i3^Ex1_pot0|0+0kn{N-xWWJc N002ovPDHLkV1lkWn<4-J literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ma.png b/src/Icons/flags/ma.png new file mode 100755 index 0000000000000000000000000000000000000000..f386770280b92a96a02b13032e056c3adfebfa18 GIT binary patch literal 432 zcmV;h0Z;ykP)@|4`Xj5kLT%`al?B=W5I`(ov;U*0{`Ko0*gOW1x?dnY zU=0kve*-lD1P}`lGXhluRs8wG@Eb_}{{H{>S-s!?{`@vR^^5K2FR(pO4M5WY0*DFZ zqCZG(`2G8?)UU4`zrJw%x*-cw4MBhY08Ix7Ah47E{sH^x7s!U+ztwL3`tbkv-#@=J zum1jzWCJ7ENdN%^b`n?!@|4`Xj5kLT%`al?B=W5I`(ov;U*021*0XgD3^5{teN< z@cTDV13&<=05Ky_HBiN$KMcQtBo?#b8i1w)1P}`YD=UMn?0*)P|9^oV_=9jUlG7n1 zgOt?2g9iZui1GF7*Fr)<|ABx33~>V{CZ_AxuLA@S%fEmBAbhajaRP`eP%%INfiyrk z1T_G`pFe*90tjjYTn_{=GBPrt03a7C3lKmc4KH52_yY$2zyM+rgbiXafFO_o^aD@| aAix0StzUbk+v2SN0000M*00(~<{@!wBU}0eR!0_)M!#^$%c|o1wA4mpD0t66HlA)zv9Z3HD2a;wKuKxf3 zKLhV?#{Ykr|9@us&njQ==l`GI|Ns8^_xsQFIm-b82&94GKf}}4zyJRI4@Cd}JZ511 zyk#BtzrVk|eZKww|NG~I-~WGu5Q~)bF9rsH0Ad2#1T-6>`p@704FCVWdiqyE_S>%? zzn?t&`v3p0|G$6zgQ7n`R{;bN6VP4%{xkdmsRoGvjXbc2Q*ib#i+$e?>}LD_@7KRy zzyJOE_4n5=pu>QE00u!g^X8F}1){Re7)$pq2>GzRP>hz5WF0{Q`{ z7%1`&WXbP;Kox)fFb41M1d2p!76A1_RfAN3oCFX+Kn)0M$tdvjY9_8yH^9QVjn@nfZP*{rmI(|3?O9b~d@cVAX$tK?&3V z5I~F!3@gDg2t{v?r~d;6^$&1NgV7;ZP#i-L5C8-i0C2iwRaxXp%>V!Z07*qoM6N<$ Eg62#MXaE2J literal 0 HcmV?d00001 diff --git a/src/Icons/flags/me.png b/src/Icons/flags/me.png new file mode 100644 index 0000000000000000000000000000000000000000..ac7253558ab939481a85cc06dcc4d73503afb9f0 GIT binary patch literal 448 zcmV;x0YCnUP)l$FJ^m&#tWvBA4C(n)b76qu^ z3TjKJi*u=MzAs;^(tHqT@6cZ|8AHxz+0T%zR}I9mkc`8faCz48MN^H2?$<3((yN)j;^`52o304M1f80R+|X9}Iwu*X+N)@cjDs2c+lU z?_dAGBv9wyKfl@e{~Tjr001}1@4rADVDj%Tpgtwu-=}^u z00a=o2DtG+^6#HtKYxRyQB?o^{pa7Gzs!FaUNHa!5W-0i5^f%h1nT_t=O0kRUm#-m z!vGLKP#fTS#5u+P{rv~@0nkXGhChFS;q~V)5d8o97pUPE13&;VK7Rc89~k`k^9M+( vx2Q8b0Y@nl1JFDW`UNKcfk_?)fB*vkB(P&2-J7g<00000NkvXXu0mjfGX%sy literal 0 HcmV?d00001 diff --git a/src/Icons/flags/mh.png b/src/Icons/flags/mh.png new file mode 100755 index 0000000000000000000000000000000000000000..fb523a8c39d40401b9abcfb144a73cbb2d76b286 GIT binary patch literal 628 zcmV-)0*n2LP)qpJCu1p{#SASZ=3QjbPhlO05Jg0{{#T~{M_a8tGL(@4F<^6===Qr`uzX+`vVjI z>RSuFND|!tCprH%UjG&-`Tqfgkh}r_F#yj01OWa1_W1j+!`}P+|NQ*@_xS<*{r*D) z#ao8o+xY#_%t@QS?0~yfBW+Wj{_zyJQv%*f2f%)|)v=^uaq0&4j6{l|Ybrbh`TZ`2ITPyN!~wBya;Q+wXO z|N8qsP{n^H7N*~zApZOB??0dhfB*t%@KJoPW~Y4ZyXB%oU++J<@%!g5F#%3te)iws z==lAQ0jwGr+CT&T00a=DyL0x5XB;1||6pKv0FF^K^bd&vjBEyg00RK!=O6aq+V@KU O0000p}y_ZxVsQQo9l8qD!tQ%&&F2zEbEdU-v3mY$p-gb*;wwp?LFG<9EeNpZLj7Q z>zeacpNZ>XJG@0bcmXcALo;Ad(L@#C92p0~G#aM!FfF0T7^YIJVVFaIl|0gRpSyF_ z@0dgJ{oT}qqUk#4;-a-U9Fej5EJ`tIE9)E!qDfL@GEq>vEDI}q@P8EmenIHxu!*Cc zLK?@%1j7u0A`mPlm`kyT;5daWs;EH!+LV0IWO0Zyj4+sHxRqia#e9ki#cu?^6YQn9 zOfZ8&4uw%r9nR_}FG?tJ1sBpnAsdGMh7pA$Mlm3ABvgz9aj&GrxaT8{1^YB+UzPEM zQQ5*0;(QnblJRNh>E*%16wccXl466KPu9Lk=M%$}%9~Z3xs9na6KbZ+^U;AoQ+JVg=BO3kgY$Vuu?iP6r(sQV=EH;Iwf|hcN2Nd zPl_EfW;$kS3zh=H4ojC&X!7Bd!`~OdX{VxLp z5dC3f{KL%rhe`hT|Cm4jfB*jf2Sk3^vlaWpqpU2@27mx!VE|eEAE^2d5dHlPWd8sE>;L~hU=6?i|N8~f1J=Os z`!`SnKmdWv|I6_A575egAcQa*n+Bj_fB<3vdK75(@4vtQ{Do`yh0yRHtQw*LD9^wE z5I`Uef5B$|`u7W{2T22%M6!Vq>?D8y0%`dD|M#!IAl1MB{`!Yz!@u8fUYwuxex*z#9GlH2{4I3~mO10Ac~g+V6jVB)KI)-uUyEi4o|t-;5vX%A}^sE-TCS?;peW@7xO)zGwLT z>;Lb2Aa%cf{|B;v0lB{!Wo3aj00dxJ4sHN|VGstA{YR$4C2D_2_!cBcz(8l;%*ju; z_5-pDt^fjRVEX=(;rPk#zkV}({q}dw+K<0~Gco-B2UY|%8?FIpIzRw{{P+Lo&pY>j zzJB!i)2Bb*-v4F%#qjU=2Y>(qX<+*Ohe1*jY|LMVKOmiqU?UkIBoO`m3qe4|00G4K6*VFmu*EK13J3rK Z3;;9iRuWt9^;rM_002ovPDHLkV1h$@)rkNA literal 0 HcmV?d00001 diff --git a/src/Icons/flags/mn.png b/src/Icons/flags/mn.png new file mode 100755 index 0000000000000000000000000000000000000000..9396355db45a8ee040c790782209868acaad4b85 GIT binary patch literal 492 zcmV@{}>pU8D26lh`@M2^zAEy;6E4#hyVhJ1te8n&0xjw|I|OmAOC9q@qGTx`1kMs zKYtki{9$JJ&B6L7=Kt^CKt7QCvS|}Q0D(0y{Qoccl;O=^hIfA-|M~k7Bn3tPfBpOS z`}Y4|zknP@Sy`YB00G1VQttboLEtY##9yH3?>`J++5f+PL6rRiQNLgu1_potVgX{t z{eKx$|NOuHhk@zOpC3@OA=>```VZI207MK7009KDfg$woe}>=xgMa@Q`TZMV99$1f z=+7UZ=>P!)^22||KmS$!{Ac;a@cR$YT8L7JY6c`57{N{g2q3VN{s9Bw7X!l|paf9r z=TC&I7$7zP9Rm!dKY#u(FaQJ)NCWfVKmVWoW?%y` zm}dTA_#*kA1?Z>0QqoLZAnySq0pv->KTM2<4My5DUW>hHBSpkmCRUfavf4zkmMxWn=;={POe9 zpZ~vq|NHajABg<@_xGlmn*aic1*nOE;s2AbPk~B-;NSn>+$?|p{{I~>&N%tu*Drs5 zfBO0B*Z*HY)v`RYKsx~fhzW>+Cjb5S_s>6&>Le+qufKnBv&bF%YWVBlABO)w3uGC7 z{rLq%Ks`WL0R#{e(EPs)fB*akI^_5N|9=)g|N8#t9~WuY61}otf4Tqs`!(tD7m$X( zzkdG%X#fZyCZKPCW&?Et`7z=QS^~DI8Yx-=nhgK{7whGvYgWDg!B8&G1k~{7FHk81 zKmY(S0M7pd06qXVA~x>%?)v`v$?y7WENVL!I|c#<=Jn<;5-<%03=swpg4MkH|N9RH z59P$=0*D2u3CIB%01Ag+CC5rQSvY_G`T70NcNRvLcR${}{{9+hIZ*cRKadRo0R++j zv0Gk5I)>DQ+oULEUYSww-@{VeP#&z`*?j4i%tcfB<3v#u_k;CAlSmszIWE zes6rZ@!!9HKqG(r{Q)GE1e8GG4GeUkhF=T-0mR5q%E0gm7LmVTk@^EErhg$tKMw;y afB^u%K|axUkwLit0000IqP)p`2X)eQ1zd`|Kz0p8A$%R z`bTZnZKVTj3KfeK`2Ky*5B&e@&)?sFfZ#7s13&;VG5q=W=RZg_5SU54z5Mv&imk%` z|FW?#NF2HHZpKX|PKHOnfBpIO`|qDW|9~0*0*DFdzkh#$Hv9ux`j_+Xe->2}ZC)XM zHV0!dKPS0Ur}$Y}|Nr_6wBa96o`K;HKmdVl_zUt7(16dMgtTSeTz>rQ?Z?ko?mjsC zklD%d+V79-zd^=BZ2$-$7GT%`Z2%eY=kMmT9MVkp=Y%mFes6g9+4CZ|=Y~?>`*tz_ z9Sja7kOqJN0yzojravHW{k?SeQ|&okK5=fKkARLe6n%c?uEf?;0ubZ>f;9XA2p|@Q zU%!CHiwJW41sn7GB}e}J|9v$?qW1mmH(Bw2pdk4RbO%twKY##YWMEE2jz}>2 jgG53Y5Cqh~01#jRFwa04;J&RL00000NkvXXu0mjf4K^ZQ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/mq.png b/src/Icons/flags/mq.png new file mode 100755 index 0000000000000000000000000000000000000000..010143b3867f21e7791b8254e806b325c13b2895 GIT binary patch literal 655 zcmV;A0&x9_P)$g8u&g1qF5h0Q6aJN-{1Mbz`Ie0O|k$ z{sM@ZfzzR@(T$Ir&B098+eukMUeMl2+1^x^fq~&CAE%jZ{^O4ipMU-bgNM&P{`mQajg9%ivrm#DT>t+4XJGgP z5I`&pzyAFG^Do#{Ra%^vg_(hwneqG2-w+MozW@IH=Wj)-86P+6=Wo9l8G*Kb0|+3- z*{jc+=}JF+`H7W<>HmKQUT#*P1{)(8poaY?9|3*x^4(W97N$Rc|4EDS&R=&5Ab=SE z{{73y$Ox4F`Rgyx2o@H`|EK_{=f}^#%*+g|tSlctd;ka_mU(L~nd(ak@UpY9GCq0n z(2rN05Jg0{{a96b$W_S@ACL(Rxa}M z`G=gy|Nj54lTiQv|3YG^`}+MH7z}h_G^4TA+~V=RqI&{}iQ&&bpkF?J{dw&CQ*JI+ z5dlsHn4|vw{rBhJzZb8+p1k+fF;B_XE! z42<9q0s8Xa-+!garV_&3Uw`~!Vgv;%KmY+HvKbgYfiyF)F);jMVE6!x-Ip&{0DU4U p=>-f&1_my$6wo1$fFwYG0RX)13*@;vt7rfK002ovPDHLkV1lt{Hh%yB literal 0 HcmV?d00001 diff --git a/src/Icons/flags/mr.png b/src/Icons/flags/mr.png new file mode 100755 index 0000000000000000000000000000000000000000..319546b100864f32c26f29b54b87fe1aee73af21 GIT binary patch literal 569 zcmV-90>=G`P)rBb0vs`uywH-=91j zzd+y*NDt6q00G1Vbl+cwzkmM!`SbO+m+YTk|9<^u`R%^_m*bXSzgT|#{QE0P`4>nh zQ2ZZA13&;V0loO=-(MgHX#3gMzn3`u{`KzHucyC$Kl}CT<*&8wzt6n|ss8o%*Pp+C zfTjZk5DUl#p#T2<`NjV0^vyqym4EMy|26&E??3;3WoiC?{O#A4)4zWSfZPMI0U&@t z8bCe+8UPFj-d`E(e|zZv%GLeN@c(z$rC;+8f>rHtN0D&|BIS>OtI{AOC zx$tZGDUcCBkzc|7XAeyp!)#=hy@sHz%Z8Nmi!G71?uGb{rk^vkcEsO8W!D1Ad0T=%Vj%gtVfB*vk>3V2g53(}_00000NkvXX Hu0mjfpCtxQ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ms.png b/src/Icons/flags/ms.png new file mode 100755 index 0000000000000000000000000000000000000000..d4cbb433d8f9fe49f06585dc46ee15593e3e621c GIT binary patch literal 614 zcmV-s0-61ZP)w!6%f1G{My^>{rmp(`~Up={s8&+{Qm#<{R63-jRF8M0M7pe zp74|h+7SfEy9M#{{`U3;5)b(M0y+2j#`QMv`vWF8IQ;$o{QUp?{QmLR&;S7V0*Gk~ zkHv3!H5OU9Kb*Y(q-ELEH9vC;U*%N({+r?VuV26a{F4-VqagC^H&EN}zd$De1Q633 zj~FHafsLPJA96}RV-#A)X~v?X^MOAye@1K9u&05Jg0{{zeC zH7h(V@9+2F_Xpti2mAc}=j!&)<^S{h0sZ;_Q7ob~2($C-{v8Cq(%>lF*}4LV2^e-j zV}AbzqQAd@=ogUu2Vs2v^{02G<;{1(|2aQ(EV23Z2N=G800M{wXv^O}|A7VrH9+)$ z7=NG)mcRcxm)QV402KN07wDuv009Kl@CPU%A;t|Pff9c}I{*Fo2PXf3L>PYm|M&kd z6T{yxzy1Ri0|XEw14AS%MzNxQNDQDd27mwq0OfZ^Ej7^!+W-In07*qoM6N<$g6Gg9 AMF0Q* literal 0 HcmV?d00001 diff --git a/src/Icons/flags/mt.png b/src/Icons/flags/mt.png new file mode 100755 index 0000000000000000000000000000000000000000..00af94871de66cd0fbf0ca8e46dc436d66e2f713 GIT binary patch literal 420 zcmV;V0bBlwP)Io>l+&W2PtRx|M&0z2M_*#`0)SN z@BhDl{r~j~sG3n$7H9)N0I@K!uxMy#e*W?mp&AJO{R1fisrv=e1J=Os`!`SnKmf7) z1AD;K%nYO&458rnZ>;h=xCZfJy-Z2&4h30>ylo1|%C8 z!A=4QAQtS#|N9SD2R9xVP=6R000Ic%Boqz*|DhQF2dLpM!{5I^H2?v`f~*=Iag5B& z3^Fndyu3hzLFn&a2m+c75I`Us-n@D94+enNf~Z%o__l08i(?1?2rvLmwOi|Xk;8TX O0000wT1SlAdCl&Y)$gVg>5qW^#Y{{Qp$|KC6V{`~n5M8AIn z$$wxH$UeVm6F>m5>|$VWV&MJy|4IE<4N06-W9 zfN4+=|Nq*iiwn$Q2C&jbT&$=TD3oCSlHOGFpRx(;BY;>KBo9alsWSh04>T2o{{H<9 zq`@}){__Va_~#GM1}QP2gACgN0*LYNU!Z^U|NnpRpWzq7|3Cl#|Nj5~7gmyqN$LIj zQvdWzhA$B4g=Z%5I`U&fgJtk z_g|1x{{H;?U6oxK=&at?J**6@V8K5Oe}Dh~1#%?NbbtT?*#Hy-y7l+}Kff9N{$pgg z_WK6Ie}+7v0!uEdpa1{-Wc>4s0pu$NunhnK1op#kuysJ&8U8Z;`FH#0jm^LQ>Tv2E z__*)izhD3U{sq|pR0FmFAb=oF`osMFS8?ijP~d>v`s?4X6Tl#928Ghke_*>=zWoA* zI8ZS_0I~c5+3<%^Qj!Z4rNibE_6+kRtZU3J46>yw zfWS`r^B2emYGC;Nhw;yEHn21ZK^Q<1%m5k+3<-b$0%`dF7h*inus>j>Kov-;VIf zD*pWek$*v<0SxiK|NjEzfQkVEh>@X`f#DO--wX`DVCWAL;}4AS4@`0~00bBSj-y@M TF2~k{00000NkvXXu0mjf^ET$> literal 0 HcmV?d00001 diff --git a/src/Icons/flags/mx.png b/src/Icons/flags/mx.png new file mode 100755 index 0000000000000000000000000000000000000000..5bc58ab3e3552b74d990d28a0f500e9eb6209dfe GIT binary patch literal 574 zcmV-E0>S->P)LFc1LT4cKmY-iGBrkbGB7ay`}g

Nzrc?B z!}RAj&|v@p#KiFL&)@$*g@6D2{reke@BjagZ=QH_|HA5tt#{7v1Ul>guV4Ru|Ni&u z_rKqNfHnXG5DUYvUm)ZE{sF26>H%tC6A=5t#K$G4Eg-G_A87rbKVS#^0WyF#00a;d z1Ca3#WHt~1jRI=eclPL04k1AU{avRH{sTG*Y{UOQAO!R;KmY+XFaVtnvEdic(+vNe zOr8IIc?-17*~$Z`|L?Eg|G`fB4^+g!01!YxCouq>54Pd=FQ6a({TC7tjr5F#2GXxz z|3N{=01TJ^fBykB00a<7!|#88#Ce2)8ovGh$;ikEv=>5x7)(s8a literal 0 HcmV?d00001 diff --git a/src/Icons/flags/my.png b/src/Icons/flags/my.png new file mode 100755 index 0000000000000000000000000000000000000000..9034cbab2c02704b65fba6ecc4a7a1c1d053b6c5 GIT binary patch literal 571 zcmV-B0>u4^P)Z-xKO+5@Bcl`=5c~|G$6#Vc^TNX8-{JF#yj01a@w+002>mTdm0Dxpa1{C#)An)W@eTA0)PNwiNI_f1h_u_DTrb&+z}xv;{Wj zFGj0Cgf$G002ov JPDHLkV1gu%1+M@A literal 0 HcmV?d00001 diff --git a/src/Icons/flags/mz.png b/src/Icons/flags/mz.png new file mode 100755 index 0000000000000000000000000000000000000000..76405e063d43f2f3b5b9cae4f76d9f1c73cea25b GIT binary patch literal 584 zcmV-O0=NB%P)d!0?ZO;SY>NM!#Sr3j;s^4&s;y01$=&U~zyG1R{bN8&$-J2AZUB z{O~2s*67}BSLujJh!l{(TM_&V!SLx<0I@JIFetqFAHVYHe9OP56#xDPD){#oDEIpx z82$bI>))?me}4fPvfQ#j8vp_bq~ZU+|9p&pvv&RstuJJil>ZL~|9}umff)b({bONa zxh{1bAb?oDF)-ZV`m5;k=ljw>l6BpeezVN}{rlPPKR~N~|N8X{NCKH4>bI<%?516t z00M{!=o3jd#=5m)yzyNB8Nca#eH--U&Fe3(f#?+keR}os(@P+F`}Hl*IRF8~0t}ng zTmN>%etWlrgX7)b6MtD}{$cp_8-#v?7>pqD50GU3{f7;x0U&@Fe=;yIS7rUbaG!zu z&%cJ+j{>}Z{{3SByBg&1|Nj_3~Dr2e;Gh>zZrofD5`!lF#Z7{ z2B7#~hM#}`y~Cfd!0!j9&~4{}>qlfDw=_GI6Spo7yiaSL1(R34j0qF#yj00RRApetkm@ z3-<^I`04Bn_xS?+{Qmv@{`~y?GBy}bOB@O2-v*J4|MK+z`}_2=vH}QbDjOT??*y+^ z9PHma=D0k1DE9l$Z%$6;=mbqObq>D1hX4By|NHgp|L;GHwRPtz;{gH)sDXiz;U6Qz zZ)V2dKoY20MNK$ASA+NcQ;z)f|Igq2|MmO7w9@DL!aL%O?v>U60R+_W>(dw3rWqbw zY+vs`7YYhj_p}$}TRP+a`c40T|N0L!J1pWwjPJac>kgmX!|;RwAb@}x{`~&)@5xJE z5fO>bZXLnj?>WlS|KEEGbn$;~p|4%Vx0QJ+&gI^Ic|%b^5f~5v0R*z)@87>RPSSB9 z(mdPNGA>^D|K~4|Gn`ysXGCuKcCvq8=a*k!egj?m?>8{m00Ic8fvd1cUx@iTXM5HE z^H)FyGjo2eEq-FG+;YA1)Puvn7=8hj{`vO@7;-=x00M~R?)3!82NxK-n*V?K1yZeJ z{HiGaByR2;1J+usHUNMy48Q{FH!M8N)Pwp9Y)wTFo81A^+}-HTA|tp~ zO4-IyLWKVGUAVv#KrFzpU^vb8&*4vW%&*_Sfp-5+Oa#jR{(FIy5oqwQKVTa`BqPut z3=9AP#KLU;d%N^MnR|>Uj{MoN{TEQv&!4|iQhqnS=35v13ux)DKYxDz{qyJVA7#|2T literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ne.png b/src/Icons/flags/ne.png new file mode 100755 index 0000000000000000000000000000000000000000..d85f424f38da0678471ef4b3dc697675118bc7e0 GIT binary patch literal 537 zcmV+!0_OdRP)pTI(!tjlO;rIXl@1HV&)cpmDGW-GR z`3+L^2aNvy`v2$G|KGnEMPz|W00M~d>&=s#l8OvKbwEpiHvESG2>tK>|GyyO9|$ut zvpzk42q1u17-V!9I61+pfvQ08|BZwH@16Yr=jVTUlmA*S|6zcEk@1g`6+i&7`~&$E zYA%%V^7j8zTmS$3{hyirzos*?2B2bq00L=%yMh7Y5+V8jy0-s+|NJkm_8$o_f}Hjb zAb?n|yt|^zto-ZmuYW+t0)q+&<<KJ>BgrQT zRQ>1Q-#;J~AoS`6pHRCwBA zU~p!DquG0BzkdJv^XJbWKYo1u_VxSs@1MSW+P$@#L70Jomw|zm0SEvBhy{qNbE|>m zzkmO1v}^=;1(+C_zx@3C{m*wPUMbGM98Q`}5v}3B|NZ&>_xGmUO#lG|(!jv*|H=EO zfB*gc{`33)|Nj{n|Mza|{r>BFYe?(AfB!%K_3?Y%L>Z^l>!7{V2qIffI$#e zz5f4~?wt{_jNwA=k=tvV8m;04hxH1ClNsp|jaD0d_yUND;Sa;#|9^ps{`~n3bQJ?5 z!?D}Pp1*tk?A@~oJ0>vvX8@W7)C|%C)&LMdARGSt{R`y$`S<5P0|@TEy!-p_?>~S2 z1lj|1A`hhCuT1`^U1^@yK06yzfAV)~#?EnA(07*qoM6N<$f^cITh5!Hn literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ng.png b/src/Icons/flags/ng.png new file mode 100755 index 0000000000000000000000000000000000000000..3eea2e020756c41abf81f765659a864c174f89db GIT binary patch literal 482 zcmV<80UiE{P)E-@kt#fq(zr{dlL|rVbPb$^K$sU||3VAQpx%4ArjH z5b1ya|A`BUvomopF#HDspdkBi_LzW}KMcQr|NHa%@9#}BHvt3?3s4hK`pMU)fB*dj z0+88E|KR{Ac>Ck+U;lpn{`Xs!M;2%gKmf4-G0FZ zKmdWv|I6_A&;LJv{(%shYM_N64Szv401;3FKmf4-Jp?oxsQb@fum%PU8~*%)I0>i# zs2CuCKpOsn%?64Bg>X9QKhy?*00Lh)xZD#`v33$e!wuw~|G$AI0?h>~ z1_&UqlR!#;Ll9OQ{s1-n2ZahyF+c#Z0Amdp#**BUAaDHn%gD$G3dPzV3};X@Gl13bFaQJ? Y0MmSSAW;3b&Hw-a07*qoM6N<$g7#LQDb&XuwlP!fzJKM z`1`}(|Np-K;|B=>MS!;cWf13KY+LvSAb?md?)rCHn)&`aU^p;VI>1V00D#b-){yc34R8!1Sqb680000@|4`Xj5kLTv#?55wQzKoX38|NjLffBpXj6#2y{D-E;(Ab?mHL=FGT z$TP6>fK>na1GWK({(upf0nrSU5*Gz(00%w4e}91F-@gjtJbOE500a;V!?RECzy5mt@dro_q~YJM-#~SLe}OeX zNT7y4|NilCvNABd0|+1%hF>6clER!2lYo}|1|zVkK=SXOfB*mf{rC6ZKVbL)odgg- vjKFAPVE6?_e~=h|kVO7~qZmRm0R$KTYszPUy89K;00000NkvXXu0mjfB$dbi literal 0 HcmV?d00001 diff --git a/src/Icons/flags/no.png b/src/Icons/flags/no.png new file mode 100755 index 0000000000000000000000000000000000000000..160b6b5b79db15e623fa55e5774e5d160b933180 GIT binary patch literal 512 zcmV+b0{{JqP)O=a{vExMP2%`MCSoB^FIcLe_%lf;|~%E5I`(IQNh}3Ao>6Q|DFUXMn*>AqQd`w z|1kXd^B;tM|Njjl{{hM0zwd6?1Q0+hV1xeud-4=Wy?p-%sO`^#2S61Jzk!N?s)6X& zzhA%p|N6}=D+{y%Ab`Lc{sL9~1=0UN4*CD*7s%9KAf+JHKs~=eB-8KTKvw|-5R1&; zzd&a|ob(5%^Z$Q=wHy9p13+aOpFRNu5F>N&`Tk_-7w>=n{RejQzkfh&Kn{rf10?_b z{tFTZibx5v&dxav5I~H7|Ney-|DWN1$%1FyagzUW0464;_wU~W1Q5$TW@eGxtUvee z3vAf*8|igK9~@*rr66bh|NrkNM8z+V zAV?>O@ek;bKfu6d00KAO>U2WB)$@6+CBT{3ok>^7H@y{~6FRKmalQ{r8#S z4^Xx6Je&%q%J2@E@iKAb=Rv<(vO+e^|@#56B5{*~0Mg z>UitA{$OPI`~Tk`F#7!u z%=q{3H<BYX7n!%ts-g52=?&#%8AHvnDo=g*(t zU{@(f3Lcro01!Y-3_uV4{%5PNloM>zp5gQNALI8Qf4=|z|KsPsAHV+n`1$wy&wt;4 zfzU5-=mP{0FqD1)U3&iJ)0b~Q-+l7x$B&=CVSxxV`w!S3U{3%6(9;Y60R+_W0~jFx z85t(6Ir{$dcL`zMKcF!E2U7}WK$QOlX#fZyMg|5;)aZo7D4hMD0TloQ7ytwk}@P)zKX@%&%DST%gMqDF&nJ<9}^SM9e)7=i1G97Xij+!pc8>s z0}TKw06GH{9{>J;c@WiqflO8wrXNp!0t65X1H*raF>uuoM}q1_&UQ zzyE+PV}l7nR6|1@Xe}f}K_mmn5Fh~%KtLN9K+(a>4Du5*FzA2|{m;zE0Q4slD+}03 zKxJTefLQ+k0*D1@+|Oq}Kt_TL2e}yHXa<;L{(_vY&wh05Jg0 z{{*4}t^?F62l4F%@9_Wk_yrLV`1}4n_xiEzG57obO$p>A_3H5V5SZl@9UBk;0Q>>~ zF#yj00jE58tx;oDUfVAO7ZA^g)(IQ}Y8G-;ZB^s|2r!a55}@Ef&J{K=uDyPxdE3 z4FCZEF#yj011R$m=m{0X((d>7`QGgNy~*X%==~K4{m|+BO$p;F|LeE!5zX@o6aMwK z|0Cnry8?)1@m-dDW`RF^3@85Z{`vj)H~*iTuYX^D_V?HC|LG63e*OOQ`}ZH9+h%{4 zR^kLX2_S%&fc^l6#;?EsK&pTL{q^hL&)-1T|AVLlN&WsC!*d@f`}fa3pay^dVgYLS z^XKpHUw?lCNw6Z2x?f-t$o}(Zg7`(je_wy{{yg~C5U2qlfPfml0Rvc4oChck)CmlD zkWL^2sNoMV9{$c|wex0wa`2z{-@pGE82$nT5F-OaFayIEq`3SAj@n=l%a5DE9w9oI(Q6o;?Ey zAdrT?A3yTg*!;YE_t&FGSk*xQBO~LVKYsuMhzTgoEGG70+cq{OrGLMF<5CR)KqmnN z5F^kJDrIFqfoA{t^Z)mszkh!J|NR@N^WQHZ-f!>?ZqK&!y&{zFIzP0wn(b{R37FH0BS}Z;-(ZzkW0R z`o;JgO8$qifBy!003d+C8bA*C^$+NzU%!${e*gOW>-S%fvmgwhvw&=%Tb23#oNZ?S z2p~`>{R0^fayL*XP!U2MkOb-c1#;`ZzkmMzW%$Pc5I_(c{;*0)g6#S8SB49$^)FDx zACSQydx0wd{{073{+Hno13&;Vu4Mp{AoLGRCWbOF`~tJSfrb9TxDaUu27mwq0KDvZ UcsT?Vy#N3J07*qoM6N<$f`X&bC;$Ke literal 0 HcmV?d00001 diff --git a/src/Icons/flags/pa.png b/src/Icons/flags/pa.png new file mode 100755 index 0000000000000000000000000000000000000000..9b2ee9a780955566cc7dc2f59ce175f32d3731a0 GIT binary patch literal 519 zcmV+i0{H!jP)|lVPPN>g8sl5Km-s#EI@faK0YA%?%RKmGG2!N|AD;!zX}Teef|3X z_wWCI{=muCn>GOi5DUcMXP^GBIsf;|&;M~|Oj3M||NsC0d;h_|&!7JP`u*?sum8V( z0aY`}$^xwd2q2IKptK|}gRT_Am!FIf)j$AI2PS_*H2ec11_potVu8EfUYUvEKf`}G z`1lE^`X5*+Sm$r%-@k!200a<=Rv$}~=bu-f|Ns5_|IfewfBrH6Nrpdvs+^pde*a>f6qSrfAZn~Z?Fa+2||AuS*t4lqXH%-ra!^K00G3r z@ax~7e+)2nAoSxWko^y??$?YNza~t8coi7j009Kl08{<<|1U847wF+XP}P60U;n*# z@9*{N{$9Nb{(u|?WHSN*&{SqkP0pSkP;|=6L&63i zfEXEE-vV95@Z%rDuRkCLl>P7efnPxL{(%8d!yj-G00Mvj0{}mHT?%@XEt>!U002ov JPDHLkV1lK4=}rIu literal 0 HcmV?d00001 diff --git a/src/Icons/flags/pe.png b/src/Icons/flags/pe.png new file mode 100755 index 0000000000000000000000000000000000000000..62a04977fb2b29b96d01ffef3b88b6bf2ff05862 GIT binary patch literal 397 zcmV;80doF{P)@|A6@UbB2E)`X3x9D*gjYK@dOyv49j-R|ARv|Nb!om5Pi12buAo@&A8j1_q}8 z|NqCt{Qv#?|DQiV^2?@8009Kn!0`Y7lcx-S{{qo}h;n3b`}Y4|zksS4Wo3aj00a;V z*zEsM)xUqEs|Es~YOn@|-@kzx00M{wh#7&Zfj0j6!|?mhe@uX+0cadR0D+zK=P$&S z1T_5l12i2VfWS`r`v>f&U-&gJf}I2qKwu{UjsNuvF#Z0+ASnqp<}V}$85tQ7(W#^a2}2+PDh3E3#;-`R r2#VqJ=b;e{^dbb<+Crtk03g5s0zF}bJ8sS=00000NkvXXu0mjfKVzU% literal 0 HcmV?d00001 diff --git a/src/Icons/flags/pf.png b/src/Icons/flags/pf.png new file mode 100755 index 0000000000000000000000000000000000000000..771a0f652254b4e891fc73910aab38967864da54 GIT binary patch literal 498 zcmV3lobsI zohi_A`bB&J!~)dH$ngL7lczwX3_#UDxxarw>LBRX?|;94{rmL`$Yzn1{l&ll5I~Ht zU%nI;6$RPw9|VBf|1(_vbYnFmA3K-0+yDOt{~_StKSoBzkDopP1Q63dnCt(82%zd$ zpFb}6I_2!oo##J&nDhVtbEpQW0tSEpVuGrMivIupee<8UpWZS`Uj1hH_v_am-&g;K z1CTfW0R#{WvT7jw$rQ2Wy6P|4+kZd)xq2}(*g=aGrk)Yxu73al#Db(Bq?4D0-N;b? z5G()RfB&pB<@s4TkY)e;`2!F@EcYcO{->q=ymt>64xqsK^^5b@FIO-F$h{9?`~e2* zUv?FhqZcm%1P~}#|Nj2NBq_=8`#0mCzd$+0-@loGnqiRuWPl>)F9-k?0|XG`aR!E8 ou!#JF#Q1|6-w+1S#{dBa0Kx%7Vg$%BF8}}l07*qoM6N<$g2}Akn*aa+ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/pg.png b/src/Icons/flags/pg.png new file mode 100755 index 0000000000000000000000000000000000000000..10d6233496c10e52ead975c5a504459fad68ffb8 GIT binary patch literal 593 zcmV-X0Hv=@BjaQ|F{1AU+wpQ{$Kys{`!CTH>0fVKL!SX0Ad1a`1cQJ=-<7ptZmH9SAnX3 z{Q_yQ`~BbL*ME+m|K)!Dcl`DLKS&U$0U&@t8vg$M`{&P}#F!W*N5{%vzvln`{r&f^ z{||ospYrSf)?fc0{rZ3A*Z(w-2B2bq00L=XVPVP4%$zZO`i8aZ($dmav$E#>{B`Z@ zum6{R{h$5&|A}A!9e(}a_zUO_pbY>4IGm#s06-9cg3a4XeYH!D;D>_*`V5R3;NTtr z%*@^Mq=>M$LXVh`5jChqDeaf800L?F_U+sH_3M8E<^KOyQ&ao$p literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ph.png b/src/Icons/flags/ph.png new file mode 100755 index 0000000000000000000000000000000000000000..b89e15935d9daf25173f89a36d8111824fda5db5 GIT binary patch literal 538 zcmV+#0_FXQP)N~0_Y@w0Al+04@f;`V3_{@|8#9F=K6XQ9UY*azdwKd1Cc)=8bAo50U&@_7#Kb? zFg*PK|H1$NTnr5Nxw#FRn^&xvtbK0f`#-;cuKxpc)t_H~fDExeq6ZmH0|XFI1NZ;` zGXMXp{AUnj_^>}zDz4B$`$1}#7U0X2MOU=aELU!7sY=Kr&1{QvMCSsj$|2dLpM12Fg)7ytqY zsKMy}yX6c^FZ@4woIyZ63`(G)I*8l(j07*qoM6N<$f~Z~XumAu6 literal 0 HcmV?d00001 diff --git a/src/Icons/flags/pk.png b/src/Icons/flags/pk.png new file mode 100755 index 0000000000000000000000000000000000000000..e9df70ca4d63a979e6bcea2399263c081ce5eaeb GIT binary patch literal 569 zcmV-90>=G`P)`{xe>ko^7oADI06=l8$gn`UeR2p|@S@&Et-|M&0Ts{jIsi2(+HrUEqpC9EW^)CAOaJl^^9-%lBC8BHP081)#ChQGgo zHUI<=3(zGH+B`^Tu)Z%{q{PpYS&%;j+KluCr=pK*_e;5D)h=t+bKO_wx|Lu6N(?HnJ zN6`lu;-7zgR^V0GaA(7wCwqWF2h;!%KrH_l5Kj8_?>EpHKuhXR);;uSzaAK9KY#yZW@T0p zQ2G1+FVF^n0AhUp{`o&J`0?k5YKbbt8;l4>j(9ExfB*vkhsr>Vq>*li00000NkvXX Hu0mjfu=^7c literal 0 HcmV?d00001 diff --git a/src/Icons/flags/pl.png b/src/Icons/flags/pl.png new file mode 100755 index 0000000000000000000000000000000000000000..d413d010b5b097c4e0a4604eba86dad79567ed16 GIT binary patch literal 374 zcmV-+0g3*JP)Ab?mv3iQ8Nu5A{|6C_|Nk>HFfjc`0biay0|+1% z2B@O{$c+Ek03##gzdwHf0*Hl3)etG5lK=vU1?W~rxN0!OqXDP`Ab?mH`1u+7`u;zA z_W#cxhChG)!_n{G|9=A+zrl>(AX#bYe+w4^1Q6Is4VEzI_51&? zUm!LT$@u9L&^Z7B1a=Zw2xL66B2?87%l|Mi00a<712fnG3~)u5+Wr7F{AKw27w8;- z00L=X`u&GNQW9*;Uxq&*os3{386YGO{rw9;K*az7#P}5)xp2gQ%0-g`0)PMm0MPYZ UsK>Njp#T5?07*qoM6N<$g4HXSwg3PC literal 0 HcmV?d00001 diff --git a/src/Icons/flags/pm.png b/src/Icons/flags/pm.png new file mode 100755 index 0000000000000000000000000000000000000000..ba91d2c7a0de26e554979f6351d42a1a4e22de3b GIT binary patch literal 689 zcmV;i0#5yjP)#D@XkmAv!xDMMW8-mEZ&mK%|%B2@pa*J{pUD?(_ahBqlG}*TVt; zF#yj00{;H~{{a8``T70x^5Ww5-{JLFN2dS#-{Io#@$TjE?&8zZ_V@JO>E`A8`2YX_ z`~rx{;oS`3$G61pUY_{!-0$E2{{CbX;QPSJ^3BEStfg-V`n;-q6+;t+Xyw zOy)sS^8$#8OF-b~@87@v{bTs||L?z_Zq~=&zGIaZd&b4_{m<{;|Ns5^`sL5xKflEU zUjXHSP67x3F#yj01nBVe84eEr00I90|NZ{}FelkBB-0BC^O2xB85HWz)f)HsDi#s! zMLEolpK<^Iq5=Rh0M7pb=>Px;h=2d#;^FNBZtPGJ5bKP1n*{>+?(qio_5k|){tF25 z`1Sjqtv%A&PR-7P0st`p&i?}b008M5=kFQg|M&R&{r=?U4x6PnhWa{`B$w z?CApk{rU?E^8f<&008;|hy@rKe}6M^a>=kt2+9et{QJXr>zQ5ua`W#$8JQS={rbi5 z^Ctr{)6XBj7@3%V17i>%fEb@MFnj<<;{gVSbOv{z8Q{qN1r~!u@ISB;HgNQF0R$KT X>6#2<48ze<00000NkvXXu0mjf$fQr4 literal 0 HcmV?d00001 diff --git a/src/Icons/flags/pn.png b/src/Icons/flags/pn.png new file mode 100755 index 0000000000000000000000000000000000000000..aa9344f575bc92f4c1a5043e6e7d0a8b239daa64 GIT binary patch literal 657 zcmV;C0&e|@P)$VEDzr@CQtS7ytnPF#yj0 z0a0(~eP|Fd7x&oU`XvhO+V>M05dgm54eRCe)!y3s`vCp^_5Az)`uqj_{QRhrlmY-T z0M7pd#W4OILofm6?eh2PFCO>E*7Xbx0@lgN z0st`p&i?}F01o{F1pxvB0QdR->g@pe`}O_>?Enew{R9F2_ajBO3l7@{2K78Gz9u`z z008^~05Jg0{{!Vds4FN77!dx<`5YAi^1B#F4D8&$5I)oT72fOU?&Jm;1k~m5*82ws z?b$fe$;$!&F#yj01PbEP9OVUy$0!>9?*iHF&;9=9{2wXIjNS}D{P+g={1WdM4-6DF z>gCe?_5uI^`T_tk0M7per>)2uHb&;=(#87${QNQl(a`kw{Py}Y1nctu{`UwC>ihis z2n-DS{QU(1_5c9-0*DC|aR2`P{`;Tl?{DV6zkmJy$H?%Xjq&fFKfk|zXRCbma58?r#f z00G1Tv;`<3F2eQa&)+|P|NZ&>@AqGj(m#Ly0)zk56?XydpHmj-@bfY4J_0oTA3y*x rGBBhgM-@1KAF z|M~a-&+mVKfs8*8^zZj?AObQ@tXl^VK#U9w|7)um9zFT5!1JoGnu}M2{r|uJ|AC@F z;y(;9F@d=M{=L6-3m|})KsNsS&&$bh^PO0375Ag3EPt6;7?_!X=sz3*^#j#0Gyh{@ z0SF+Vlm3Z`F-Ar(?BDbM+y#c5od5B%>y$nn=KcNZ|L>nr$AC#T8JS}%RsaMLPy>UR z34^BAe{Qb-hmSD)`~82~jewZHH;sOtVgB{~2T_Lx z^M7~ue_6TzObGu%0nl7VM#g8?t^ouP$PYjMFazDG!uzbThlgL98zlelKgeJZ;~z*Z zSPxJG!?$k$0R+;(`ulr=6P)M00|Ni~>`!`VeZ#eh`fLE8Q){QmQQ=eGY$|NqCtU}^v=1iBd@fS3^8`SJ7r@8ADF ze*C{^(f_{w|JZZ@y#o+HED**2KY#i6{~yEeU;qEJ{Pzp|pOucqNnlF=0*DFdB%s0n ze*I+l{{11(um4^iSXF}z{SS2YKY#!N`GNV*AE2Jys=p_Au>JnK{@0e3zk%WO_xG>A zzkdJw^XDIk{pa6bWqzfjEk^+Y2&CaX+n+VzlIN6JC4s^J?+-}zKcEU=eEj+Q{|`_P zFrfeb|NHmfUxq&n00G3<$-qz^$iN`P!0-!({va{_z!?9)Bm)CLfB^vHpj0t%_B3$- O0000op82)aAGO;3n0AgYI#891D4N?IF|Ns4E{L7&Dm*MXp#y@|U|NLS4 z{rmr)KmTFmmra`h0*Hly38?u0llM=#nEx6H|J4!x{U`A6pVzdvv{Rd?JIrI9L zs`Fos+0`Q4a^C}Q0+k5A1KaQ$>Lf<6lK=vUh2aka(D+|}f9<^YM_B9kC$A?0Z|}3+ z`ptao7t>dSY6f5^0o~2O01!YR8-T_G^}PA>yZ7X8cHUpx=KlJ_{+sC?ST#h$AD{+c zSpNn30U&@_7``$5{_{tYU-I{#-$2g*Lz_YNHw#c5FVJd`!65YaF9ZRd1Q0-s48{x$ s?-&?Px# literal 0 HcmV?d00001 diff --git a/src/Icons/flags/pw.png b/src/Icons/flags/pw.png new file mode 100755 index 0000000000000000000000000000000000000000..6178b254a5dd2d91eeaa2a2adf124b6dba0af27f GIT binary patch literal 550 zcmV+>0@?kEP)~nkZ zGRMDC%7~XK0S0Tx8Wd7-QG59jKr9SQAk|O4{{Q=*0jSzY^rW5C9>)KFc0aM(`^fh9 z|Np=Kfe=u&EDs~YzkdJ$!~!z=-~YcrJO42FE6xsAYGq`2_Mbt_P-yG_e|4Mhx&31J z|LZSE!|%TgKvw|-5ED@OU$BE2n0|Z9O=M(v1mpqrFfl%gR9?uy{Oi{rkOq*RfB%6# z1PCA|pp${Bfd()#{N!P|4fj41<69Aq$E=K>;Tryc4F(7xpbZRv|AD;q^*8I6-->Vz zfB*5n`o{nM2Peo6f5F}W+3*h_fS7<7;^vxc*?8?`g7w0kCk@cHxaHDByoH$n$~K0fYN5BQR!wAqjL2Kmai^lz(OTgcO%Q oK%!9YKcr{|u^AZn7ytqc0H_5zuk@Q*SpWb407*qoM6N<$f;OS^T>t<8 literal 0 HcmV?d00001 diff --git a/src/Icons/flags/py.png b/src/Icons/flags/py.png new file mode 100755 index 0000000000000000000000000000000000000000..cb8723c06408828ce68a932ff472daabecc64139 GIT binary patch literal 473 zcmV;~0Ve*5P)@|4`Xj5kLT%`al?B=W5I`&pU%&omV`KRD53KJ$2txq_ zg7fbmh|k3I@68*40Al&@kBy(1nSq%Zss!k?M~{APS@-YvZ#JJG201x|0gQ}qez5@r z5EI0wa6>`h%cteq@9Mue|Ns2{KQdro`19u4 z9*F+^0|+3-w;#WAv9bOIX#?r_2Xj8qX@CF21pWab0}C_Lljko10*H}8@M3d^)Z>@G zf!6*0!vH4#gGo5!|DS*V{{HzdC&9L6!fAj26p=v+03Zy*=I{f8|9_}7o838uP_pBd z=z9{Sra^iHOE|+IC{ z-`~G~{{ZRVfB*dX11A6d`CYbrEkFRVK#Yg0UeQ$d`q2ZhA|Uz&)bIy{egR1#X&Imb zfB<4bR{ihazwp{dkXn!mkfPsU#_wMs1hfID1|Wb~;Esc6TU=EJGWFLlunkbN!Q9_} zL0)432p}e)sSwo=4bd$f5a~a^fBpd(3|0LbOac`E1P}{Q!+)sq|NsB}pI=e{a>g%& z)4?|U{s;0mNCQ9sG5v!Z57O~Jp}QY!5N0Be0)lgG%);U`26kn-@hOg zU%!6+4+cOs(0HIde9xZz`}Onxub&LUB0x(30+2WcIRJn#2ut|?gWYu1Cf+!-K%B8# zdf?1WA}#uZ8oj7u>$I1i0Al&`=O0k%-@icgAIJnM0xA6maSq6BK-ECw|NZ*S`0Lj% z1_pot6puj;05Ax`F!=umqj7^frO?t|3^&I1kxUq9yECc+jQpY84SWH_0#pxl$?v~F z@*hy-KN0|X07U)z`4{NpU%#2aHUI<=%a31wK(7Du52Oc(|3O^?R1IN+RRjI-n*kVB z3=9AP#PZ|EACPLGJ%9cJNh|>9B%spYzZw7h1%?tp0I_@ndg9MNE>313@6R75NcceF zkr51-#U+7;F#`Sf7i0rK0I_`g_NQ&Zji7_t0d_@@ozArL?Su`s;*Q{AKpRQ~TD44PX+*q00taD0I@Lq1k(S2nt`tR{g)9*1H=ZfhCe_Je;NM%1^NLXfPkU&2dGq1gcanC zzsyWb(hLmW7#V^70~+_6f#nZ_(jSmgFakOWAb=Pd7`8Gn`~pjZT=;x%FbfOAzdzu3 l1(F{a{)I#17yR-T)##NTdjqb^wzQ(`1@?t)Ix4MUXz556teM9A7Ic zq_@itH|pv>q+zrjZJ^Hx5bj=fD{5McI3ol<@^-l_@~tZGV7p>1CU&qG~{YccyC-q z$8~P)6sG{nMmQy85K$E6L33rja$x-b9$ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ru.png b/src/Icons/flags/ru.png new file mode 100755 index 0000000000000000000000000000000000000000..47da4214fd9edb383687c1d4f84fe8b42a51ceb2 GIT binary patch literal 420 zcmV;V0bBlwP)X|NRSO0LlM<{-BURBqYRGSojej zfLOL~|EH_V_~;P>Nc10*D0|Jxss< zFi1)Q<$$6LU}rIc*dU*QNFV}+9T))>0|XG`SD?F)5CbX~O$rDA0t^5@iDe$xIAIn5 O0000N_~0!B1ZtR02zJmAl3i>|Nr}+@!x-t zvcLa8?7#n*fB$3p|L;$z$Rx)9zm`4EX`B2HAb?mPX21FhQ~^@@2dMNf!=L~E|NQ+A zWdHd6KUK1c=hsc9f8Rnyezh^=0R#{e(Ek5GMIci_s{j0D`2GL?@4p}ozrlKzzsUIh zhw0@n(cNzYfer%*AeP_1{{8vS`0Fp&84w#lmi+$#)ARI~X!Y&+KyeWsW`<9n00M~d z^G^m==F0#79{mS71ZX;t`~_q%fY`tPf!Mzw;*3o4FJA8j2p|?NkT1UdXZrG=;TOYy zh@M|qNhT&CJ~jq`0Ac}pl#vl6#K7 zFA)9u_3syi0VMzY2QmHtx&Qtu@&7&0&HxaAAvs6^7=(cU7?W7&6Z-$piRe`dyDK`^ zN$WO$zWL=wEu!PO?Vu9@iVSM&8cWvf2p~p=WCn&G3_$lI&>tl77dYY}Tp)vm0U*Et X__=7oxWDB`00000NkvXXu0mjfV`BRN literal 0 HcmV?d00001 diff --git a/src/Icons/flags/sa.png b/src/Icons/flags/sa.png new file mode 100755 index 0000000000000000000000000000000000000000..b4641c7e8b0dd79aafaa73babdb525d3d2dc6a8e GIT binary patch literal 551 zcmV+?0@(eDP)4!1u&@QJ10&`rk^HbMk8Ee|uIe&H zS+;4$DbWCt7$DsBz5oJg0IGiW@flDZ69W^F_wDDmUw?kFvatRB^XvPsAO9KtfBpI8 z%a6}8Lb5=`00G1TbjJVx|9}4ZVWnuJEUfzZ$EVZx<$*voWzTGcp~$d(=+V{_?X+ z3y#kPS_RYq5I`UeU<=TsD9Bk~@o?qi&=DPd(?v86a{(`&&3I*E&g8|Wo?Sn;v*0j086Wc~d66UYT>00&^E24DBZ$$%)DV9SRUYEY{Wn z85tspN%!Z^Q&_X+!-^Gee*b1;`1hkUW~HJ2(d(c7|`w2)m##KhU^#|s1eh2YzMVW-Z(;)C{QJl7?-Rp6DTaSP8U8UK5I_L2Ffe?nu66~hU^Xzg zV`^IR|NmbGhChsd{xGln!xZ`Z|DQkqe?!SHn>GOi5KsdU{eSZ0I}_6%bMu4$|G#2j z_zP0e_xu0e-~WI8{{Q>e|6jj=B8;-KKpOx8hy`TyKZd`5nT(9?%F2RO|M~TQ@}K{E zz)C@?e?v4d{QeEp01!YxcLP=bXJGj0<#nFn|DXSVfvSK1-v%}nhwkOu|GvKejg0<-0ptJwK&1cy1oE`H<`Z?5M+~$7{9gq& zn~(3mv&(;P@Bi|05T(EW{(k!9>4UEid{_Ab1OPDr&i@1e0Q5gX)c>UW0I2)_6d3&w~i*%}NQ0G05Jg0{{#gAwk6j%|K36Wcrx-Z zDBuV5-R-~I;@8;l*yr}=_xShx{`~y_{Td7!{r>#`1^@zxvDKIVAJ?B1c2ZXvZZlkB uU;qZ}2Vg*eW0eWa_yywvNgf7(00RJ0?>)A@UfIF`0000`tbb&P~tyW8d(D~GxMiUp8x`gh2bB=pZ|ZjUUI!&{yK1G;4d%$ zIuA;MS%3cg{`2Rrii*m`ix&X`h=t(`1IH^)u0vdsLXv;@{sQG7;18Jf2Mqqg05F6A i0*HaZmVqPy5MTgGElxU<64PS<0000a|fPuet^$h(7pHv_{jfB<3vn*8q{15ov!pR5qo|Ns4BVf^v!57RHO zo?l?}`yWs<(7C?=0*LYNK?X*pGKOD3v;Q#s|MUOfZxH$qCjb2cBQWFtZ$@_cPkRpn z1P}|u9|n-AAQdnT|9?TXAyk7H4FCQBl>h_~&`AvcLF)bhMS(&{8jwh^2qVzve;5D) zh>=0RIIAq+{+o}$pxEl(3%2T)`P!1-fBt~{@Pp~sA7J?W`}60ovKZgl)=2;X#KQ37 z&mWM7{{H^+4`$e}UqIEMAo>Rk|KALM|1kdh!vsX^3=B^I0*D0|DL|!?{M^6*VPKPH z00z{*-?BnHps)wJ`QKllIe-8D1EGJQNCgNWMh3}bctpOPvlbWzK!=K^+cJPc;};D5 g19O2S13-WQ0NlBGh$rR(5C8xG07*qoM6N<$f_QiWUjP6A literal 0 HcmV?d00001 diff --git a/src/Icons/flags/sg.png b/src/Icons/flags/sg.png new file mode 100755 index 0000000000000000000000000000000000000000..dd34d6121073fffcb2fcb5b9402b3e6361cded35 GIT binary patch literal 468 zcmV;_0W1EAP)dtOYis{Le*Dj#JuDs`KNc)tl9OYUmifJZ zA4uJ=-~WIA`uFP>kj*SB3$z3vfIu4l|NYA>FaP8D^M5;ba1<8<4f|GC2UPm+H&ER# zkRGsxe?Y{*01!YRC;dKnkj2`X)zkCW_8s5b+Wvn23^5y|0jv~A0#!5q{{4%A0U&@_ zfL8pya^=_l{r?#l8F+XY{;)G~as30ko(ZTFY%s&0Ka9WsFiJ`S6$1niy`;Hnv5 zfRT}r0R;fL{~@sn5I`&p|Ni}W_wFAQ`~gBVzyJ~jk&qMs5MThRyiZo6SsHx+0000< KMNUMnLSTY6dB!#X literal 0 HcmV?d00001 diff --git a/src/Icons/flags/sh.png b/src/Icons/flags/sh.png new file mode 100755 index 0000000000000000000000000000000000000000..4b1d2a29107be96413eb86e64a75ac7a3ba5793d GIT binary patch literal 645 zcmYL{Z%9*77>Cd9?woAXO+#E-F%m^1b0Xy*Qky9{B^@hJqB6}jOKKPc70u1CS|Ug( z7>SA^1`5-}4+VvY=3G*k2%(8O!OWTIn!4?td(P>GANugV4?p-l@2B^fCONIbD;IAODX_{rV|BCn_NC>%qlWoHrzH=l|0Y^Rhgkwr%>N3 z(d)FjlCqjgyY4&yRH!;rb)|Z-v~HjxIkvar`*JLyzxBc-B?Ix`3*qGz4q3JAd`#LY+Xw^k(ph!n`d2H7`aI`Eh(LrOLs%9g zj93;8ws%s88WHkIqXqnSf?YSjh=@dF-}4L7dS0HFB@iNj8OY*&4>%Dn8t&*i)aXz6 zSX_wQ?~e=9UcwhrAtAf8XLVoTbE5+<^|-KK=D&>)yX6u!zrPCrbEr|4Yi(XyIGTQI zFEDsraAY{)DhUd*DN;Q?!uSxvkoT|31dF#>2L0DGeRcNZNehm>xm~}-9q?gtV@Qz` zv-lB19|m}3LHcg92}TUOb+%v(0bnUhB(5rQI9?ZY)h~Hw=%2Au&~WB@t;^kVE@F0Y z%=8f1ZN}R1MniiNxkJ!a;3!XFerfimE2A;1XJChGXJ=)MAVRubE8WFo1T(1Cmhdfa ztzC{Qms6asjkstFkFp5L#maeek84Y+NtW^Wf=SRytjpC1=BCX4NH^VxnQ`+YXocAv zR?lKskkKZN7D>{S3>4;4+gPYYq0_5iq@jsB^}M0yMT0|p`lM;R_dwbVrBg^4RRbsq Y$WB%-43-yHbAJTXS^1gPjGK@C0`m$%7XSbN literal 0 HcmV?d00001 diff --git a/src/Icons/flags/si.png b/src/Icons/flags/si.png new file mode 100755 index 0000000000000000000000000000000000000000..bb1476ff5fe8e0d3af4fc6bd11e513d95fd9cccd GIT binary patch literal 510 zcmVm9@#;PEzrU@Gx(rNA|FHo^Mn<3|00G3vEO>ZAhtlWIf1*N!=PZ8p<;&lH z{~7-L`S<7dzu$lU0~x=8==VP$LqeQ==EOq)0mSn6{g=m2e$<)X`O9Zpu5&$Np~P9Kn=gZ0kf<1I-4a zUtk1c`~{K>fBu3(0U&^Y8d(1RW7^4V^6LZG89>!QBmXe{`pfY9FT=0Dj8O6)!|#7g zK*az7#L~(TO=a{vExMP2%`MCSoB^FIcLe_%lf;|~%E5I`(IQNh}3Ao>6Q|DFUXMn*>AqQd`w z|1kXd^B;tM|Njjl{{hM0zwd6?1Q0+hV1xeud-4=Wy?p-%sO`^#2S61Jzk!N?s)6X& zzhA%p|N6}=D+{y%Ab`Lc{sL9~1=0UN4*CD*7s%9KAf+JHKs~=eB-8KTKvw|-5R1&; zzd&a|ob(5%^Z$Q=wHy9p13+aOpFRNu5F>N&`Tk_-7w>=n{RejQzkfh&Kn{rf10?_b z{tFTZibx5v&dxav5I~H7|Ney-|DWN1$%1FyagzUW0464;_wU~W1Q5$TW@eGxtUvee z3vAf*8|igK9~@*rr66bh|NrkNM8z+V zAV?>O@ek;bKfu6d002F*|Nr~{=Pyu%qcHbB24G}l{PX7zKmY(S0M7peLS*D^UKK~y z+6(XH|9gD^r>6bY*OZ>+`2GX^{Qmv@{`~#_{QUm>{r(dW1b1xK0st`p&i@3&%J4-( z6Giy=|7vRh4-WrbUHx`??d0*<@CX3>{QLa=`~Cm?`~Ld;{u~zu0R89!i0SVi2B1U! z{r&fU#+3gbKmA|6l!@v8=U+^J{{8>`mjUR&KfnL~{sUtC1qTg400I5L26X!4i0my} zo;{uZo#CfPX{7DT1DwDAf(-fnkMZ|^ra%9I0mS$d6bftr0mQhUfkCOfiE zM%HqlKU{maemr>kAILSo!3gZ8-+$N@WcKe}3J^dnRtyZx@9+FOdynDWy$P0%j62V; zZC)?>`}hA}zy1SB2;@n0006p>>h67sJD!pI8@uK6+#GPW%ce@CEFZM znTD)%K!F4J_qpc@AQp(ZPk%rA2T{TB=kLG2fBygZ4O9eD_xsnsUl6u5yEM=SfB<5# z6|+@gR}o|u1R4pn+XF1YrQf2oylS zAbS3(sBkhcTmc9mV6grHN=r(zLW3F{=D&YK84x>x_WT70A}|U80*H};VI?9O(a}F7 e1_Utx1Q-B;QgQb4eH!Wj0000PEol7!5I{@}e;EG$`~Mq){{FvoV+so& z6Zek;JYV*``O13q$!wq?2!V|I&+z9TKmf4-@!$W9Km&lr1Ie!(IeUNcyZo#F`{&0p z?&{CqnEw9%50U)~((nf$fIu4l{AK07*qoM6N<$g2hARp#T5? literal 0 HcmV?d00001 diff --git a/src/Icons/flags/sn.png b/src/Icons/flags/sn.png new file mode 100755 index 0000000000000000000000000000000000000000..eabb71db4e8275a5bfb7b1b8f3a8374d50da95db GIT binary patch literal 532 zcmV+v0_**WP)6{xSen|M~Ox&!2yPfTn)={d@hr-#`EU4p90fz>J~+=oo+i0%`d3@9*!wzk#ZO z2WQUEDXOGe*gO;$t?-?1~^z5 zels!xNuY7SApXOk^arFAjDSu82p~p=WCoxfknArIdOZOgs+`19}IpFa%0{xSUi1L7diFBr+f01$veIX40Tgn<}np4MoMn3N`o$god9 zrkzn;+j{#q5F}xeh49xZuI$05IKi0v3Lq917Le*!UxBJYN`Vr8|1$jj50VD5fvSOw z-(ZF~46zx($8#~-kUKOh9u19TNY0I~dG z`1hBA5y<}g_y4cI3}({*g*gAq^Z#dL_#dnH|JmpNJMaAe2etv|3x;0|00G4G>kr86 zzYquf`+xk=e@^EAQat}9xc>97{@;He<|?3qzo3u+2q2a}APrzwf*tnl_y6c6m z5?7266~G|=0}2mdsDK;{bP_-SF*1~XW%vY(NDyK`u#uw~6h{mUJPZH<1^~BhckWKq{Jk|L6Yw|Nrm*vcLXk{sL#*k)f0!)jRF?KX6FHLLC_7zyJOQ#RJf}AnqSv4E_E0 z_d>^cfB<4-C}v>z1dGUDNRj#r9OZBkNc8hC00bBS^Nnc?6(4BA00000NkvXXu0mjf DM=x{`~^7feaw| z@9%GBrr%pd7ytr@3Fu&;D>$G0;d%9&ckUlP_FsJLznOpkI<);49~%fU|NOOg<1c>p zU%YI;<@gu?0tjRS1JJ?0e*b^_hvDg;|Nnpg`SWY#%HJzjff!!CzZWj}wP?w&U%!5b zMg95nhXEjfKpOu4{R2W=zZm2}8km@V1qJfIu3a z^ZvQT`ny}__wU`%Fad@Sg!~P3A(#OSI%WR9r+OFw0*K`e1H&7RKZ`vj#ee<&!}=E_ z2M*0Ye}N7Llfc;c2aF@2)L(`#3;+SdxR!w-xR`AxVx?>``QKoX4p z{r>$=Qj`^FFF*h>?mzuiS(feBuYdplGyMPm{~rVab^il$89+1;fd$yvm=2wM1rR`t zfB*hvWMl+7=|4yZ16bGpcem@l{$rO?srZisfXY67`UDU_ED+y9gdmKw*T0{<`x@v9 zlkZkl}Tegi}1FC>)y z`~`;fe+5al?K4jS1P}|@5C%z67NEr6KmWj?{{J^f1u*QH|Ne!BH7L;kfnp0FfEXE= rk23safJY>Z`~zeELt=n*00bBSq*!cC{}>3t00000NkvXXu0mjfg_GrH literal 0 HcmV?d00001 diff --git a/src/Icons/flags/sy.png b/src/Icons/flags/sy.png new file mode 100755 index 0000000000000000000000000000000000000000..f5ce30dcb79b443ebc1615fe4889cc26e2d762b1 GIT binary patch literal 422 zcmV;X0a^ZuP)@|4`Xj5kLT%`al?B=W5I`)SK7Qoo3V-qKd5l^# zgv$taFhBq?zJ2?apPwJU>mjm?jEr~g+yMw6Mj$IKE$!aDd%wZp7Z^YoAQH^_^XK=U zKYvwJR4!h;2oOM^VEz63kEEm|Pzoptl!JgjVAdZn_zMF-#Q*_BG6D!N0MDLEDh$KY Qwg3PC07*qoM6N<$f z|Nj36M1Mf!|33`>e*gaqWCO|HKwFtO#a&sZ0t5gt0M7pel4t!zdFAutyc%F2ByLSib7d z-@iY8{9s{WsjaVha_-{UlG^LGvEO)A^**!$6$1ni3ljqaFhGRYPy6$qf&JG{kKey{ z|N8ae_ixs}{}``bdDhkT?#VOp#VvoBm>H#|fo1~)5aY*A1~#Xrf1jTKgW~`H-wePI z{Ri~aZw6pM{r$!84-_k)u=@Ltg1)Cf2{xiF#iKZ95W~`fDE7~ z|1pDN1{?_>vH!pR*Zxoe2p~qo;+=0k{eVOy5dHe~@Bg1a48OqWACLsaJOfY!7)!uZ dz{3I%U;rfUVNTmRI(Yy9002ovPDHLkV1m_xKPvzL literal 0 HcmV?d00001 diff --git a/src/Icons/flags/tc.png b/src/Icons/flags/tc.png new file mode 100755 index 0000000000000000000000000000000000000000..8fc1156bec3389e54d3c5bb8339901773a881e68 GIT binary patch literal 624 zcmV-$0+0QPP)Mt z2Fbqp@bUfi_XiXZ_x%As_WHU2H1hfc9TM^w3-JC0{^0Bg`~MgK0Qv%mWs{6kqN+Cc z+b3Uc-enXLWmi^s_2~6APR{Qy8GilxQ)j#p({t5y7`^LQ4&lw9Z0Ra5^`SSP!?%<&3?fU!$2L%N9{QCa@0Qv%mW$D2m zA^~iFet$Uihac>@UpF6ozx?O#ufL4HfBpRUndtzp5U;>@#TUPR{|1KG4}bt-0)`aO z`@jDF|MM3p^6S^{zdwKf{q+mXVfa4fgq7?27ZxvH%|34Sm*EEk!#{ukVgYLS^A{)$ z3^fq>3urc&4I=;kz4MwgW4X`2zkh%J`Om=vauPrQ0X6*k{pY`=2p7%A_P)?P zUwuVdAkKe=-@h3}_C6p$AOxEwQo+UIeHT5%mg3lYGL;@HP(LjqG0$?6F}(Ht8A z0K*^*BsuTDFa|;zm9Mc;PRcq|KMMBO%8|{GkrU*a2x&r-3HS3`xnqW1|R~39RolBu`vAj19S<{HjoWK z4L}tj8-Qm20eTwfuYbROLyY(bwgDi3SQvf*HG+%>>H*pSauQI_zkmNAP67ugNCPlf z{{97O00g6G8FFbZ~XHln?_bqJeH^V)*lb;YTJ&0)m(r7ytqc06HRil3NF`RsaA107*qo IM6N<$g5!7R+W-In literal 0 HcmV?d00001 diff --git a/src/Icons/flags/tf.png b/src/Icons/flags/tf.png new file mode 100755 index 0000000000000000000000000000000000000000..80529a4361941e01d1def5d581bf2847cf99fef6 GIT binary patch literal 527 zcmV+q0`UEbP)KfiwinSYl|od6I(APxT+{=azr6>87_{|pZw{QvzM zh#vfW|M&NwU%!FG-`~IfN=xzq?EwhD!Wi2C0Dv&)|Bp?Zs+hPi0R-LQn75%cY-O8s zAPsw;Q!9X27=Hcx_y6DDzyCn0!4P6RP{Xg^fBpb%_yyDhbQs7f8-Qku33L4cS@IvK z8OZ(n2kOgTzyGb@ek0IRW9ouaN6$P0x*s5bfH4)06qlIj4>;1{Yyp4(0|4dQTo>gF RMrQy3002ovPDHLkV1fdR=hFZH literal 0 HcmV?d00001 diff --git a/src/Icons/flags/tg.png b/src/Icons/flags/tg.png new file mode 100755 index 0000000000000000000000000000000000000000..3aa00ad4dface0a9c23744ab451cec0443f187bf GIT binary patch literal 562 zcmV-20?qx2P)@|6mN}b_RwI3=Dr@=ogG+VE_mq7La^(HIVqv%*^=nCj$%1|9}7Uoj(8m`RC6+ zAo~61@1NiQe*Xrt|Nh=Ea}z)Sfi-Y&{FjhmFg0aZxaj}$=L~=U)(L)O`TP6-zu*7= z1Ib@N^zYwqCU)6YF9v`BVgi}{>lcH)J%gU!|J)p)>i@rg^Kt&>WCWsLoQyxgk29dnvBpN5vQb0*LYVQ3gi&tp7jnGyMMp z@*mKbe}4Uk_!#8f-w;8De}5R+mEP<>2M|CkH{LKvi2wQh{WmZi827ytqc0C8?ZF&p#S!~g&Q07*qoM6N<$g49|K A6951J literal 0 HcmV?d00001 diff --git a/src/Icons/flags/th.png b/src/Icons/flags/th.png new file mode 100755 index 0000000000000000000000000000000000000000..dd8ba91719ba641502bc7ffda16c25dc71b2066c GIT binary patch literal 452 zcmV;#0XzPQP)@|4`Xj5kLTn#2^O%5QJf({+!S7KyMr1NSdb0?wsyYS6cNVdko7wub89?$EL;)x)00Ic8;m6; z*ldXL$Yz5{poPB}7`^}m5DPc2nu@9r4=+1782$pC1a=$HjDKJ@i17#P6G=(#Q>V-T z0*LYF&!5c9%>VxV!xcCX0F(uW(%ZLh0Ro8SA3Hl!NeKhQjeq|#{05SL7=Ql;MhF4{ ujRQ&nZP~jQAb=RZqDCa1IEDa#00RK>mSUL#9?hx%0000(5Af|u+{y|g&!S9Ft%(8imf-XR*|Ns8{XO&`< ztN44b9;zJZ^?&~W0*LYB$B#TbJpUo){|D*(`>^x>w|gKB?9z<#wQ%E^n3(S0zYh>V zEO6uD3`W^f29Wmu3`mZF`w$?27#UO<(rVJ~y}I}N&+p%VfB*XP3y6U1Uw^?QNbuL6 zzrX+d{i`Cbal7Zfib@b53s27mx! mU=U|u;Adc9XCM*)1Q-C-v^a{iiydVE0000+lNu{Qmp=|FW6D0*D1<1Ovm9m%kYQ|7p*Yo3ikU z7~kiESLFZv{{Q#iA0zqwf4<*Xu-*CD8$MYncA&8U0mQ`ckKy0n|9}7f|MB&2MbDkQ z1j{KKBL!IA2(Z7F;(zkuBe#mo9TT;SzkoLU{s(jwKmai@{QdX$=kGt?etVi7(p9*e z(|o73K&5wiaQBkXEB9so{`tH8jIplb^d$ZPi5h|uLD4*o5RnOS|{Qd{@Cr~j!0D)}y0}8T#$FHit{lE#dc*g~k_utsL zxj&Wpto`+k?f2h5mv;mM4gK>M6!-uE1hnA~P_?8O+wWh(`!4wX{Cn2j=z=is`~Uxb zzx=@K_DcEUJ7IZAUZAu8{sn~+Kmai^Fsw$4O9qB73=GeJhA}V*Ffg!yW&gnt6F`6g Y0QOrYft$MNbN~PV07*qoM6N<$f;FEW z@b~ZkKS1)&|37~i{`~p>`}cn&^2?@800G1T)Nta$zvt>t<757@uK4@^{4bCmpb7~3 z1tfp{|Md&VW|Wov$G`v(Kp+kO{{26+>+jbuf7A2+upj>Wf7$Q%RxoV1$N0e}Fas1Q1BW)@@rKJa|xATBWA`D>(WW1JFHv zzy7cP0k+{MTm!^O009K@!>LoJmn~avX#S_9;5YZ-KmTX``u`YaHjD&?*dJiPF#rS* zNW;&cKP?=87yABYZ~OCq-%n(9P{tpi22h9t6$1niNQ1e-pD1xDrvBdy@BT2zfI@>2 zY$OAO1fsuxAqeOsfB<52Wnfst00RHO2+qJn5C9Nh04p0wT74^6IRF3v07*qoM6N<$ Ef~oTCkN^Mx literal 0 HcmV?d00001 diff --git a/src/Icons/flags/tm.png b/src/Icons/flags/tm.png new file mode 100755 index 0000000000000000000000000000000000000000..828020ecd0f6fc73348373c9e7a235fdced09de7 GIT binary patch literal 593 zcmV-X0VKiqu&g@GZ_kb&V31Gky(*8`UselaloV1SZ886W^4001!n&i@1e004Y* zk0R&!|NaLC5DIk$@CyeC@AU9ebDYiJ)zswL{Qdm<{`>p<{rmm%TMiuO{1voVt6d+$)WVk%^O){nwx0zkdJv^%rQ#Z=eQ%0Ac}Z`19}Y zkI%oqe*ekA`2WvehFzDBOo*xZ{rB(cQ`_&qdGhP`Z=jyvAOx}jAb?nae){+CFDvWc zZ(siLa{c@D=g;LQw^HX+sY@u`d-M3!$G1SGAWQ!Ifj9{ufLMTG0<_`#=U?|Ye)D|< z8pH7G?=PVA*@stt1I-4xpA0e#40jk9 f${7d%fB*vk3(!F(w2U8u00000NkvXXu0mjf+94t7 literal 0 HcmV?d00001 diff --git a/src/Icons/flags/tn.png b/src/Icons/flags/tn.png new file mode 100755 index 0000000000000000000000000000000000000000..183cdd3dc98c6957bde83f375a431e543a3ce9e4 GIT binary patch literal 495 zcmV@|4`Xj5kLT%gT|L_r@28Q3iff@h;hzaCwplYy<4FCT9KXmB7 zhQ|Nt)Bg(#gN*m^{Qvt8$Of<_K(zn?!~}BDpT8hi0uj&>pxItt|NHv>A2{&e(C|Mm zFGw7s;m;qS=>P!)((wQ9AF!W(0sZ}7M&|#9_5TYB{zpfHZ20g2t^wjCfB*tH2_nSs z8?4R7=Kq6S{f9wP5^T(0hI#XVIvK%6GC)WrB}fdh6SO{nUiXv3iAlW}aH!uJM5J&?vILH{_iZHeP0c!XQ3PuJ7 zfB*t%VEX-sK~fTI%wL8-Af1e0BN-qh5dHlNK|sX-0mS$fH6j^sMDRaYQUC}r0RA0L U-~OCsp8x;=07*qoM6N<$f)6&Rz5oCK literal 0 HcmV?d00001 diff --git a/src/Icons/flags/tr.png b/src/Icons/flags/tr.png new file mode 100755 index 0000000000000000000000000000000000000000..be32f77e9910c0896c1ee8e7ed4f0edf815a517e GIT binary patch literal 492 zcmV@|4`Xj5kLT%yy% zCxE~j7#aURc>+`lQtjr(@bBOM9XtMi`UFz<>-YcPzyAOF1!ObI$^vZw2q2J#|6qeb zs-vSBOie-Rl$HN?bb!_U0_g#3VEFwTr~x2=m_Y6Zss`GqsL0^t^nd#F|4B*zH*EO- z_3QuT%m4H6g6)A?0#pkSKujPf{rCwIb#eU5`( z{s2t}2q2J#|9}60{Pg58FvR|AYlEDjruP5RC6KEgJ^H_IA4CJhNdN)F0>q49OBog~ z{?Etvzo-c07$As@{Qu?4|3!FoS~(Xu$ujuK&Ki|5;f$7pYF;Nfxh(xqFs zZUMDjzjMbfEbRY>5C0Dx`v3aP|JSeozj_5kj66I)?%V+g05Jg0{{w&k0RJ5w0P^!X zSy|WJ-R9=z(aMV97z{4myy=pj4$^bx3|zy{hYtY)h`Ao9!QA5iyLbPuTmkB_PfP?Vee~$j z!-o&gUAyj)n+wu&>J&%=KmU)%j{yP*q=CWA45Z=rFNTYkfO?!$Q_o+&{s0WlT)E;? zRQUhj|NkdWF!J+%fBF<4fS7B68jOwqzkLe|6QI@S&;S4b-#s()-1Y1C!Qjl5tA6F> zpisYc>&x@!00G2Y!@$5~Xb92(47=Z8{{bD%z~Ggi4>bPny?b}>+&OjWQc!g@0~6Et z-Maw-h`Ac5K~JB7o9jOp7XvpB0}lu>-nqlT$mpA&|LpDCZ{NOs`t<42?c44-IbZwx z0Rjj;B7x{N1H(%OhUW|nPgz+XA3Vr_1a9x%4G>@ep<^{rq?UTJ00000NkvXXu0mjf Doa;3l literal 0 HcmV?d00001 diff --git a/src/Icons/flags/tv.png b/src/Icons/flags/tv.png new file mode 100755 index 0000000000000000000000000000000000000000..28274c5fb40e5d3bacd7c05d9a1b8017eeaffa6c GIT binary patch literal 536 zcmV+z0_XjSP)mzpv3Mmw05Sgm{~xFtLc$sUu>nR##!sI<0R#{WMEdpj-yJ7j ze)|0V&%b{_!~X#7`1>EofS_N0|E)GoUH&SsFy}2m05O4F@}ffYb$qvjbfSUipMQUU zgY^9U_4m&&5D8KZ)HC5u^uad<48Q&W1P~L@hOIAb7eDp_T4W)^*Xg48{r4ZBJ-_}k z{QCPJq~Q-pPnz693xQJ%zkUG(5aZwHtqd&u|9`*u&+TyOvq{_Ghd=&6oB?#w{~Yv(xYPgr|NRH*haKioowt*& z{dC`3v>70P7=Ql!$;`|Q@(GT>fdHT^FqGcDeG3pkjNS|k>E&sEfzAeo{ckY&=g(gd z`CCrwmxA8!XLtTy-uM6CzrVnM%iVPzAb=R%ks=j>et^j`MFs;Wh8c4i)_^1XKP)u> a1Q-A&>r+tW$-Nl>0000<~s!0-E7R}a|Ns2?4|9|}gs%Dgx1=;`*KrBFO{{8#+``2Fv2B6@-@8AFY{`(K80jdYk13&NH4;SYnOGgJvc0I@K9VW@Vk1}Xmk4~YK$|NH0P z-@pI<0D+Rop8&DnA}oIvEc_iD{O9-Y-=|4+U?1uFgf@9*z_zyJRJ z%fS3QR^zuR^Y0tyerNXndi(YlP_?gzto2+5fB<3vIsj-gQ0X6_*?&Q*d^>boB3^zoi8Kq^tbl{qlR!{9jwQ|Nij< z=(=A?F~8j-MSe1{Hl8Yc@zaXo%Ljk}VgUvb(2HJbe?0kqy?_3vsPXrUmq2rWE6M!I zE@4*I;Mw}vw&7&iFGdC>zW)rr{s9CK3xfnhrsi*1wqMhx{@J=6sPgxpU%z6)f4fBr zzxpd#a3tyYE8}0lKnA+|-+zWbe*glA<)R0}-=}{Pnt#7~1q_Mb;=;f3i~oshNgsS> zIr~z~(_bRL|NZ|1LO_>;A_pLVSoBpHQd9nLa7ao@{lMMx#__lBLe9Cjx?EiU z71{s)`Oon8FXP|;z>s7BItd_v7-5mj(Adb}701wVj$!S*>kNN{fN~5FV)t0eYh-DxnQ(+0I@JIfmA>F`X8wD?>`2h#NWRRzyE`zA&Pzh5tt#% z!^rUCA3y+sZ1@LM1hf`pHc0ia|NsB|1uKPX0CRu;1-SztfLMSo`wOxir1}rsY$VlC z667idh7Sw?0mQ-}a!Q0#;n&}vAb0=!_Zy@WNd5!6=O2ju7s{65Vq=gx0uVrqe;+b1 z$mIY3|KLBvF9x7j{{!v#g_UGtQhI;<6hHv607H@yECdWlR7EJN!LomVp$!l~APvkQ z4p0cL2#YobhQA>6hXEjfKpL3-19eKmL_s!=;22W8vpXP)6RGKQPvx1q)UK1Q6rb{|u}Q zRsa7#{m<~1f#L7}|GzNK{&HxZVEKJ4>jAefr9{u_M=MTegAo-i2ynN}MJ5kZm z42KRel$J95{>|{~*Z<$Y8RdVo9Ap3pAeIsa2H!t_KmPs=bot-kKnMR0GBy2s>sC=w zQFmwO;@`jj{`v(%zkl=p`BTQg01!Yd{Xp;j{qx|@pI^U!0X_En_iwRd$6{h)tX8f( zaOhC?&!0e%U%!3phy1#1%V=eK#YHXK~n$!{#(ib5I~Gyfqpu4^P)1J@ZrOUii!$=0Ad7ci1(2A^!3kwFaT->5i7Ttz54h6XL$JkA3s3o z=g)t?e>01U3h&zo5I`(I-#Hr#t~u}$WXZu-Kyv1Rm&rE5wcB1YFI@@=0EYkn8G$4- z^Xb{M0Ro8S57@^*QJ}#<$Im$M^4iKw z00a=@`Sa(sw6y;I{R{T)e~6KA2AmBHF`#D(ii!XNh(#nN}rF)(}plRy9vU;su%e@J`J?dSji002ov JPDHLkV1n4Y8}|SJ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/us.png b/src/Icons/flags/us.png new file mode 100755 index 0000000000000000000000000000000000000000..10f451fe85c41c6c9a06d543a57114ae2f87ecc1 GIT binary patch literal 609 zcmV-n0-pVeP){qW|y?pud`Sa)3|NY&vWd%S0u>b>P!2!lUe;6EF*#G_c zFVXVt@6Q{uX@40W{p0iY2Aa+A^Cu7i8KT+YH}2j52q4BskM2rJ$^k9;2Xxc_|Np=M z&VaLlA*IO5FlECMfB<5VUNC{tBZO(|zW*;@GJN;|bTJ71`0*d;`d`2P!x=ymOA`2> z+y@9C##^^8%gd{MW@Y91_2d742B2~OQNf=-zkmD?Vqkdk_wPTUNeuu2#KPTG{_;O4 v7C%8E5*DLB7#Kb?Fnj}}-(W6879hX?8lYRg`Y`<~00000NkvXXu0mjfD6Jtx literal 0 HcmV?d00001 diff --git a/src/Icons/flags/uy.png b/src/Icons/flags/uy.png new file mode 100755 index 0000000000000000000000000000000000000000..31d948a067fe02d067a8c2e69f28cca446bc7c57 GIT binary patch literal 532 zcmV+v0_**WP)_vmzq~N}&z08z z0*LYY{pZr+B0$d}2MCnI@DC;m3N;oM#uMkR0R#{ugY)L9Y<*xj0QCR^`!^)W!R$Za z5CobHbl5+T3;%B|S`QFFjQ1Zt|MTw;G#Vi+hCg5i(ELAtfD|ak8UBG;ObiSF0R{lf Wla#5zB1?M!0000JMe1P}`Y1HZufM;3|NZsr4^XwNEI-g5fB<4iWtjhPj`qjL zFGT_P{{Q>;-(R370Ro7T!5$Ws$Po%5A+Zb!3j_cNFaSC{Z(fWD@s$7o002ovPDHLk FV1jsy^u+)G literal 0 HcmV?d00001 diff --git a/src/Icons/flags/va.png b/src/Icons/flags/va.png new file mode 100755 index 0000000000000000000000000000000000000000..b31eaf225d6fd770e0557c2baf8747c91ce88983 GIT binary patch literal 553 zcmV+^0@nSBP)|05Jg_ z#sD@3Z1&&(|Ni{{_Zx)%v%Gr!NnLzkb;C z@#QWhJ{xI9$+*)bNX$S?E90e{K^EMkYok78VXhR-hjM0*K`g z$j^Tmm_>oEVgxdn{xJOg$-v0L$jHRN$OsH@P9Y&+^ne@=1^@xXcy~X;zaPM$WdOPj ri2i^{AeYDB@IM9-1r;P))4B5XW#s0WPsWLbObPT z00IbN14#96puqp%TKvBf)PA*{`~CO-uM~~n%6z|m{re4Z55!3T0R+GV5`UO(`=kK4te?c|?1P~}#f$jmC10=!0@{8gBFK@Zu z-~WJALqveC|MTzfA7GIDVE_mqkOrW8BqZ2?K4D^#WMJTBVE7%b47BbKBg1c?EHl#| zW&XdQF#ikE01!Zo3=CVrargu%_x5NZPzVyc@Ms2-@*Gr#1lu5DU{kh6%sopXB}uDxAo`@Bt_a*7F+) z{Q{%kjEu5C8vp``Wse8Lf5q7h438n|z~nEOsZga5l7ZnjPy;{!05Jg0{{a91!FF~d z;^O)I`~dv>{`>s@o}L{E2?GEB|Mm6!N=n`P`~Ld+{`>p?A0G$7!M*~B3FM_eAU;q6 zNCH*w+4I@c^Ny?Q?QPpWZQiU1R1HBuWkA0H1P}`l|NYDG=gP=Ihyj(0CItil0R{kn^jdV2 S*Eqib00003_-&c2+@O*Bba;fM%rBo$$qwJnuekcf#0k*RG7MM`2+5Y7dK4k?R% z*@ue~6f;u_A~T0evP6qS=VxXnGS_mt>CSmS&gmG`kLSL)e_Vf_=c&!fKB7`4C;*C(7s2O*P zOs1$U0urzb3<=a`d9ABG4Q$eK<6~5Cg~V%B8`UqrfRSN8f&?QTVICs^VT=&p*?Eut zt4Ur&-BL_ON(Z|Xfgo93lf|gRkT$Mz-7^OQoD^XMF@}g>R?uoU0094KbXv)l?aF0E zh@GXQVr04m@05R(Rjxq*p|CCIRfv;QJmH1kf!hsqX*sha?_l;f%e5i5I~4YG#H4;6sPG2&U~bv( zNr`eMXGIX9?wP^zPQP(6+&$05Jg0{{;N}{t6CR|M}we`P%>f+X)5&j)Fc04NUj< zI`HZ2Woe@k6UF22`V|Qe2MTi(6bb?WF#yj00*Hv<{QLmnFd+P z9@fS%;@9^E|H1b5`Vk8^2@Yw;#}(}C_yUN9iGkt%y>Cxm>T2lO13mifZBc!n`jhHL z!MK>$6Z_d%|GfHMapIVnqod%T-`{|q1_&S~IR%b4Z+;63vi@iI?>jBz=eJjkjQ{>J z{QUQa@gMhBW_GSe5B=V~`@+h~@c%z3lmG&V@$K8U{QUg?|NjRX|KX9x@@rf{MxIY^ z?fG>3gQ&3ruaE-Yw>fW_PfAH~0~Or8dmA8tSRg?T(ZDLQOiOw%6RWM9%$i>kkAMHu z-oH0qLBYb*loP0ck&zJ?LI42-(g0BnBsn<*tTlsx%zxbLe*S!R<%*E3>|Z7(9Y#iG zpdch>0Ro8e`Sa&!arp;m4%k`<1H=Xjf<=G;Aix0Vb{`Xo7A9K&0000@|4`Xj5kLT%B_22*h{r-RE_y1qN|Ns8=|JN^|IHRmA&<212VgZ}|A4N4# z+WpUe-rxU^{Q|504bi~x`!`SnKmf4-F(Xhl(8fQ1fG+vp^85d{-~aW0|NsB{f9tRR zg1`PJA~XO^2M8drlm7gLxRT-bpa1p0|1bLmQVm3Azy5pw{{IQ;B%q-{(*XjA3FM@| zf53hMJK)W)|CK-uK=ku}!>|93eu7kk5yVLV0R(o^Z;+)RSAk6exg_KF|98LtFaPy_ z#c#OrKtum9FaQJ)NCPuC$bbfbRI>n`@$3IHusZAC|2cmD|MKhqAD{+Mr~sV<5I`Ue zOuzpyNJ@f@0s0=KlTj9AB*>SXe;D}wK*A7+fQkVEi190GMB<5K2mlB$03I1qT8uIj Q5C8xG07*qoM6N<$f}XY6qW}N^ literal 0 HcmV?d00001 diff --git a/src/Icons/flags/vu.png b/src/Icons/flags/vu.png new file mode 100755 index 0000000000000000000000000000000000000000..b3397bc63d718b344e604266259134e653925c9d GIT binary patch literal 604 zcmV-i0;BzjP)7(YpZ_rO%ce~L0mQ<@*ghnz= zZvXM=_iyVze?clB=ogUu_5ar|Ae&KE_8$WSKmaiTHT?Vg|MaE5OE>+VAUAUr;?j4FCZIvLVX%uQ>mocOU*NTK^}%njy93_oP3+fBpUa=kKpye|`ZO zzyE?r`Mc+5Xcyo_v6>E-#|Nl{r(LkAS94bRQz)6 z1Oq?-fi&zp{`>yDUnV+0)eJF{zWfaN_0t9DjNiZhfxY|}ME?2z=O_CghC>Vh0R+`!~0W%8&aG{{H+4 zRPp!M??1nPG5q=k)Wabw3seITKp+kO{xLwc{r>&$?_UrCGJgGL;^k4Qujka#`tk7L zjnovNAkb9+0R(gvNCCu>f4~1QF);xde}DY=^Xr#I=|`5hhp|NZyp>({@(egUPqbabS$v+tIbNu;L>xVSv%=>ggR z5I`*V_U`A@(fj`3!N1?XfHr^}17rYw{OcFcC69Z0BvMmfELgy8V88%&5l9HrLN(5b9xs8l&q^Gm-@&XkD1Q1BW|346ee?wJ+H2_`p`^l3V z+1Wtu|3AMO{`_T8Q2{Cj2q2bUARGR$NlJo(=nv2bFrDDw2U!bb{QV0-KNuJQ0*G-b s1H(6@xcrC2{sj~H2V-zBFaQJ?0G2^Lae{Q+uK)l507*qoM6N<$f;6K8u>b%7 literal 0 HcmV?d00001 diff --git a/src/Icons/flags/ws.png b/src/Icons/flags/ws.png new file mode 100755 index 0000000000000000000000000000000000000000..c16950802ea95b40a4e024be6cce870b1991f40e GIT binary patch literal 476 zcmV<20VDp2P)>E69JA<-5ee*C|6>(%ey48MQ<`3*E1sOaY}WDP*a00a=wNxxYB{9yb2 zOU?HFZD2h;3gJl2w`NO~f5I`Ue%-|qnfGfh(_6MlpFT>xzKtBKk z5J&^l?>`KZl3-*0GW-GQWCR<@03m_s?_UT4Dh3E3#;>Rm$$$~H$WlN65MTgr(_Ikn S3@&c~00004%P)h=Z!r1m*T3JtfNUmdS)dI70mLHE z+xy?%p5eHez0mS(A>sL-rPOy{yGk_s3 zz{tq>=+Ps90Al&~?;k`pNCN|I|RMxbJV00L=%3E(v!XamT}{{RArWx|9$7Z{pWi2U{IKN}lRCnF;x&=P&!(V3Rv&T;|GP6K500a;d#1A^U zy8js%fB*jT=jRXRU*A|5K#2L*r(ZvQ{P_O!=da%umKG4l0|XG%NkAKznV4BvSbj4y zawHV~fBoj~uiyXJSQwZYIoR0QIXM3O{tc7`Dgy{0# literal 0 HcmV?d00001 diff --git a/src/Icons/flags/za.png b/src/Icons/flags/za.png new file mode 100755 index 0000000000000000000000000000000000000000..57c58e2119f402072640ca758657798b621f3fb1 GIT binary patch literal 642 zcmV-|0)737P)Cfuwe;F7c=r;qyPX>nX3=Cfx7(O#Fd}LsF&%p4OfdL?Z7#j~W z{9>KL@b8bfkaUokt?1q(EJu$q{Qdp^&mV?AfBydlG2rBvO`8A$h{fmzgIW0J+B07s zK74uV#pQB`MAdI!SdN|k|KJ`--LK#OfB*Xb>lcvCC@cGqfdL=@05Jg0{{a910Lj6A zAt&mC*9zzO1pWQ@b1`Tn1`iV6=KuBe|Nj2}{{8>`{{Q~|0SOB6tE&PCq@k>=Oh@B| zgDu0v2b@p;u)h2C^Y4EK4rY$O|Ni{`3qc?^$?%A8m^2X}fLMSU{`~p7aqHLD@0rW| zzIWc|c>Ry-$DePXKfn0(_xG>AzksTL{re5n#{Tyw!wUw000L?F`}dEV6O*(3zu6Di z9{gne@#pKG|NpqSh1vf81DXBz&mW+Me}8zmL>PD&00Ic4!QY)xLzl7RCikV!EWdtz zoorLj&BXoYF88-DfB*gk`{Eza7yo#;S!C4G00M|*elvr*8B6X-zBgb0FtGkEHc8mM zoOScs_b*;Q0~!ksq<=swfJjA!^Ww!_00G4E&x@hvA~zQkvxU59n3VsHd7Nj?ec|R~ zkmuqAx#JHo0{#K*`TG}00$uYDAb=PdGJ(Ek5Vx?d6PS=4{E7kSFNS|$^b5xL14ayB ck_{lh0N_F{UmK66LjV8(07*qoM6N<$f>aVd=Kufz literal 0 HcmV?d00001 diff --git a/src/Icons/flags/zm.png b/src/Icons/flags/zm.png new file mode 100755 index 0000000000000000000000000000000000000000..c25b07beef894408ae11c3be294d6e0eeb28c0bb GIT binary patch literal 500 zcmVLz(k0+Rp#|Nr~{@4x^5fB>iy$Oe)U zA3pkg`SAPSuU~)vaR2(F*|!oPfLI`Azxw(Lr25~#KmY#x{rl(7|GyyW-|wp|{||Bf z=)Cuc_0O*fYWnY`7ytr@1!(pEfB(To0uBE22c#NA{{8#+_rKq)zyAFG`zKdY6euFW z2yzlY0I`6SGJqWbGV%`;{r&ytA5hcp-u`P`AAdOg`t|1D?}h2=^+y>10tjRS&?yMj zfBygt2HEouXg1LCzyJLD1w#LR1MLR}1V8|>0KE@nffPa916Bvu_V4#Epof105yNkw zzknJ50tl=DS->P)FK#X6%e&u3i|I74$@9uP0*YE!se={)r{r~?r68Z&3 zzZn^2KYiK`5I`&p3=IF7JHD>uaSofgtUAf*-w!6nU;qF7`S<(x|35&+uYZ4j|Njjl zS;T)|pU40ZKrEjoRWbQ1@P?oGFzcPCjLiCzcU8ZC{rmejNW<@6e}U*1kPT$~=Kk_~ z83O}A05QHjx|ikdd7h}_|NsB_wl9j+&d<}^`}fbEzkmP!1q4tEL@O#P9zA*#Ab?m{ zv`qe9Isj6Ah@Z*IdsTw}WYHgB8-D!*lmGvK*?)d>i2vThzyJ_HEdLn(@uk-N0|t-& z`$Yv&?#y3UfPVP*`ya#a|BS!>G5-DsFR)1c1&eHCHYDzO7ytqc0P0;>l>h9)WB>pF M07*qoM6N<$g71PE`~Uy| literal 0 HcmV?d00001 diff --git a/src/Icons/loading.png b/src/Icons/loading.png new file mode 100644 index 0000000000000000000000000000000000000000..2b8e5b96b8e80134e0b0b6f39cb77112e2680284 GIT binary patch literal 248 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAd3?%E9GuQzsmUKs7M+SzC{oH>NS%G|^0G|+7 z1__3lGiRoyr5PI=1I4y(-CAUG^cs-GSQ6wH%;50sMjD8dhY#FnK+6#Y%!KTuvJ=mvC%}4hMPWI1&60hS>WTws4>~pAwXbNL!)DW hz&j&1#yfHh3|j=bzkaT%>INFk;OXk;vd$@?2>^BCL-GIs literal 0 HcmV?d00001 diff --git a/src/Icons/magnet.png b/src/Icons/magnet.png new file mode 100644 index 0000000000000000000000000000000000000000..49b06fd20d9c598fd549b07a6d457fad69f953c0 GIT binary patch literal 7199 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

dDgZ|tMj1a?0oBmiRs5UmNje)&>_&{>gD0CdR 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 T5L3!r00000NkvXXu0mjfP)g)I literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/dialog-cancel.png b/src/Icons/oxygen/dialog-cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..6ce79615464a60d0ed1cfb06124bbdf692f822df GIT binary patch literal 2207 zcmV;Q2w?Y#P);pp9WZz{RzCfQS7jw={Mk|eOhS5t%R z@o-N*KX&Wcvj?YodVaGnne00BX)16(hzDVZ5(qq1zU`j6@aEf)+-}T50n4(S;L2*6 zbFTqcagbd6GGi|sGSWT0&t~8UyI}ki8~79WL-2I;woMOJ?brb(bFizzCfnD7kwvD2 z;w5|W0;7jt9L{C3P3NHH#~;_gA0QNxD zkrW@EXarwf9lm9?fV5ynSOz2e|5}(G9NF_E>_7KW2A%??N|s((@r|Y}MK#N@|DglV zPmVFx(n6}Mr%yMn!v#2=flCHxeuyY=qZ_s>#YK0PY`EDST)Q3+jtR*n7(H}IOC^SP zHo=i44Qv7)fnU|$x9vNnYd^mLpFG>n@M~`jXEgnX$6)_+P~bY+31Ta3FLTQ;mEX5r z@|0CM25?Nk&|mgXPtT-p{ucByFPW?KINVXTX2sJLo3{v~pkwMfqbJ`a(cJd$xMAM) z7__|y221F>uqxrv@Q{5KZega88Lu-sve@-=NbwHs8w+d&q7_ucMb$oZ0{Wf|}8 z%U*)tx3aWapLn9a!iG!n?wB<&j<^Dyhf9`Dvage&3-RYudHr|Ukpz07z|7z<#cS6{ z3VdO~z%5XtM2llu)^H4Dr$?BbRo{36CYCJwV~^FB)x}zjcaB#Z7cM(sY2JWKhT%jP z@y`AOZ^J_w*q@z9qN#bbd>(gM7z;Ko>;VN82Jtf;7=l$Bt$70` zge_S@pWi%%d=3o;uRA5TZmlma4KypACu4MtAkS|$(+;_;g!9RMy58+QbOrtoC;*H> zK36a%F0~!4N~a1arEV-)l$yFF90MAN^h}EUbQgZVA6+;G1lQ>MLaf%t63u0U#N7QU zBq0!PH@IAwJ~thc19Z0c9O{6t{}WW^Wq_pv9?L`mkc5-p_@D(UOsfTz)bM38fUioy zgxEDhW_6JwHLuEy#-yW3^eg2yO=rXDR)LN(Hx~x;FT7*JUjvn^R0LkhE0u}7fdojh zKr^jW9xTVeB=kltkR^d+T6hE)g2qw{rhrGGKIoU5H-tU0(!Ob=Ip@x5r{;9Im-iC6 z!#2FB6;!U#di!$wWDh9~84$8SHR(M+pNDpcSI%l<6{YTSF;PIC)$xVgTeeMUkzyzd z*zk=JZ>%hy#SM7CS!G4y%?gF~c=qtS7ENuSavjOA)9(`K7D#~IfAS7??mZVko5>hQ zrGN_o7`B0EiQ5~3p9YKM=3C0Wv5*aSIpF!Y0Vg4)H2irMkY#}cM6w3qD&^r@D!j4c{wxwWApfA0v-X;1bZqgz58x7EXkbJ5rA0kr|)v^tu{D(-SfaC^aN7+ zs^|?x>jRS-uK7vj^xlS_u&Z;lEB(?Li?5wu0=^S!*9d;QW<}ADZqrQJ7*Wvx?5dqk z>Dffq*m(+umOPSefKaVV9KCC8@r{wr85G092YBrSCxb5DjpzDHs+T`sRbPKx7ot}f zMxi(wjYyWYekyVKUTy5+z3a`ir)nTeHe-+jv`U2&E@5^ja^E}x&wS*ebQ8qNJ<=<8 zH3UCf*PX_bH5?N@Ng&xRNLEKsmo08!p|1o$o{b`;J8z3BpN4y?s_o`aonl(X1)Ox*yBnhu9qYA;eWznM+ z=;)iwjE}1?tMKbf&^7|*f9>J45?mEczCYN{iy hs&A!XI?4Zu{sW}21QM3dqm=*v002ovPDHLkV1g={D=+{6 literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/dialog-information.png b/src/Icons/oxygen/dialog-information.png new file mode 100644 index 0000000000000000000000000000000000000000..ee59e170aec98bd8d0413a12d76ba9779101dd47 GIT binary patch literal 1636 zcmV-q2AlbbP)s3VK~#9!#aCNwR7Dv6=G=C-yWMuNEwlxt5z&f*NJ#`90L4f& z5{VH4JYb9l@e-x-;0t0CjR^^uC^6xZC_WL4;w=&`u{2^Mp%D@;Du|Rjlosjkc6ZNh z#(#PyDa-D53om}jw=+9CbH4Aty4p>bp|Fajt+lNcdZ5@W;) zwZ@1ZF-uGnlf(?s8Ho{N1QAl0Nlbe*WdG&E>n;3BBN zK+Z)^GL4hx`>t0<&CMUZIBTmik|FvdHlV~S)_;9)+P=f*w@kdd_P(hT#)10`eQ6t| zJWE4~m+4?Stx}G^_7_S$QVfMJ8}hoUrwPE zViDlW-G^>8)kNp)S-14)%~{ZJ6WZF^7S@8F4+ z2VnbHLrScm2iWx0Gin;@I-hxb7C1*)*p%|7nlL2JT+1O8vQQ53h>0J6>B8C5-Lu4R z>pJuAgqpv2bZs5g(#LQRf&(IW4E%G=mLVuZ9+<{39C}ke?jPTXv)$(x1GvQiW3%G% zIHk)&DR7_TyEXGr3=7)!LN|4kL#!eqwPqH37Sx%hKG?OT;Clk4kn=c9-H<6FmVO{w z+F;@9@|utlz%WYF$bicW=@ESf7Yt9nw->YD-Bs8V9tQU~TvE-wyz7uS$uR%|cQL}P z8DKd_z!E<4FnCB3L|uL-0l&}y7XXP9f>8)WEfZlAxRK5hZFF5t;l_Xs44n@Q2m*Vo zHJQq0qcIjnpoTzLNE0kD0wUK)tVn7t9pQ)tE{#wS>8y>@7y5CrHwpMIl&C6^mlTBj z3^z-@Z+W1FK#bGe zC+Y?if^{K(7yZSW@OSujv(Qb*Ui0W9D>wT@#{+T<&;e-lVY|p=GWiWEOKMn3T$2kJ z3Jyw`=;Z>ff?KgCw!=;V%pf6IYa=*MxJ=#HK@FU8ci2}Dli~+?C>G@C+Ir`gkwPis)H&UK??1G z!P*wUb%AU$sJ&+9pOZ8zfZjg=AwHE_Mc)V5qD4B+jy;dM3H6B813C**YACukuCH&w za2U0k${UITz5{rQvi|)SfGa1j;GPR(m4TrQk zZ;C@3J{##Rl038I)SOHRP&36U3h2}hd$m| z_O-mw#M^V2rtK8bs%nfH4~(4}M5mild??*g%=e^`AnN_sfU2LNWmEm!6$?ezhW6Y4 zW1_(3wi!k)xgI)O;l)OW&@dTrvOuH?sE7xKa%mvbA7tgi5tzANhjFplF=MMl`&ti# zG6u?nwX86$aALV0Vy|%EK_3Wn&)0=)HPi5Q#&R0)2Y2`;XW;ra(Y48iLRkZM3dZKD ihgth@QIG5|Sr!Q-Kma@M0sI^U3SW|cAWwNoUh-lB0RnhI64+4`$4MN?N?=RTVoM^mhaAq{ z-FK^#zSCE_pnKRY(UQ1G1$;QCyQ*&0`Oa5WeG6z&Rldl@0ACXDB>`U&@Wm~TD^WxQ zMR+Dpz!5xxas_te&;JxSEtVPTgpA`D&eO2KA{UrrnWr?pehGL+9F|F759N&qeK37Y zmVYrT*8d#w&k^!Joa0V!CvAH&Ys(PzYn^~%<4f3xm;=eO>{f4Z>ra3xq)`VUL@NY4 zJ0y7UOJ+A}4p3oZ*7tf)z!09@Nz0zl*f=wF95b>n3%rXYvu(`ey-0Z)jm0IQJ%M8v zFm!Db@K+KLuo+_x`DJq>;&4-sfhGk3KC=;o^8`137synQwKZSGvMGDUwMl@8a61ju z-jc4ECrPnx!$U~p<}BznA;Y_{ja$$Z>zkcE*51Mv8i>fXN5FG95^g~CXxg+}2r8KI zuY=FmeP(@_`#Hin?3O=51d>i4pXyPnY|fr_Z4n?MEHR9+x20|K7=qZThmq>$i?gmB z5M{PdL1hCnat|n?ZTookjMZm}$hAYjiv(C^yq5=kXg1-7F=G#a&x0i-?f8oe2@CTH zQ5=EE>%w{5rf-1}(w1!WUXEj!=6eL!2mvC@GXi#x59J{Rag)apH}X;ND=P`_o%Jl7 zPge2%8Kt=#gLG9PQo)WN1wniyk7DfY3^M{ES3d#IPzJVmc&J0bB*6qSe19Q(6Egon zijN|E{2@YS-%D5P&LOa%XY}|}diGW-MKEZVQs?uq1eh=(ks*Hlj)kr{*ePx@E_0cqzQA+DE zL;LgKqg>t*nskHraprfBt3W6=Mtl?7xD!knA2I4<{RRPBvoWqt0#1nmCNO4S(lSR- zaN}P?#E=Kyg@lNPSye#!P&qf}?n|56^fu*46hq{3sRLS@wCHh;`Jq zVjH*T8TFuP*LGk{N)ij|Q&5k3k1Zv@YTF!Ho#N^{iQEVp&8_n#zG=$*iU+v>w5}cn zoEFOhlNfVn+%yMO1vh>KG=Yy~U7Y#GW(vrVFM|%O3xQrpd;vRgKPbd4a}aOtAZ8*P z^XgH+Bvne>n6!9GBWeuYjID0VgZG63L|3g1QZzAL1$d9D#|8N^L4g#+=Y3Obb&90C z9@-z&l86(|@=J!f0IXa|1r*sgOoF*9ZOUDW!A%|niVY14o52O`RRxe`KZh%~p=eX6 zMluzg$4=afs?r%_KY{rQB_^}6uRH;ps3F`GugJI3kg|;K!Imd44qA(#GT3q+d=f(r zTfQjh0%U08$|a<}4IfkPjCB&nj!b!1mVjr(5wjj+?oOM!Ph5#$^lpUqN5K>U6(qQ7 zn6LfJhO5@qvOYz-!bYo*^gO}DUI5aT?(?a+2hVy=iMw(HG^k^_Ib7f=9}}37J29nl zPtaXN`7syas%=QRDj?}1sJAKlMO~P@kLf_#m|z8|-;7TPk`+!;VkdV~y8;B{*>AG} zHTR`WcB`r3CT>Th)f+Sg&=6Z|K@#WtK(2s{03Y?rzp#k!s9^mLG?h#RyGhM`G}w^M zF!cEn@Vo>Fn|!Q?mwoPkh=|;F zRWP*`v`n(1JAI<}V=n&!)m_$Q$IrS~UD1MnLQ{;Lz8_nO0l+JW2NKW@j0aLs50d*{ zaTPyw$~H{unlmN5Nrh3L9iK21&5F-=0w4lC1hj(XJPlsAGZhmSNO8 z;zgZ`7yM(u^e4GGb07P%;~1l;-P3;GAJ4QEh zkTqTs87TQ)7(kXNZ>s`jl0_X2|Ia^3$_$4oeM(C}3?bvF+1q}X!+1k!dOfaju6L5X zxOAHUDCagXe z#O!aK(f!y8<(V3`I)CwG%*R1NKzt@xyNPCXjw0}Zr%7)x=6ULe?&+%FZQY;Eop%2V zRMYpW%d(^OYdx7ZDV28}q%`@TP)w}9Z+iUxV8BtReS9BLzF`qJx*p%6 z)OmzdjdQ>ogfP>UgZd!i1v-VrK%HG42Cw^K4GAK)| zF*y&UV23z8HXN)mm1EqdnN2lLifCTUb3Nm^KDbQ1wQd<8WZsQDT8@u>&M+J@@ znW6_BgT+->iK%4Ce6{(e-)(B+ls1KkYh4_qtPwPT|1Dbex76Sv*qAVR>H^vl2tcfY z2Vy`!0sPv&g#Sh3=m}>3`Yi3Ux;xo!4!dFhI;W+{Q<@G^Kn2Uz09M5ur*Q zwcC>O%-Ep`%A1xE6ZHhxi$Q_+@pBZPFPDe{(tMuA0|zjrD#%Rp43?Zb3 z)%D4et5^1a1vm5x_{(_VDeT~)y>_tL2CLAGCb*5G_@%Ip&TYW>Du{sUrT2gmN`jWA z*Tu#zm8EnOM6UyYUS{CZC+Hsk(;`BEI>D%-L!}spCxt-@P>$0C|4uL(&53z^L)too z8~ZlsB8URgFStH+gGlIC*Pp0fE2xVCI$o)7 zU-|pyTj6)2mwz0zT0{6&o#_3L=#6t+&BYGaaFaura)@nsjI~jH+sbJyui{x5d<;HM zn`69YjQpUsIdLmz(ud=Pa4eY%gXH{zl7w8%C7oSHTT8gfO6)4>`PxkTN5=T?<9MBa zBI3xPe~c8r1;&WD31@Etokpmm#$YIl&#j>JD+a~0R_X2UFVUZmIj#cu6k!=JZzJhz zB>aYR%;moU1`<%b3=LDkGDMj=LV!VlqO2u`0OfZn(PclQ=;u+Cn1~h19sDC9PpiMo z{|t!$!fAwSsl0^pGz$F#{PNG!@a11;ztH9X0hvkd*MPx#07*qoM6N<$f`G?Y A>;M1& literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/document-edit-verify.png b/src/Icons/oxygen/document-edit-verify.png new file mode 100644 index 0000000000000000000000000000000000000000..8fcf9e74a7274f44d7d77c211132de7054793ee5 GIT binary patch literal 1998 zcmV;<2Qm1GP)Px#32;bRa{vGh*8l(w*8xH(n|J^K00(qQO+^RV0T~Q2A1zN;ZvX%Q24YJ`L;(K) z{{a7>y{D4^00&MF=&< zlB!jNBN0TRQAA@g#1cs)l1U`j*Rj5_fejg{6jJFlBb~`WL58sX`lgJ{O>AbfjIFIL z$Q-*1sIP0PR;xrFLp+iA4>1w0*C5WwAOiWGKrjfW%Y|v1jWOeNVt!!(x5Ht+H!BMO zKpeXZxaR;1ps1OgNmtj_V4s;$NM%ALDi*Np_hWo~9D4l_E?gbJCtbt1*fR=M=P+(+ z$LLu*oK6R4l@fq`2lf!K|3@TXYfFio)wj2|V`6fWN$hqzj7B3Y77KjDmS0ImIvWm47`6ojqB*@3v(?>2&Dp>qTo@FFyamgl^3Q z2FIN6$MVpbrlB1%qfcwZgyR+hNeS~|5reikX1%NU`#+AKA*vtL6!5@LSpbyiIr42$ z=jkY4n=+fBH%{Q%$O@)BY1q9{%moq@wSdK76z-K6{P9f$;yJ8r2=GJ&SbP<98~q5a zg>Dno&uV7j;Lqg}KrtMX%{Uwg1_HdJl&D~4ML?G+4yQYWKOQ~$GWXm!*P&mq0HyXE^`KUZ_A6J|ctL8l z-rinl)cttpq6}Y5$k0M8-(=|i69|sn*w~v3LK#_TC{O8>mtry zIRAlM@f`vhpQvjB2~fy6>S7T^La9_@xIG?Nt!BL4=0>-z26lH?QH$@3Kv5JCJMV8J}f`lk#+Adu}b8|Cy(|}gD^y16EJG7So?tOATN4>rNbWOJ5BJJqtkT)>S+M92^h1t0|`5FG&`thx9rucSJ@wme@L`U$j6}}z0h>{ zus@MVa3|rQ%fAAm2LnZu2R6 z_W?q~zJ2>%Y-#y8sgzEuAM*YF4@ZBzL%??PZ8siu#5c3R_omZnE}6U(@?bE4_fMZ{ zWpZWFd1GVa-}=>>5&-`4{#W<){_O&GOh7^{BP!9dU#Pb119>Tt*C1C`8*$ z*H!w)*mBLzR=>3XI_Iv5Mx*>WE=eNS{M{4B-edCJ*JIB=|J&;{@>4p!{_=McKqX@V z6cLT><;v@CympMg`}SUU5gsNyNx1(z{c9$XmUONFv)z$9a^!_KnfzO>$7B(NrvD!N g+%tsx2>*ZU-)XbIFUDjkAOHXW07*qoM6N<$f}P8+*8l(j literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/document-edit.png b/src/Icons/oxygen/document-edit.png new file mode 100644 index 0000000000000000000000000000000000000000..c5883acbd24c8dd04e44b77a86b8e303cc622b08 GIT binary patch literal 1700 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 QD*ylh07*qoM6N<$f;iQC6#xJL literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/document-properties.png b/src/Icons/oxygen/document-properties.png new file mode 100644 index 0000000000000000000000000000000000000000..5b43ef7eea9927afbe3c6c2feebece02b39267df GIT binary patch literal 1328 zcmX}sc~nwa90%|xE~8GC)-lsOWgWN5m>g|7V=DwMspKF{C{Bu{P#IQm5-Za-OUptl zMXl5n)6=Lm6NtGaiKeMhE~tPDAPSPQsJZJrm~;Bv_xs-8z309A*F7&K2<2m8Zf6bv zfQ6qg0u9a%x-vBc6H%1f1WtxzxF5#U)Kn-wIs`7w&ijUt!QD%`GDzsY(FShXQjl0m zaBMUs4u3HUh>MGZo+h0opTwV!g2rAX&bSEtU--xrA`lTBg(pN4NioE8=kA>W5c{@LLI5vMhrWM3 zUOv0p+j##AUmy}o-QDah%psR3q#j}aSAOqC8#AZPtDvq{`}a5>+->K*&mQIDc|5>5 z91DxYxI~={JA2AEHhf3?1@x8EJ8w~srBK{cucFhgAkq^2A11(Q)NSdBi1eH2Cy!}a znY8Tm%h{O^p5|mePxdOLVHk80BmWVDQCPyrE-lV4EiEml?P4;SEEcnp?#X`3V6)j( zc}L#S-QQKQtE;PPYHDlq4%WV}udAzjuTx)N63*dpJ`@Lh_`q#wXy9_Wjm5~u#>S?m zj~~lIo6E4x|ByaaU|U}yTU*;&+uGaPKl3Vlc%R#OJl>be=#Gw#&d$!RT1t0!H=lWg zuhY}V^6TppfP{iR5vad^05k|10*UJa#bU8U)GU!mq*CdyY(yrLjWql*0vgqm%SYu3 zxdME~6vKSQh)4k%8&ixa$COH?>?;_`Z+hc;6M8B=wOXxGfT7lC)Y>VHMy1iwYP6sU zU1%r4p`HBS)Z~=jwBC2U8NFG(xw+Z7`8m)$NFNJ&i#ki7WgYNpA;=RL@bb7)(5PSl zVq)RsaR}}ofX0TLB3@2=_#`(s|78i2)yx-&hrfNBo}QgwSXg9Iy}(Z(mVO8rhAOz7 z-b(5WvP|Z+*^hQ0{DvWcMQEa_bs5bP!c7e{UYh`1sxkb9lVfc2hR|Y2`HCzhvRT{R z*rt|8tWpJ$-P@ermXl+o9@;IeRBrQuTvg}6LfdW2!RVE>%Pm_OYw-gH@LOynE;R8% zTA06)nBw^2wowv5}wx;B5H{JALa@S(J-`}I$U zmL#QXj@P6XoW34Elja{^?OVLR$k<5kcFk-2=uvBW@w(Zt41QkXromb&>xKI!5^V1) zRm_HGe;0CS>)o`1v)ykxQbM!ci)QMZR4x^t2rOur#2^V@jGUz~&e!eTpQ%3VF{Dkc zS!4|4+)d%&W4yiTiR;_zNV^H1k(*2kHvcMpDf&Ko;W1eFogqUy(< zv9I)VAQ#M|dd3^zJVHU}r@^r8?QbDFYs#c2Dl2$OxaQg}n~Rg!hYv75cU)G_?76ⅆ#Z9z`r(VY_Vfx zO5LCdnINQB>A45Sg6S T1Kq$3)%}e8kSIhsJmSWG!FbIQ literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/document-save.png b/src/Icons/oxygen/document-save.png new file mode 100644 index 0000000000000000000000000000000000000000..7fa489c0fe615ddfa1d1f8dae1de37c8ed858dcd GIT binary patch literal 1263 zcmVM8$}SF`)$W|Vz+h^3K1d&siN<^An_F5_&0!O z)Rzj0@&v6^_10 zg~*Nh4_Qv0^%;Z#{w#!k|1X#ZQ;;@Dp6+HDfFwzvR;z(y+w7a5d4<3CPl}Rf7-tVSvZMG^9)A0BAQf8V&LJ zVG9{>Z3|Y_U^M`ViOHx#!ZB013K_`6*9ZV_uqB#YC@zDZ2d0D?f6(P|tQ3#a@s(2L z01}P3@xh-TA45^onUU7wF%q&o*g97OmE=lL4uFOcKDoWQ{=CRE|L5o=qZ!D84eqm0 z(TY!}fpk-G0x@+f4Xgl&tX`6`UHUODLTUZqH4rBXBHE6TT3rHJy|_6BfHj~JeTEX? z(^0ITcRZGj$IvMk;Sv)L>kUjP&dLt6R- zyYa=Bbgatf8{D{glU698=svQ`7Y~CniEsL{qWLobmqjQA_hgE!!xHWaYvFXB9A-fFUE*Y87hrIt&Mc0u2-(v~0T& zKomz11c4+VD@>5(9wI1v4m741bguyr;G&{9J{<$#x*U9p55;jL|g$=_H zfzf=j5U4rdp6zxU`u#o_*fcf*z=O+|E`3m`*1o|~wbT1m=)U#UEdfQHwk8G7iBS9~ z3|T7zz%osq?{>Q^UTjrN8wdl&ql1G#H#RoD-hSocXL!RJi!cf~kv-Q!YQ;po(4Rhx zD7a`UT{6*-j6*c%v3CUk-TC)uH2Mye-|{@~A`$TRl`GZ{4<78euIssuZ~ literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/download.png b/src/Icons/oxygen/download.png new file mode 100644 index 0000000000000000000000000000000000000000..ec888b8dd31e9778c9bc54650c22127fc6119b24 GIT binary patch literal 2445 zcmV;833B#{P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2iXT6 z4Jje}^amXP00|9AL_t(|+Pzl`a8%V9{?2{w-o5)wHX$KT@-QJ_NRZeF0@H$n52P;@ zbvn+pzT2^*Gj_&yXv=7|E!qw<>I~Fsr?n!Y^;Oy#q=Hrii$KIA!jcdYLdYh&+0AbD z?%v&d@9E!FXVgNW&mOD${+7qRQJt`yBlz9V1l0ld`|ZqQ$>jb=k@VJ!{sqw{|XWLIDgt?~Sqy zB_9}>MqZR~K}Ri8i40^#Vh-o1ZkUBjR?Khp1^o9O=?m@U)*lBy+;89c5?D@)pG8I8 zPri5iZOfnY1>8Iu%docg8VHJlv{Asoa2zI+;P$xD(ov6@0*8^DK_-)f1p$d@0v(H+ zd3|HWclzHiKRuKD%>mH9z=`uAa01@&JxhM@{ja^`@v1zY%&|Ea%z_^9AY)qa_&o^E z@?l2iF28I(L|K9{lR=g|0YN}X(1Tdgz}Q$4l@(s}_Kso4_QPy`TLnu^A()Ks{@XbS zT&*uzy67cEQ@F*!F7B#BOKT-2(s@{%L6ihAMMl-^5V*hqNyP5`BXGbW5t-4688}P; zJw`a}M>>^-?sdZ#_E8b~qDUn0TW%dPaRvw=)HZis=hhXZGI`eA6h@W{Naq{?j0kX& z*oG_$C@s-pS`N1FK1zydWI`Zm+K|Wxl1lC|9n;P^XW|Xn*U8e5IfrERkBS_AH-NJgOp(sDF#&*$!s#hC2nv^ zdN?vh1`A--#We_(XrKjDwNxAhg+@t&1rD!IMj6ew)_P#&O;%o}cj6=b>CI_;5)ufi zDuv>yEJ-P0fBytrWGauQ;E9*tML3|MvAzsFk<-P>I0H12yR1}4!gMI72&Z5bOW~G< zU;bz{Hod{IW3T|u9SAH4)_r}Tec6rt(VJ)YUD_mM31TT?`=TpVrGut6j44}7Aknq5^alEr>Aq*Rzf=dK$ zTHo7-&p?_^zGdeNH*#5)SdRMYC!@(E{jCq~z+E?71Tc=ssU%Ki9Q04*FhxBM`4kuy z07WVi05RsALncpTQ{xz-b!j7yPr~a_aQNtnGkd_cogq~bIS8DtI}e`1!j>>LZ0ji= z!+lW$`-YRSBmt^U24mufeW!pd77ZvWG?EAMGf~81Q;2^YlksB2CZ}N09O1t`kWLw| zOH8;~P^Awmp^Yr6EN62({7Nr6n##}}_9E=pFf^6LNYa2=aHx6#5E%f50|33N&{{1%f{IY}P1{V=ef|^_8U_^b95Nt?n9RiNrr5aa_?}g>E|kuUk}u zJC`+~y{-fbnbH;|N-V+x!?Fu!!AM1^^2BF@6i6bUiJj>r{5ggOe>^n1dgYxn7BrhN zmS+s2TLC9&%ZW@&Z3(*SLm+>`0wB?gAc7Cl`3EuH-Ko$#AL>TD9Pw~YZuBZ8=<;9&~-0`kCJ(y{U=;* zxD*8{soEPE#ap{~A`v^iIrhQdH;VWSrs8j>`VPMFm{*?LbzxmeLtA4hZ>#aMtJ=Z{ zYAPVAuxtzQOpXqm6jXuZB%g(2`}Y8j#br-9b3`|6K}CTp$l3yCvJO&I{ZulGTzY~> zPxPL$q6fdKl+A~TGvLyz7TE8+_Qcbvc9}lf#+?D^_`l=;OI1L zBhOD9kFoK-lL#smhx!h^;-A}ji4-a+V}8F6exDAVBv)0XsFEPqeE-g87@zBIF2t2Qm_Gnx4K!-!+iY8Ongiled00000 LNkvXXu0mjf%)M}$ literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/edit-clear-history.png b/src/Icons/oxygen/edit-clear-history.png new file mode 100644 index 0000000000000000000000000000000000000000..6250bd646fe1f8ab6b9401523833589c4369cb0f GIT binary patch literal 2031 zcmVNJX9s2nl&7HxH7V_X9!#iV9W*1b0P1s2$j)?zFbkbrmUC#RsF-0eOswSkq7t z#$V5gi3STPu7B(-Gv7Jfdw#!rJ~`iWe&=`r!2eYLp8%=^8t4*fU`nQeIh6(lX?`AM zPD8ON4|8ztGXn@W(V*Oz24?mOI93=Btql_R*TGCUzAFJf-?;@&>`#X?btE*ErhzGY zDIB(BgEHyQAdY+uq%rfR55QzHU*Pjufh;aFhnbUAnZ?NH+{WBCANQq~l+2`sQAf6F z>g3#=UrKjansi~3BdWFB!laluw?y=K7%>Ily9WWfxbj#{MBQi%#G zw^*)_v`A#4`y#Ob1R^eQ`7B^@n7?>=dCkD_G(u@Ds_)3K--rJU4Z}CX_n~uS9J(I> zjAEhZ8v{SX$-lKjYRgTK^2^#&d_tAhNdfZm@@APWrWRAa0rW;KX!R;kX%wJP=0dJQ z0tf`0ARVqmpAc2e`L2=TpGV=cZ4|De_BtBy+@Srj@blF>&~UZ~ic$~t#lEp#RWs!b zSgqE%mcoK_2m~gAP;MY(!y|xjV{P`~zND_Z&~)V%)SbEk1vTd(=bxP*z^dz>rN_oC3_LX(I>L6{`=IBG? z8=J0x_*56jK05>9m90Shy&VYL?)f(mXSzXtp&v>=GYuUQv;}^LYZ6)cm^;4U&wL%^1Y?S zk3f(`H1}lxgc9$0q1t*~<(cjMcOd-U2oP9yXKNdQ%<`slS$=eF{gU(&@2M&w{`D_W zs@%cHE1vJ#dL8=@?z5DBwikiy8bxu>J^6vfTMGmJ@~OG1_~_}3fqM{+wjzOL8;0oe z##Y9XE#|7Aw88+7rC6<1vXp8$$SElx8vxrNBzeH+v%_$IS;YYv0=YERM*@?Jmc1Lw z`yq|NZ9Y&|ran+nrpw}rPA&@NpTm8>dlqPQ%H0q5y$oD72t~X$_rR*E@((Q9R!w9YJ;~0QaJuW;#k}rPRGa@F2dVXn)^g>{q>;gqq zKR@l$P-jrLskIci+aMMTQ=S$8Ewq`wVTyx(VN_W<`hVI0dZT7Qqf>&r4WyJG`80#C z&)oB-Z>aK%vlqJ!Z5`Kkzq3)>7>V9Z3&4=4X~)%Wq79^Gx`X@26)p4MWT?B=H$)BE zhBy7#(;t89uB|2@)>JpGMTn|g0kQ!m*dQ05p3dM4A`1f+#aXM)Uhb6**&zaN!QS59 zsIf61ulL+JvNX|Jg}16l0Fy~aAR7SLfB{@KJdj9)>pTtqdQ^$`ob}rJ;>OP0%l+dK zxcJ<@XLmr@$ALaJ{@~bGZ9iJ)qhf`N)|3E7qj5Hxg|Xk-AnF$g1aD22h|B7%kClz_ zmNv2ROIsAK`xmeF#A)=}8gz8u5|Y9zUojUgClv94$znLbA8u(1xB@oB#6^Pu^(AvuxA7&$6M(ZQX=Ibw@Dq>ZEt#uPvL1rh1jCAz%i+VIK%`}` zd}R=9%i*Yc;+<`r`xIruFgqvrz|H4j)JuL6fY4`d08LA`xBXm@;! zTm0;JpM&~Ygg2z19Gv^i0Mb}rP{z##MLZ1-8Ixg;K_0A N002ovPDHLkV1oYU$2$N3 literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/edit-clear.png b/src/Icons/oxygen/edit-clear.png new file mode 100644 index 0000000000000000000000000000000000000000..3e052bffd11748059d5e46d5c086ddc190b6b999 GIT binary patch literal 2073 zcmV+!2RP)REG=wpRd*%GeBQq1Rq16ModiH<&$(P#k zCE)OX!0+{J=XL3Y>Zw!y1d|C3*!0*pshCPE)l~_U@+T%d;QJfCwK_2};LmmCpuMB} zHxnMD0L^EfXHVadCNZ|k1pCcsl4h} zlz>)vJxW8j9DxZH9EjRg9DQ+5YM5dDPR3eaCZswH9BA0K!5^{(VaQpGLaQop@@LHu zyCPe^)C5*7uJ>0~J+P&^RNy@P zhdg{LB_SEwACl>n}O| z#kGRKBP}bYSBD&ngYgy^oC+nI?SKgb`V`GbC8EO)uB{8YqyTqt@EjNoLsm4&0J_Kh zCH%(R=|R6;d&~wA9YY#YGN8&?$QcnF$DkM%^xPW!bQdA_DZsn6^QQ!J&iBA!h6;qh zPRQ-EQ!^l(?!b&iRXL21gL?>>Hm-n%2MP|mTtZRU=SF@GL3B8RYrP@{MGmPfhry9} zmY%ru33z&F=Hlvb{^xzfsv5*$w{mvD#_7vzIfq~&4xSQ0)etz{jt7_2=Bj4I%Vxw~ z1Ddxi-CGcFFCdhI!C4^2WAF+DK3;^&rl6~*53vjpgF4w)zhY)lxHrZV!EUjJaxHu? zkMI6!BmMD>L9S!v94fd4POzF0iiVO?Utr-wb8~ewqS=i2k6*$U*Du;qJthCOj-I$M ztF9ceSPF`yLDDtwstkwQjh?|coQ%ljQ6*i})eDFcBf0_3Fj#l}boS;aZLE?b$1aKT z@@MAEBDH_{2jfMVak|ck-Hsbe=cDarzo!0uWA+ov_AV&$HNSr1 zw9&DA37k9!Cjdc`Q8^TYzqrt)0QI*gaH4rJe=+8qPp!r;YAV9Dr!IEk!Rm4tP$9;$ z(5(bnMT3>;5OST!$SNY;@qxUNjJ?WC5IS$M;kp`j;M_%{GLZ9D*^-(MHAY1X$)-O2 zYPlDTnrpSB@LNW?G%R>WJE03y-#5`)NaUQO)(6Lv(gU z36h%3G*Kf?j}61|Gzx=mXo?C+(~<9UBO)rTS~8i6Q{Kl{R^Zr$%SL&A-oBCrQ;&nU zq%0bV85GgLl<=k8t0OmCyL*>~A70L#jzmV~e;<|aU`*v~`8giKlcH&5A!_4!>(rtk zBrwKw21+<++UV#hOgpjwibHOI*h4y!-fu;Kjz-PqQ0uq8bz&$}as2|4t`wGLY1$s3A9?@y=G`zm~%Ldnec z!bU$EjL4Hq{PvK~1<{;BMh8mFfSZwY8jQSVFeU literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/edit-copy.png b/src/Icons/oxygen/edit-copy.png new file mode 100644 index 0000000000000000000000000000000000000000..d4180c69c2ce5791895782978b4e813bacc2270a GIT binary patch literal 860 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy%*9TgAsieWw;%dH0CG7CJR*yM zqGce=SbMeU3{X(A#5JNMI6tkVJh3R1p}f3YFEcN@I61K(RWH9NefB#WDFy~cqX3@} z*Z=?j1Jz>%&aSRNao<4y_@t!dwA84$nDm^iti0?Ud-mSGd+*TU!{;wt=$+8pH(|o0 zX;Ws-o;`EUtOW}fE?u^4<;s<-R)fIWwQJX{Tep7w`VAX4Y}&MG+qP{xckbM^Z~yMy zyAK{bc<9if!$%IEIC0|i>CNOa=0fV<-@D2>#zkm1P<9i_Z00ti+;M2!XVDK3X zzJS43F!%-r-@)Jq2>kpBL_dH10-|5PeuKcDKY#xI{rm6VKaQJcPXWV4v?Rzcn1PXr zS=HLr+oz&&(u`&6wjKHY>)*eN6TfrB(jw)AHloTbu#r>pGZ z)!FsJ{M%%wv)syFD$0L6d~K`!jMI-rZtk8Hd*o?lMP>R;=6YTyWraVpVqAY;ZzwQd z++d^gTHpWkKCy&vjg7oYT2h$?I}S`ar4T=>L2{#*LuG=`qyUM)%d0jth_G}w+NjR= ziw<*b5#UPq+07TCyM~MVNQ{ACV@#1U+gc?igYDA}l^RUZnsp#1@8~KIrd+dp`Nl3R&BO%$Kq(IxQdk;ED~%W4xMCGBG*-g4)_irQGpazIMs?zOh~3vU*XI z{~_XWpmgo&>gTe~DWM4f5f#Qg literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/edit-cut.png b/src/Icons/oxygen/edit-cut.png new file mode 100644 index 0000000000000000000000000000000000000000..073232808a62fba614f56f1daeac9e4addc97ccd GIT binary patch literal 892 zcmV-?1B3jDP)kdg00002b3#c}2nbc| zMg#x=010qNS#tmY19kua19ky@)q>0b000?uMObuGZ)S9NVRB^vcXxL#X>MzCV_|S* zE^l&Yo9;Xs0008}Nklpqd-%TR z|2P*vK`+{{^o5}LLo7{%!9>5_s(X6h6!4&|@wG|7Gj({ZFmArnqtBeLl6m=@OEcNdT02My0)1X$-i2NUA8lO)N72t?3bsjBer@&O??6`$nZpH-O9m zi>d@lw6_?3>DfIM8k)(`ECAxBjVa}-nylHg^2CV=nJ&2iWC1{&#t#Y%3^+N=Ol&$k zmH5&}t1SXR8D(Oq@$%7hZ>Ul+5|rGf1r`G2{YfZ;L{gG4)v~>Yh7|ZQ?i3HQ6rlap zlTe|%n{0{I`c@4w$_2F8VgN*eAB9qAv<(+-&%2sm~ONpS6-?k>+_aRT8l%mV()gRX@>3M$+ogXIGs+SLs_r&rYOhGu<^&tH?Z}VX` zW1Za1j(aYFNs<}>#EO=M4o|h9VIEvYjr}?}pJNfpc(FnL?I{Qh*8{xysR(ES`5lbW z`Rdp?pt)gtx+{3_eFzFF%7EWZJ%F2^iR8a=kNIjIoLWG}<5U&Q?9)ZJMfc`{`$`XR zvsh-A*A1~JTvZ3au^ZsZQQjDArrz|KuMFVjX1p SYgWbp0000q?g~GXWD-rVdtQ- z)eByHw%>lw^Zh>G|M{K&|9=hv_)nP&@c#~QlF0D1rDelefBzfR1_sVEH9bw_^nj334Uwb1;nE|$4J((T-rE!6AzsfEKm<(lDT9|V zR-ndYO%=|)<_O*!Vw`k@c9Nc-7CYlX**Ca<>RX7%NgW}k9e$hzRV*A;@4#eM7K8^? z6*%K*53UWB6HPgeqeLzhTs!0CfO|(Yn9R(?-~0Aq;zS9=OFYF}Z-8S&^_46b`1C!D zr*FsY?T<-M$3%H4zV}dpdxmA;znUT#A|mY$3#3 zZ-7!F#}cB!YCBW>xgj1siHX`ICu8K$S19CxJ9zL0qVe5M*67dQi|(YPDgA#PIlzIf zA)ex`H-J#Yjm3PPCu|p?XMHp-M{Cm=6NA3IY-BoGAl<Eb0N|2F>4e2v2GRGmM>Shz%&H~p^<5Qymuub0llARU{Iq*1%EoC6^|Es z6z8+SL86;wR>tUxeI2d7zK;kDL}yeKx>HhdZPR9SZQO`oSFAu&up5qA8bLIoot1Y1 zo4Mq(VX1_8HykZ|wJm(*=Ts`x&YOo?A_%RkJW#^JrB^hw_A<(4vphB}wlqdtuqVzE zO$XP!AU)EXJ6i#Ah@AJc;bAKibcA}Ni6ufK(;z%rEBhT`J~(W>2%^b((IXH8wS1A- zuq)gT9Yhe?nTyN?LDrA5S0NtEv)zW-M2>q{s9}TN$Ytm!(xQ)PjSND7jT!uz^K0I~4XHgv zZ_Jy}s4O8~;yI%LyNu_%v0zYy{cLcHNQ+UXGbRKp?X0kp=w1-f{S~~vv^HF7Q~LYk zBB8OjMUJ82P?4XXyWRj<<|e&)OT2M&T@>ySX)(cEi+u}WDjTdOy1SLgQwZiD;ky!xwreA>ig?w`?I0A2h8NhAKH((YXL00000NkvXXu0mjfs{d(= literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/edit-find-user.png b/src/Icons/oxygen/edit-find-user.png new file mode 100644 index 0000000000000000000000000000000000000000..e92aace503f8d75a2de2dba3db432a5e0705101e GIT binary patch literal 1908 zcmV-)2aEWLP)S35rA@ZfmK}fJziAY3l^jrloP6b>6Pm zS+Cb#@B1;YJHwqZI0^z3B3m5k(|mJhb~5dm{jh1_ zbE4=<6O(ykY9{kS|Bs%l;wEuJ4!r*S6G4A~`*WpI?E!_yC&TTRA-df51e&2&zS;ZW z_XcniU~fPpBY7}fSM?r-Wx)#~Ty77%UKxQ<7@{wN5ysV8GDpb)fcN6B>pb3~paq2Q22iKPYQ7 z`3IkArw*}Y+W9{NkR%rvjybZV0y^&6J*sMIVeyLq(=lV=Y5|sE=S~o!O_~fDSn?j= zbnROfA@eYGSVRL%gBDF_u3rl}#t^cz_brcW^-nC7!YS1Gwl`RvdZDmM&JVoax|((;-w=ax-CaLdk*CsXP2f(V6@ z+EJ%Mswfxdq3O)apja*e4m{!bSgue6q2v~+I|2+%#rU~PaQWoZ%YGj4dV{7ax^Z!8 z0w&R6=o(a=prd;|h)F8TE`a0tP&g2RgE`V>aBisoq8*_!oQtzlW0U^aE(Ho@Pt znq@h-ToQOrfWY%$7|xlXE`$&4-MhC9{|4K)Z*LqL8rpJG0%i-<&!#f@K~spHu9-fD za1yoNfI)QFU^pHFM^53pk9@yj;_{VbxmMq=8|1nTX?`v{{`6B%z5mn4esc1L1n4?( zPtOz|O{V4(tVM=BF7Y9O7bK750udTu25v#1>n?;>--8ktbq*xc=``w!!j=n#ADYCx zc<$VV6Zw4c{=UAxZkHrQ()4*W650CX6Ho3M9315S)DMy+0hqSR5Ljp_G!ux{-dB$E>;m&?4OD)gCxsjE}CaPgwOi8Z#y;%^NP54T?@ z;PTY$pJdrBF^mb0Rw~*}25WKWV*n@rU}OZxj~~aep<}Qo&&JPrLJIZE{iIyUKCw8JN5}$V=*MojyZ3P4NcR)(}H4cZPb~hbN}AS_jbQ~ z;+;4Tidt3uf!{B|a;jyVY6%s>{>uU6jn`hq+ehC%!^)O0vi=~Z=JIw`zjFi_2HAlHI3no1 zV;ok2XPrr!Wa7n}n&<@bI4R;Ev5b7<~1001SRVFo<}(6Mgr8&3;9})rwdbYeXxr zft^mkm>7jtw+Y-PX z9T9XlhzPj^1f$LP_MW}?%6)zITjTtm7X;jM?|t~CWUtAP`Th+)Z;$fIe71em<86Vz3m(G3fJzaK|OK7^px5Je5= zvNepJggAKzx+zu*gZ uZ`&-2;tM_z9UZrHkFbLD<7f9jH~x1p`(8na^~34_0000O_BEi literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/edit-find.png b/src/Icons/oxygen/edit-find.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3fe6bca06c7147d5dc79a2a2ae506d8fd03c9b GIT binary patch literal 1705 zcmV;a23GlrP)$x}9)U-ug zo3sy{CMQ9h%edX7L%Fta}YW=Y(#ro z8v=6z$aFYyPgA~6gG z6KpmIJRTn^DypC&B6>y#pT~>5oLm@mdSp4BXliW4mhK*$K6whW%FEf3wEZaoGJaKM z)q_ie7ctO(9B zy~qCNl-RdtFD{%rk1HQvMt*+&&y-902Le$OqWV8LK7i&`%`8*6GMyAePl2V-QbG#I zt&mY`VYS#%SGNEs1_p5M%vsb_&x4N9bL!}{4D0)p_zbTPRh5<8g1S07F?jw0LPJ9@ zJwt#jc5WbWpRIRSXBSqHZ2n?DG%7Ww@TMSXY9iz^ITw@?aB_P|`sK@(2b-E!!EUod ztyDjgTq4dOq86|td2s&$oH_j=u95bVc`SHDSS#`+_-W5ogEzmk+T-87;%z=SVUPlyU`E!uHlSY^Fu^ zZrzH*@4kntSFWOmdV=7kx5NSg~@1u%VvQ;cLwr&UV5%Y zE;VUw%{*3xl#qysh;0nr^g12LQj4&#$b)r@1L$pOKyP~!s>_QJJ0%u63P`&gnpQTV zVR=1NL?9_K@g{9d-?1y*yZaq9Q#m|YZq6q)IR$0|12-eZqS9=vUsgjg>(R5i0p*3c zFw_#hVwAQp+aGAv!P6#Mt? zgO-|c?AWpXsHmu=tmNIByK(&ees0e&8;#H^9OcLAgx!h{|y% zIy!pwZ=Fon?NYJiu2P|V=y7|3Y||>I^WjdOh(*R}XteRs>JnmuHw{Y+Q&FXkhcP3C z>zfd&Wl$#(p*VdK>KPu^+7r>2FGg=pI+~2JL?|95W*Jxi3FF6CJ@0UdiHULXVt6o$ zli?RdVWBP#>)k^1&YX_TZUHtqr(*kT203O8H{v07o9%nHQ7V)P=y50GM1=yE>-4x- z!{A7X7^{iE{IUXW0%%$$yufihMwpt49G8_8orKOT0gjZ)Fj%d@U_g$eMWlphI%ayZ z*m4bpkh58(P@=Y~9Ni^)ob(HEtyYbXDnvL^oQA%ZWys6RV-KRQhE4wLsd$~0x4Eto z-QH9jE1HfgbJh4HAjYXhS?FBT2=bvOPMXQRz%Y!H_WR(xKoyQ{+knrG?7+2weK_2= z1#>FOVX;_lum{zP5+EB*UH&!2MDO|*4DQ>4F9!DD)BZi^Y-xhq=?p5B%D^*Qacpet zM1x+xvnV&`R^d$F!&&(`59~(W4LXub|KaD>D3{aepb`JZWHQ~S=6qCCP;fibYCRPe z78W<$2g&Fs2>F*VhA@sWfe<$GRXjrAe@Ea~RCL2hbp@SQ00000NkvXXu0mjf61x&k literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/edit-paste.png b/src/Icons/oxygen/edit-paste.png new file mode 100644 index 0000000000000000000000000000000000000000..4a109a164fdb846ad285950b6cf54555bf52d979 GIT binary patch literal 937 zcmV;a16KTrP)OhyY5q10W3=1t0xvk9N?~$xasmc`-|fKd?d|tyZaQ>-KmjlaTzOz= zX{k4e#&UbQEtyOj0}EJKShx|1MDF_i{uy*NaDw^ydFXUH%I&JIwWZT(!1-#P>ffr@ z>yI*-%)7oJh(@E2r>Cc<0)YVdd_KF-;-OFo+#nv0LpU6U;o)I>ez{zp+1%WGirtO^ z6sC4|c7TJ(Yqc6oOt{OhY&HwQV2~$guRb<5c1=t|BBII4eQFWfO)8awcDrr&@qP@K zY9lX_+qE%;LV?Ed&04fS3!xgdiQL9wF=(|~TKlQ-G={8J8jS`~TvmB^B7lx{Qwh+{ zwz6vB)zww-f?O{5oj)V_RWy6t17~_cWiz2zD$&IMg&J6$EHDdd497{|g^>}vg$p=y z_sS~-o1ByCbtXisYj6qy7t&7v72YS13j%}?I16wHgBy4af#c5gXIX$00w;2b*kcH| z0D!*avJmef5XiNu1K8W&hj1ti!xvOKy>*tDpz1{!|?T~K>7VqDK z&!4_fcZrhD@kNx+=S_6orBe%XE9L|8v&0)nDql2X#L@`@^|YU-NWI=Y6& zW|lT~PA+bq@hKPG);9+N^|X1qIEGZ*dOOLG?~nrzOa9yLfJ4>|P5P!D>t zLoH%iH1n=)d2(iHd+OLYnzzghB literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/folder-documents.png b/src/Icons/oxygen/folder-documents.png new file mode 100644 index 0000000000000000000000000000000000000000..3396f36c116e3de8ed9fa8daed0b3c0e306d8c96 GIT binary patch literal 1119 zcmV-l1fctgP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L05@F#05@F$8GuGz00007bV*G`2iXG( z5fC}q+b-<@00ZAiL_t(|+U-?6ZzM$&tk>N$z3V+}fezgvPKXmCBOoAxONcJLlz;&F z7w`wj2ref?LWBoMSRx`ILCAz8WN=^!fiSYYYrJ>6voqa~>hXTC?qw}o77*N%+H;F|IhwtSEH+s)S*IW{AJT z5ZCPR-fOoW@4WNzxPvPWH!G^3sA`3(0PVRPy|TXh`ipUN=bICVvAA$3PaeW_Jn`G_ zzUe+%5>Pi0l_=^-h2y~iV$`fx>pQtVtQBlN^DG<-3Hn0jKpj+*fZu-E!~5HB0Eo*Q zYh0A7^DK}yYg)m~dGp`QbNIsH{?1R>dipvhL6Hk+6crbbtAN-{@W;W?oQScKTu+PT zdqj+JQO^YU0*42OD7#z9>DBLm<-(eIZ*LE`UwS!hl#$QtG$xV>VosOL1y;DfeFN`3 z_z}hCQ@WxB5fvgPbRvY1$TI<%3mn&+EC=TWW@~`aH~_u4vIWX<3WyL97-ObHIdK|a zzaLjax^xXt zADV#84GU)rtPfp(NApn;L4R1M_D-T=_}rGUuItNwuZx=^+Aa#NL9b(Bt;6L*r`KFa z)fhTqpepEi4BUqIgKmYJ5S7yx$iNqLz`4s)Ggc`O9wQ2{sTV5P@aWS4*Y_O&QF%th z2$Y3MeY*V9w<+&}2;l2T0Zw29-BSV5rvr#VC8|&WttkYKSZpB|AeYp9*SUVZy;1l4SmbfDLv1Esn#wOwO6Ec0&>%VQu`e*5JoUE6#!Vefc$g3-UZFd zOtg3H3ogDCByKl4-tTw)^H4HJBjgkqqo6CSSNp7U0r~jqZ$?5pf9^onTa1o>?VIm* zzZzJVM%D5PF%~CPOnC{$5~;R^HDMBj^%?MgS1d<*@tMKLLpB@PSN4!GZCJI6bOLTGdp~PdNB7P>m l7c4?r{5zp7p2Ytl{sIv#Q>QvR7M}nB002ovPDHLkV1jIS0Js1E literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/folder-new.png b/src/Icons/oxygen/folder-new.png new file mode 100644 index 0000000000000000000000000000000000000000..448a57f7b89a3393d06649b477677266021f0016 GIT binary patch literal 1369 zcmV-f1*ZCmP)Dy$G-}bd zN-2W)phPV`Xz@V=u@o-NK*-G_bn{$_Sy#ahd`Bzt8kNp|D2nUD;S#xO>ek7?jpdzbx< zS$+b-Hhd$t_}x+l8%=-5Ym-t)Odc#{L%Y2UKpIU69ii{?5$ zPGl2Xc3rWHHMuo}QAnv&0)eELL|e_F@k8wSX%GIm{{@<@_Ffw({v)YjGjB*vwsfuO z!t*?i1$`VE{GOd1JK4EvCr5_AXP7=xX^*asE+iwHsIXsZ45!@va{q^sWgBNOntTx0 zJ6^y4q7RtMUe+RPZ)+TEzyZ>D()rlIAwQ^Iz*&fbGKbdQ zLiNHt1kf}H3*FjDKy?tle#jELVULh)gP{tX^kJkGMoVDwxyVG8g}b+}o>EGbwKl~( zRQxhe9bU&z!I$8Gtb}wLE=WRd zrHihmd0;&!SAIve2!rE51yUh1hN}>c!*L&m%YX;XJsX1NbZ2dVF@e@voOl2c^QAJ4 zT+{s|2eJ<`vACCV8II;5EwFgMpn$4|@e))LKtt_ye7WsB_CztrHY?*g#@9-#gkx+C z^W|v6lJ={){+H+Ys{9ngD}NwLKw+$QG@$rP4pd}l=~>6d-p9kn6`j#Yp%T;v=(1}_ zCtW$K0U#vZG|3H{$aFtL&ySzbxAs#;+kYjbf)azSxHSH@jMay4VoB3RTGwA1l|qL} zKPsErm6wc`OfsPeBhH%ZW>|j7RkSYa;Nrm>$ba}dL3tYOxER+X*R+_H&NU=bS&Wk) zm?%r!t_@H{qmg7nsD{GX6G(WZQ;TS7X(77!GQiG!r?jpe2N9_qh?{@56Rw%o3gtN> zRmC}=P95hT|H9*D+%}%03tEZPegX-qmU<8o;%3}7uB#?hJitY?k~$4Q;%3}7o~tJS zUIa>0V-}Aqjf$ABC!_1QZHg75yw&a+5k0H39JB8x4yMlMB=tFN=B^}Wv#8- z9k7DL&A4r}Q6q?z$fE0a2M|O_+%|;%NG|D0f4=NQQAB+Rxuj8X+kEr>zQfyh+&7i= zyawuMeA=(P{l>n-0;GX;zzQG>DE?m&Pyl*>pXF3A1$cl4g#VWXLZA#3vDR|F#BGV+ b&Zj>BE|BU#SInZk00000NkvXXu0mjfmce?) literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/folder-remote.png b/src/Icons/oxygen/folder-remote.png new file mode 100644 index 0000000000000000000000000000000000000000..6210201b7d87744ca585dad05fd159e1ffc5eff9 GIT binary patch literal 2393 zcmV-f38wamP)y{D4^00_%TL_t(|+P#-sj3iYV$N%3sr>eWU zrsqDrGrM!!U6$*z5Cq|Y2NWU-`amKQ4U(8BhKL&D1MvxsQKJbVF-BiV%zDER5E6;R zm3YZ=k=^CKEIZ50?#%4;+^6qV-E}+1uc{$3hQ-as_;tQi_o?pl|JDEdSErkvIJyNv zz;X?A#ZDLlKnmcsMIcI$EsPI>POiXMvisT(fgj#Eg#Sg+^p`7`e?%ay&;3mI+7=Xx znCv8hVhuBQ7WGH&i_Py|5NJnalmN_yh;eHJY}N@<0zv@v^Jlk&0dyzA9V12jN(uxF zKO-P4Io=lVT>tq2c&eh}wdv#Sf3S+$U8WcB8f!qkw40YC>2Z%P7^ zdIt}diuf*om|MM%S~IoS^60 z8*F!&Qb5*9)f z{G{X3_nugMeZaMPgGl$s+Vm5h|J7Xx06$0ys^u(Et9nsWy;Y8PkkCdFloa^CRHDJ7 zN8V`dD5b21rG!g>7WD7onh%+U>6-Z;CkS-T*=!GvG|&dnQLH_cv#gGivIrOung5<- zE|HSbyKPby4Wr+U2hn*1A$lXR4ASv~`Zbea3ZJ_V^15)guR03C+VaSR~^lx@Ru z@>#r-D2CP=^r0YRxCNJ=0(d-p%Hj$0fx_8lQlY-S1*)!M&1^f2)qr4hm zvE0DgmX}!{hY{?c1!`E80wPCccK*owYrbI zqcA+ykIH%-i)S~{*XQD@Yo>AJ@G*wTW9qU!2!n82CRiLY1t7HeE}&*clL92&6dNY7 z@;RJ&m%aq@+nT(A5B?nyk$L z>;ON3#jVm7fa6%$oG+ufRm-R*CI`V*!3z>}VvULMeoT%J;N??ms01252NAOv*IhA8A9xizc!VT9hn0)|Wd@I4>R%?k2)1xpZEBhyMX zS-a~1w@GbL5*Zy#jL7q{g+tHJW3|#ovmN2>`3f4G>bd1Qnn8pc4vgWFy+aIOLGqkM zo{ub)>v6DatPdl@E&_&Z*PA?6k&fa0BQV??Le2mLX{|}TmsCjxd0U{?3ZV;mtWqYoiIpZaRFPSu^`dWI3Z0fD8lJ3Z5p0j7cEX*9NvNjhlX{Fo+R?R;z7O+!52S z56@%&z7cGM8l{mQZ2A${BiK^FaED2Pf@{N7!1FK8LbaM^n5`cf9e{xDj+aZa1C~N8 zQUGNOzt$ns3=_%P0MkSPFfg@?Ok#{<2_x9ETnc4b^w)PPxc}CRG0L~ynQ9v^E!Hu= z-h{`_2&J%hS01x7t0ru>N&6vs#>S8v8l;-90gy>0L;^{?Z-3sj)saJgs1>HK^Mgc4 zz=Qw@M92>)43GB8WuAF&PabDhTXe<#G1FJFXv! zw||yZ67&{CaeR<&xMtkkbj29;aqt?EMk7dIIO#j;^ZKg`B*r;wi=KKCL092O{u<}I_bq=-1_uR4;OZr+{%DCMM z#0xW1Q9r+RF#O(fZ7{tgs;NrBYGH zZceY%I&h^ysYha|5n*nl1xr4j^(Kr4BQjX&*?RD1&J!G!tI+ky}c{NsMCy3%r>2#LX!0K0B#S~A3w-@J%tade*pojK7}ZF za{d4S03v!+SaefwW^{L9a%BJjc-kv3FW1Y=%Pvk%EJ)SMFG>dhHrNJO5L3!r00000 LNkvXXu0mjfTsLRQ literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/gear.png b/src/Icons/oxygen/gear.png new file mode 100644 index 0000000000000000000000000000000000000000..9ab8c04f4ce514c83d3b86d2abbd6a8a0e56b3bf GIT binary patch literal 1403 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 literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/go-up.png b/src/Icons/oxygen/go-up.png new file mode 100644 index 0000000000000000000000000000000000000000..86d1f71a1ce2c1bfcd123115f916c4f553989c47 GIT binary patch literal 1517 zcmVIQj}T*mHBuuQ%QH|g1R7h~`#9&!8TU*JH!TQKZa>_al|7Gp z&R(z?4+PP%$46UlN06iD`7Wfs*zU}?(vvcFFK*b|l3ybod-EAux z^<*-Qfx#3WUpiUOkC>m-t^2rWTnS8=_Z%SnoogSPli&eII+Y@%!2=)dizX!m#ICw0 zc8?zc5%^Cv&1qOuS{6epl^%ieQX8`xidRF3E#qE5>?otqR0 z{@Q|vr#IRmJ1cuSMV>G`P7lM>Ts&BxHyuK}krM@C)7CU65*0_5w?3)~akK2=7ClYV z@O@WGT zuLKx7IDh^_?eXgPEgob5%YGBGK5JL|fvz)d2Q=1l`oJ^6UDbdP!IpTuyuG-rWGKh! z4BU(d&kw*kz=JFTg3kqfT60}r{#HE`wOy1(-R8heZN00jI8wW`!3o(1XEr`y%9jfQ zn5Mv_hxAN&fI&zIhCm1+BfupYj}u`Rv8aZtf2S8lYg>-=b$``!M+L%@nk|N4Ps7xP z@bz7hLm*@jO#w`YfUdj(8h@e+a?R#JrkF2&%Yx9lK%Co>cmVt z6qQnE1B0Lf8bi>e&w|l7ONJnrnv3N}QC<{AT~(w;1m2F@roc%wEh#9By_dMJj>(s4 zx;YF(c|F^QrVV-1G!e3Gn1)=}p)*yUlDWDUPM!S=on0rW2uq@Z~|Y!{|MBAiyZQL}2?~7%^wy zzZla5BLW5mHaOte_OJ>%$dvr9?tuXW4vi$gjg5(bEJ|tyEb7{}sYsYK1{m$$Bgdo? z1V#iRIVJ#2RvsYFIiT`S3Mdj_)MRkZ;n6yibz?*a!nwB05j~|{wppmEka0CI`;}}R;8U_rY zp9Sb+90NMkoEtLWhfKultI^RXSk4sKad@wI>zxmN>e%=GtSdd2!8Dytlsz zVGIq6<{sb}voEvrzgz*+jZp;58*@meux@^fSYO8Qzp#G*xI$#O Tb?3s500000NkvXXu0mjf?y{-d literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/help-about.png b/src/Icons/oxygen/help-about.png new file mode 100644 index 0000000000000000000000000000000000000000..2658ccad17c3fb88f459a85f912644bc5c6404e8 GIT binary patch literal 1491 zcmV;^1uXiBP) ze@I`Y)`|#v=^=U$K>}I!B?|E+2qEbqOhu$ZQ0SqgRwz`|6fxT%Yqk8F?jPOzXYM_x zIlJTRc<=1G`r;S9oH=vO`ToA=oSE~R5o;|E5{d^5k9&Z0e!Ucte6@#3Vp3Zmo!_j-stt%Nb9LX-%$uHLerpbg^VdsUxLzbMPD?=KB-U=> zi6gshSC_eO1M>Q}ZHR0`)T*YO&zfbkSTMVhST2$vKbu*y*^Z?7*xl^UQ3?6CyU!KU`t=k*i!B2!_GDVz;k6bXNoN_WnmO`eakyZ+>(692#?8Eb34( zhQ+hM8n)X&Q8LtV?ZkzZVIQLv9qB~YD zoR05#E~w)jqA1PrzXqtquYV6Ao_2le=xfc&wrL=GmArp!{rCoyx3OhvhN-!Xn{}#K z1;w7DSKNaZ4-2Z6oxfbfDu1+J>9%3G8Q72})bwd-%z&s3sn3ACd$1!^_-WDHDa>oh zM*ApcV}*Z*MJxAza(GLc-)2lfHRj%VC*vcY5R#gPeSol zDJ3-JGtPZHzTSu(t?MlNdy6C2qH z#z{e_nkt22scv=-xm*_Q>7>cjN#wJho8aP0=w`1g~i zNW+{>C&)EUso5@KR193bRiRLE_tk=W14`%Iz(Q5HFi;`uYjPQlR%1(9t}rg#$y+Vg znii@y)C>&8s@r-6N^nUm%|Q0HdxJ1saWo^xtQOa75osX%!7*$lp!C_ZB;jUO4kXSC zW+XTvtrK^;5eXs16a(rK$m4e`pA(6Ms7Cj_e0V)fElS4qiS|0FA<25&UPv+EodrSz zH6lJ5nO85@)yJf;YB z5an1CuvR0kAFMNAw=Oz?=;NaTDt25i=%`ayU~&`iPTH;+J?XhX>#Yfqd)k87bowf| zGFmyaW!z+BKYnbNTb|KiDXU9Pmgx_jaek`MoBL)oJs zO?6LmVGz5ejfo(e{)GHAQqYf8?Y66>Z^Hiq`_bH9lwONc!?j!Bd5XJXT7%%%cN@mC z&IOH(iLAI;Iul`V&?4@*4Nbs*1>*vbr1R((;b3_2p6zPw zz3(3r=|&;fIzep&+kQK-DjB87Shh1`QpXXy)oyOxb>DwR>1M8WAhIgt3M_3vE@U>O z%OhvOo<_``aJf(1*RPp~D8P^CB}zw~po%Dr!3mj&)dVXMgG3pGaZQ|zB!m-;>X}4v t$4m+v67AvwMZ)D21~o>FqYLRw{0|WnKq`oGUsV7A002ovPDHLkV1kE^!qxx) literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/help-contents.png b/src/Icons/oxygen/help-contents.png new file mode 100644 index 0000000000000000000000000000000000000000..7579eefba6cc6205b4906b54dd82277eb7bf4d6b GIT binary patch literal 1599 zcmV-F2Eh4=P)sNkqgTs29Tm*#sjWyX@|;GfvNRcfGP+ zb){0-m7Vcq?Y^ncuJ^0o`_-Esp|!^US>muGOqrgZ{_W7AL;DOcVvFLKntP84$b=Lr z08(oKO(X!A1rVf(TdqKuIns(yc1>Rada;%EmzNek`{mpxXV(G<%buB;nO9DqKF#gO z;EAM^h@uEwo4&2N@EG?2@EBXrU%&R!wK<%*Fm`w&2DogVot?$}{JeL-n>>H~JtU)( zsMTs%UG0JZXr)2m0|EsJgVs`ryim}@Gs0LIUQz|}yuh|fcR$vYPy_662EcW8#3j#j z3*zv*pX1=s<4g$_+XWu3vSa)2i!^h)n-Tt8QXpM|0at)qYd}f`mDeWDf4FPKKeq;u zvb4mpr;#l$H0~}Fx*6fQZ52pi9r}50!`Q>e8k6G@gygZ(L{MuTBdJ+avR=1(Zt#Fi}-6f z_op}eS&eO^0Uey0A8;CwK86Q&)s4^+C<3y)2(@6_3y&49-0mWY1>SgV3?k5h`6z|~ zz_)-MdjMe7JE3hIPkgLi+|j_qh!>#;d4Gl319na%fe6_!kO2xZUub@l8}lj1<&K;8 zGmKQFvCxUI+Te0$A%{S49f5pMCe-ZAG2lfg058IYHsRB67g0?l?wRD(5_oMg_V=nrNf6rF2BXx`8}bpPG~ zw~xO(ihCYLO3h4FPxoy1rAm^jA)l=G*(GD){PZ*NRh-Fygc8 z9dKD*V~A`J1D^g6gm)MmT?D6RXZ=E>ooYnVei>Qi8!S*d(2N)|1nkUNm;<~+E}&e?>c-perf;3`+ZkGJ{`BueE++Rkd;6R@?E zQEzAl!f?pA!fDxuh1ieQJ|vG*GRAYx%%36#AwUE#ULk0B03ic1G5`qBR?Qm1#g#zV zRFQc7g);M9z0*T0)sQGvpKCs~M%k78?7&QjIQByU163%SjDYgoWW&PcF|w#$ArV ze-fd;k}|Ojc-;pKT)5H3=7vNy7C8TF2TCzY9bQx4j-(s_z^%=)%)XKnk$p1)G?XGQ z!m^d+8g|y=VFh=Ufr68qZToPhx3_#cHUHG47W)tba)QmNZ x)!E!w;%jf=xc@~}ILp2HzMtzlOO5pz#6R94Xfv%ry$k>V002ovPDHLkV1i^P;`#sp literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/inode-directory.png b/src/Icons/oxygen/inode-directory.png new file mode 100644 index 0000000000000000000000000000000000000000..6919f984f0273935c51d8d9cd15af3f2e67a83e4 GIT binary patch literal 645 zcmV;00($+4P)u=l~CH&)_VEqZZ${D%6eRJeZ%6pX<-B-JGo8KjW&!S(FCcUp1T;-+r8|o_Yhp z*6$pfDxp=Td*Yi_wN@73=HH?N=lNWg8DxyD(VY!bMrO!_V$PR`uey% zJw4wcu@y!kPVHGR0Evl-^yK7Z+kN}?#iypGW~Ha6XQ!m3BzSv!N7~rfC>kp zAmBl3YwPLc3j+XE%EraTg_oC?m!ZXj{r&w@sCKHlx_T%$IJgTlAH(O|?c28>F*7q$ zqxLKqfY8uT>Bz{);Op0~H$HpzYywH^)6&uohJ}UY@7c4bv$3)9Er-LIMBD$^x^?RY zYR`fJfRV^z&LNOf)2mmnCJGA+OXK6?t?_I&F)?9PRaL!!&c`s0NklnDqKkb?76gEk zlM@2~B9Od|$Ky@0SS)r#M1+N}uP=S=+O^hsd3l_R7cV{mmKdhK9+yy1JAa?1Sz0sl3FDz zE9-Up_U$K^FJJD!Wg;9*j)tXX0E8B`MpILB1+?w}#uwti89jCCR0GzzqZ`uywtX2w zA+**b)BL;^&-KdJJa!lB^jtf@FDWVM2*ddkEq#eumJJOJjiSn4RBMUK#h?y5KR>?$ zTr7FHxw-Y0mX<#73B`|QzRcjX61SzVg>d?siOcVsd2azo0~_ova;&H4L6*43eTTE7sP)4_kU|$fgEY>Zzi064lyfJCv#Q- z?rTOM;W?1-Z=CN07mdF#?-H~<6FR^7@ZrO896Al?gb&3J>=8i7A?S$zx}cKHAXVK} z?_yK2%G>~e#R|Ag#K6a&wYRtPGBPrHG3QB`%UihHTYNqYgSn`!t?jO-r>FSd%*9j- zRg(oX1$p!|F~Uft6V1#ug#ECbush0$X@Mp&0SK!yO~R}+8OeW;cw|O$Fqq-*?{5b7 z_d@?qaMB%EzkYo*4wyLn&DGJ-`CdguB@tn#uC6YQaebikRfkq_b8hC4V|R~{qnxAU zcnhK}mlU< zlPXbUNfNm{2C=`O$$kH&LB!3?O}(L^!4=H*$A!`ugp;0T^<0DRTfQjTH?$Gq5Md$` zB0>~nG5JB6XK_v?cKWClz+GLwwYAj(Z!Pxld|i-G z3d!G9IG+#?6ei~9H3+lXkSM1}%_Je1P206=7acDQ>p?CPbU_&x50UvNr#j~^rX0o~ z#y_i&-PgV%@+tJ003bDC+}l+jKYpx*s%4Q}5VM{C`@$pZm9Jk1%C8BRd81yqh8Ubw zBlKjUnMMSYk%rFYK|oQsnE)zZptmJw$TCnsGU3Z~iFol*(G=kk!L$_#AFuld{V)@K T9Z5M(00000NkvXXu0mjfRey+A literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/list-add.png b/src/Icons/oxygen/list-add.png new file mode 100644 index 0000000000000000000000000000000000000000..5724694a9bfd37b69fc9b04d74f630bcc6fc50dd GIT binary patch literal 1487 zcmV;=1u*)FP)$&;9g;( z=iJ`|=v=b}^SNsfLB;Kdn8cae-{I8Qw-_xB?@Y}DVN_`x9RCsB8+W5gndL?^hb#9l z!dJ2}H2@PcAP5mfD96hIJfodmG9xtr(gYzSj3JbDw9HmVF^o14K$-vy2!Hz~|?E;h@fLR34WMC|S0BR5cX&A#0)}Cq(2*n^`L^@vP0ZsbiEX`jXiBaTLYOS-fY;-v^X1gP0-p{0FBs~ zC5k{q?p|Za-D@bh-*B>5?=?0ws@9(QXzKV!!*95b=^jQMpLhJQt8LeTz3cY^!eB0% zL3N*n6oUc3oE@SK87fNT)JKIf75vW`hI0W4id3`77TjrnLA!;`-u)D>tVM8*Kpz*EY~ zKp9sqP8rX`0=w|cE-k}B5DpFw|AHOscOWjsKsgCPBm_u>D2o`LC)|hDHAvjSEd-u& zYh_^`@jFq`2E3RzrQKusE8J5yDZTx%1%LwzM3K;V0>M415sySk@;iL7|e+D_WJ`$XT! z(6Ua*AM+Ie&;4iHd`&V7*Y%u7yefdQ0G@|RasVU?jJ-P}Qu$3tCaLq7V(?;oluWz; zXa_(k{vL3LGYeGW7{VABO1`yN>_*8eMSuhXDC-J1(oiz8N*YozqNJUq4j>q%C`1%S zuI4MTMj@;qEcqa7vpgvRh(rr<2r5=kti-MtxbiG!z>=(FdH`NV6&tcazC{JNQJPEI zv{m)BDegc$F+wgCQu}9=t@nT5+1`SK&1cv*xf;{RWNM1+{Am1Fk zxp{4%S2rrO=JOz9z(jbW`EkfVL1bhkVBSs*;7}JB=td_ zY)VB!7_kZ)b`#r$su)ltq=|u))?WxjAbnEy@(%|m*E8gf-ppW zejeNR?xAyZlo&Wj2QLNX;19J!@V8FZxwB^x-nxbO)hooc8ej~>gF*p<$R-#2li0rA86^YFt^tdRWC+M0ZJ z_wF>wy?5FHhwSupJh!^q%-p$S>sPLbxL&uSeEYWe;ObS|Y&1SU+SvH^pj`f_d2k^A zJpo6aP9h;6O`udVQ;UmxxrK#Q&yCjtYf&ie7>DOzw(IP>EZ@qqah_>^~ z@~lN|$U)+M(#931xrkx_Z#W#fbPBp%OtFHj?<1>JpUfi!9pw-VAhd?*^-bG}DnMMIxg;m0w2 zA%<7d-&YLaabFR`|3uErKo*M-9=}|LSt0;Xpw`qri#fBqtD`~BDm8M8HT30^4zPa0 z10Gr7j|9Hcr`|m6GQbG34jBfezu>w@zhwZA)G;?S7Ywij;5!3cW{adv zKdscyM-5h=o)6A`Aa?j~5qfZL6tKm;Z`!~wlBR0X&5S%Zo&k$A%F|dS2_(ZMk+3`M(OD2 z9Yv5rCebMj#9%CA8OvA(@+afpodyQ>k`4d>03v!+SaefwW^{L9a%BJjc-kv3FW1Y= j%Pvk%EJ)SMFG>dhHrNJO5L3!r00000NkvXXu0mjf3~BIB literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/mail-folder-inbox.png b/src/Icons/oxygen/mail-folder-inbox.png new file mode 100644 index 0000000000000000000000000000000000000000..f320c2677f96d8c778e6327fecf42db21ec4f81f GIT binary patch literal 739 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H3?x5i&EW)6%*9TgAsieWw;%dH0CG7CJR*yM zqGce=SbMeU3{X(A#5JNMI6tkVJh3R1p}f3YFEcN@I61K(RWH9NefB#WDFz0{fB>Hm z*Z=?j1Jxsgl`B^QxlT?_5J5XTyTZc4j*gC&mKJAc=lNi;bLY-oyLK&KzPzBIVBNZP z>({Tpdi82?aj~nbYjAKdP%1w^zo@9FwzjsZds=JnjHyd^%$&D)*2dGbSMHp>;pE)S zXXhkj-h6cF?yJj|uUNTi&C2b^R_?vJa{tX$K(KnvY7khn`p})V>o=|4 zynF3|YwI^`T7Tr;hK-vxZQHZ?*xg;H@9*BdXYby<`}glZaNxi}AUJ#b(4j+z&s;rx z=KA4lZ;o7jas1?|;}`Cn0)i{|PThWc`V1J{etYiblXJIUUA%bd%9SfuAH2JM@5S}U zUv2`y)33Lle7^nU{hcT8?%lh0|K+y_FTXr~{q5=NPfy=|fBy2#%a<=-y?Of@2tNLJ z|Ni~Q&tE=&{`~dZw{PEne*gZR-}j0-FyQ1%g8YIRm=)A@4Six_;t~=wYn$6wtlYcr z@|Ab*zyJRG_wT=d8*5@O0F~bIba4!kxSX7@Kr`V9AS%DiisO-w}oS-p#&+^(lJDHT*KTmIFY;8?htbA6f zXo12FD=RlY2@M^^rw=DTNS!&4m1QNHBd6WFOF|A0w`?)7?VjQyyT6Ag{O}SH?&1Xu z0TIV;-n@9j%-F>>*w@zP@-?k9HzV0Jblw4dnX+m@;-aP5OV(rvvp(r!Y;`@?D;d%FMt literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/mail-mark-read.png b/src/Icons/oxygen/mail-mark-read.png new file mode 100644 index 0000000000000000000000000000000000000000..dc9da64ad6e885f80fe69a3b4c77dd63670ddf09 GIT binary patch literal 1360 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 literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/network-server.png b/src/Icons/oxygen/network-server.png new file mode 100644 index 0000000000000000000000000000000000000000..bd82964be2359fa1416148bbc339362ac1b3baa3 GIT binary patch literal 1056 zcmV+*1mF9KP)jlCByaOd`I*wpX$`#3y$ zhel)n@WIm36aW)fKtnj_XYKZlZl|lY-oMv6=jWQ9NN7Y}`{ns_O-pE+REkXjWa^f=&oUtp_iB0^;K_g~$mg z0+XQDKZw??s(%*!*kbU2l2Gz;1K+stdj#+Z#ODF&+rVu{5B?5L1U+$SKmvgfc<;Rb zo)J{!1lWQE$oBX5Kah}dg}@V_XMRjiPjl+=xFkcISwI$qw>dpAdqAo{2m*5BERk_( zK*5m?d%&Lseo@jJo=0ROC!lz9rGjY~n8o$NBY;Tn0=j_Ern+yM7V^2=FaajU8iC_D zJQ68^bUK6bwK6^*8$&jm9iDKRf=)~XI0SG0c?&(AMkbT_$O9}zG8U;r1Y*$uooaM+ z6w*t_;kwU#ejkGecyS`Zi~B^#WV+oh48uUL*TbOSM}IJghk$K6uw4SaF(CvB`2uRs zYOpK|OUng#Zn2`)uw53-7nlytx3K1vyznxC!3q7gB zAfctGFzMulZy!Fy8TBtLi-;KL8$Af64#Rptu)D&0;VS@T*JfsB9?j3s-*Y{(ySw}2 z@$qpTz$w`=*$J)NjM4)PcTpno5`@{=*@flh<$F{W-O%i8ZEe;4cXyQ6agYRKWMpJ8 zF)@KkrGk7uZz~_*A?gs+YPH8oiElJLn^X{AS8m>{y5fBO=Ix)txj0w0VOOiwKi1aP ze)?nrtE;Q?Q&Uqv0K-^ZT)bZ>6h=&$z~CZ*QrdzCM`=h13EQ??6pr5!K(Sc-Yhz>M z=PNZZH#axCva<4hV3>2gUa!NCqf4m^-`M2j^2L}h;?d@$F a0sIHGV8(tMA5$#=0000ZXfe#8;LKtO5tWXONw^t@E!e`!RYw6GS13ZqQOYPd3iX#FXM=#8 ziV7%kuyV*{!G;#bRiqs4=qMG+IiTez6hob`4^8$Y-~YY;o9};)H(<PrNHq`+3()3_u zI5?!GrPv8EL?RLN>+0%8M@NN1;b(@dtSmO0 z4OBQBPES{tKqx??(M%?@q@)Bi%gV}HTU*=P+h2b|czAeHQWBu8sHnhVv4DX@A^~qX zIXS>aO-)U0Z7oRD-Q8_sVq#`yW?^9g%v)Pq+uGU!dybBd&d$z&AA`ZTxVYeOI6NNj z;o;%s<>lk!Lm&`*eSQ6YLI>W&g#}{(GmyJ|`*sA05J|#CMn*4qoae% z<#tVU@pwG`&`2M^OkaP0|A0XB_U+r@;bAb?v9Yo7@o|wzBo>P&CMF~j$>ijuR4SdC znv%(6?*NpW(?a3&^z_Wkj9f0Cot>SVo134XUszaJTwGiNSXKWckt{DSudJ-BuC6LN zI~59rQmI^9Tie*!P^nbg+uLfjdS_>6cXwB#(fs>ye{W<2+#-8V%`tGR+~U3QJ}@`{ z0)a&8=$ryDGO{6)V`HgQI{hGOMMYh6b7yCFw?H7D1>!*Hlg9cdY^meY+1*9#oup!n_wwx&Gb-YX-oJz_v0}g#dI6ZLmG$DZoQ{> z-VWj2aH1GGo)ocrnsP-lDqTWqoz^6*cU1;0w<>@5u7PZO=7^g`%$8ccbqcZZeoMxU zy8HtAv)sb<@KI(OlX(~uE$uw)!>dG=L)W^iLP9F}RhBXSIWL3c8e}77^YRhD%bW7A zEKz(yLy(e_ktR~S$XAH^)vISJao=lgc8bZZaNds6F+^Fmdr5WPKN6KsEvhHJxr5ZN z`}s|XX_H;?4p*=DevQSqf!yRH`l!HnP#r@U+ov*k?8^GF%>FE#WH=yoe`58V6!zi4 zwJ(ST@F(i+ia~zFLICTWSxCWBi`L+hBG8t+^q1c6lKF3Vs=l4G_5NIs)7e@dm+gOD zcHEts+*6h*N>sn#zWzg;S#Vb+D>!M@sDB}HU3}B)K_R@bZHBjq)*IKbn>fAcYuH8N zf`R!>nION`hGSex2^F4D={z6Cu%fLNp4(rIy5+9;QXShbxI?lTcxjT|FxyY&b4u~v tiK#y0gJCgvG}}1{`VSDWogM%H literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/object-locked.png b/src/Icons/oxygen/object-locked.png new file mode 100644 index 0000000000000000000000000000000000000000..353a22ca259a4bcfda30193e8e360870d3b0c10f GIT binary patch literal 1052 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 T6?v+n00000NkvXXu0mjf_&6?@ literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/preferences-other.png b/src/Icons/oxygen/preferences-other.png new file mode 100644 index 0000000000000000000000000000000000000000..711881ebf73e6c0960ca21701eb9fcaa3e2b7861 GIT binary patch literal 1906 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 literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/preferences-system-network.png b/src/Icons/oxygen/preferences-system-network.png new file mode 100644 index 0000000000000000000000000000000000000000..0e16fd703f73920b841cc14037deb07abeeb57ec GIT binary patch literal 2685 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 literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/preferences-system.png b/src/Icons/oxygen/preferences-system.png new file mode 100644 index 0000000000000000000000000000000000000000..2afbd23ccc523e9ff83d22d5dfa13b46db40b604 GIT binary patch literal 2171 zcmV->2!!{EP)hXMG%fYvC20^tL~c)}RIH(0J;c=RcM|JC$4jtl*dihrl9tgPte z;u-Jj4qB6sANMV*s3`AM+}hg8Ezqr`r1TvXT$4K}*ik($X#^B^fz6Igq@N^pdEn zuY;kX;S%oB0ogI8KP%pP0b!cFyuA76tJf4ffBwAJgzHUA6P7JoraTe}T8g`O@BY`_ zdvVCf$Us$f6{-mp6&1L0^~Y8l8=Ey;=CH@%jlsb|1z*wPI)9Zygo)f=0$pKdNogsX zo10-{`(?U?g~in20+ZI1a{=dCl9H3S+3_Il0SXHX@$6Y4l2ej!((n7u*gLV3)YMe? z`W|c7(b2Kt@i0^Y8BY)j1iGno12SVh9KPC}ziZd78Sf&&)7Hw$%KGL{HxO_>2qFIn zf#*?A`1txFD?5_{I~^gRA>hix!on!X?aS%REdH+Hs@OP!w!Xf>-MYGZR8W>U?{_J3 zc6OdKm;?{j!-o$gapxID74v9YJPqyzzhf#p<877hq1dGh@Zx?LB~o}l0h*l1yf{KvU)baKRv zn>RqNfw#98+`o0}*3{JekLqiiw>n) z2FmjMdZc9`D7v7CpdD;qf1r&7nFb6BCKc-O_cJpyVf}>_3=H+5rS%Dp9XkecN1OQ3 z-#a?XK1AEod63>550M{h_-Haylf?=nDi;U@YS*q^%T7s2!KO{-bZb4#pFh7h#ZI0) z+3IRBHe7s_bvNB-=#FQ2mCR5R%kb|bEb_0Pu?5@`!x0%)`Knc`X3{Y6G&VMtI-?o% z^mQ?7_DoRvAt)%QorvuFT#Gr}{+hMdU1n&BW9TelkQOjBXD~F16uJ|A6vLF2nc`3+ zhE#59YPujkKE5s>}hMyE(_2AA#Yp#0^UA5UX04^Fbq7Y~R;#RPQJ?L|Yf5{iH7CGlj*T&6Ub#IKZ7 zp)nANL=wLr{9tUdo}yg`Q&p$J*w`3RQBgfa?lSLWgDV>UO_=Fz&C-j>9Sw;T55;5A zQELlnjuON%6c_tgsoAGYbzqHnOF7l`)l}D;Jv=}25z|{Lm{GyzuSu+~N zS|8C+di?w25DIlMWr_-Dk_8V!Cnu--yfYFMMkrPj$0;zA^E+96ZTuS&^*@hBN0m0D zS${xv0>j+{?1lRV_D4>l_mG;J+H|_P)YH@R*}8S>A}PHZU0n8qx)&lMB0%kzmsp_; ze_Z-WOi~!bR{Q^%Rn-uQ%G;EhF{98~IUCYUMbxD-WO=g^UReoD-p$R;jv~H^zAq=t zUb}X!Gnt(GoacKf?R`f0;C&|KzKME;-xgL<6-y){-k`Hw3C$@AkX&Nzea(uEr9Tbd z#>K_8X=rH7w zC*6-#(B5LMyI)8}C=~hx2M4$K`}?<%&&8^$s(;}ol2N%Vqn)O<26M93V@K%wCw+UP xe#rvDbb=9K6JaS~vP{ZlCn3jO$uY1${1>on!Ni=?(fj}a002ovPDHLkV1h5bE#?3K literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/preferences-web-browser-cookies.png b/src/Icons/oxygen/preferences-web-browser-cookies.png new file mode 100644 index 0000000000000000000000000000000000000000..83512ea9f9f5bd8c339927fd8e696bfbe7d0f75e GIT binary patch literal 2394 zcmV-g38nUlP)Ru9(qaHRr5%bXv_NSTEd|04P)kse*cg?N8X?gr z_=;#C8Y78d5W^1*_{SJhBjq8nbt<%lGSHSjX8M>;XYTaA&-?9n_MO~7s6^Xa{^{sF1ea^xE`(ht<;v;w6lDl|p?d7g*2EY3GkN51HL-LUl80i8Y{mDJW6{}Wl z&9NH%}xKsv0Bw_+a5Xok7+CZpAZ-u(Ag7D{%~b? z|IlZ0UA_0nYGx1sjvY9Nrylwxvbqk}_i)$u?nB?AK1ecy@0fpU%%6GSp@)9G`wCZW&8^?<>RWs-7-ME_7M?MWOilyh5aropvwsq1|)F| zmLzEhoO1$`5GO#8{$dOvli|l1WV_FUEX&U9$*HYh`ojIc-#2T&hlF%4@avcN%6U2Y z(aFPyuDJe|H5lxXk(FY=^T8-{l>jBqAW0mYS|Aab$kZl5fPMR2oH$m)+|(fqF6mK< zJ&QM8z4o$06EBayJ!1y%ufTm<)@APg>Yb08hWq6%%|uBD5Jhk-2l=kNm=d@yWJLj& zAhRu$QNMu3wg0Jfm0Xc7XC#Q5mw2&9aRmgS;8U&r!`df&PL_sJ@!Z_eEFMG|E(37zZ5Fgha+vs7z59wACsW#d;nYSJzc=yNd4a z;@VtS{&%P~B0=E7zJj!R?6SMLTjx|rIF5%*HUlt;a79iu=2F81DLt1JKtZ}KITr+d z-^0P99t@9T`A`*H>xQm)DCT)88Qsqi5-G_uXsmAolO+v+EeI%*CbQW4SnOJ0B$aCu z+l4h>#sLCXgbM976Y$XHvdnTF4@4Apy__VuBEV9Y zt3XT>IFQfjSbzOxc=4r!Fbor)zVQibj~J)0rT_xCB5X zw~!sgw(~s?5{ogsI1kG(P$*K>(v^ zBMLkitrjYE_c*E1A%I=8P7?URiBog-K9}k@JzY&FbwFbg0r@CElmb%31RnV|eA}Rf z9h@y!@Z@9LQJJsPoOEuG8dCJj)daGfpxLP7Y~2Z8cxC44I0(XbJ&Z0WX^~C$Uoe>4 z+*9OSktHzBU|2qZ$53Q0q^7qAnuV5rY39H z`-X+VJ{vXxymq9qegDDAT<;`dcsKMbQRd`;6 z5&?yNAk1}ku7YAQ16AXq3|Wl{nK_F9Qt$Lk4S#&*4K(M=IDaIE*}C7_{`b@OTDE)m z&4!n}OMzJrSW=Xoxq5JVabNbP?t+vPvPY4~K8hpZ;9OQBfJFEpn^maR30jR77=aq~ z7Tueq*$Z{@I*`dT%vBx8x*Y9$yYaJ`vhk$VAjes1WefX$#Y3w>dsh{lUpI)?=>e%#NQipnkHTOV^Sq`v&^--h4(b5dr20v1_|g&GDm| za?SnceARspz#HU~O0!k-_st{uuf7ehEC7Z6k_0a2z}O-HC5j%30Sc9(K`}>Bp*Tw? zsbSUY;hx$@@O8Y3wCFBrEMYkwOPosyV+>L3MSkqrX0oUJ!M>9J1**3T$6Ef_-v9sr M07*qoM6N<$f@v6jnE(I) literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/security-high.png b/src/Icons/oxygen/security-high.png new file mode 100644 index 0000000000000000000000000000000000000000..95e73d93e0d768731d8d2f496adc16781f0d2b6b GIT binary patch literal 1628 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 literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/tab-close.png b/src/Icons/oxygen/tab-close.png new file mode 100644 index 0000000000000000000000000000000000000000..072c9bc8492a4689d50983a1b62f192cd3506e37 GIT binary patch literal 1349 zcmV-L1-kl)P)Rm6%6E1jU_>I3px^Ir z_jbH=E5E3cbC(_-hU;ixCV04a8!x5zl9(AesfRMKlXg zN+1Y=)nqc|v-c)LgfGo>oaFDrye-Tw^JRZL%AdyIL_h+Jk;W)sn0u&MPIAWm?5@~55JpWK3lv1TB zBdSTuw+9JX#zUe*jzsatZ_NnzNy@c`5~yX@JqB=wI2ApWdti}z z;B{RDw{0uzQ}e(Jf|_|m3Zm`E5rpbpz$g=PD=VQ-OH~#eNeNU3OaQkzC@tk0E@0-; zg|OUd#*MxE&~c+lae^iikOG}(s`>~{aYBRhf31=GgA zJY&U5L>t@SC@#V1_C~n(??;EX2?1X#+y_2H&*3T*mX#vf)Q&N=)2R6xSRlbdXT?j6@K{o7|vGghR$XKcd-VGH#~>C&9{>__V*)m?rdEB zvKrIXtVSpx0<6Du?3}akS#E}b%Y+<_Dmsr;(&5BEiG;NuKc`H<0pzB(kRGb85Dpx*$$!uLY`#ig3$;*1GrXm8BZQN z0ZZ;=aD-qu^fUKt%vFoUQpA3mYn0iy1R=7lx(1D239-~(AS@x?-3`g*M(BzkhKvmG zHZycN1ed@633ERG0_I6MYVZ-90u}YjV6kA~@e}a;(gl8sh*&TPITS`;TN_%B9z~pM z!G+J9D0ufhC3B+F;Zg9nRc<+*0KE&|$0OnOf)3Qk2ta7*!RWE6xOt`q)~WfRgeY%J zhPG2M@Lo=MSe6ZYcVJ#tI)b%sj0O-l2;c-BL<%GEqYpFZOv0s$-=WcD!V_DzAk}Cb zQ5gnfs+;gtVAGU|_5)8%%pkFv27p0DJsMWeN2i>?;_7;!r!QHmxzpk7kK&x$ck)b1 z%E2Jv!W5vx3?65j@hYV>fHyNOYY*gR$J&?8qa8r9rHJ%&>1sOLpl@*y(s1bcm9)cZ zR>yx|FozzR<)9xG&U&K=;Gu;b*<wdK`M5&OTswaP91$$v2d}rX00000NkvXX Hu0mjff){o0 literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/task-attention.png b/src/Icons/oxygen/task-attention.png new file mode 100644 index 0000000000000000000000000000000000000000..ed25cfa0d8837229a78dbeaa79656edf23d249e1 GIT binary patch literal 651 zcmV;60(AX}P)1Agan2~<)#u<3-UoC`XIE#Aks)=Td}-ffk@k0sWCzXSJDFA-IVhX7C-gHt+$az@k82I}xP0a`2b_TTSR=G&l)@Le z=x^g__I^ptiQaNxq!v)BVXrxcCR-)o-wS-&gJ16LKsU8#w1Z1S0&C6jPKpa(tq{JW zz|;XW9jZX%{t9541HK)G2v&($2XWXM%OB%s{T5Hj5r3Y~O#+5<0d*s)w^~qDTmpoR zycK0gxC)SbL=W{JZgIMyD0)37g)yTLegcBbG{NJPFw!FdGX#XPOyy#(Z5{B=uyb*X z#2sp1a293-OqhugRF8y+mjg5cqRfomi}e>GeuH}S>F;Grq-6t7GzzF$(L5olNH|qs z$}k_&YusZU6EPyvl82;Iwo;^(Iv1QHP_2obfZhGN`Quf)ZWp-RebiTB)RzVq=ah lgKY_13)P!a3lB^megm#=+3t*d>A?U1002ovPDHLkV1jxIC20Tv literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/text-plain.png b/src/Icons/oxygen/text-plain.png new file mode 100644 index 0000000000000000000000000000000000000000..adc288363538a493ac2c274eb2091c0b8c6e67fa GIT binary patch literal 1138 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy%*9TgAsieWw;%dH0CG7CJR*yM zqGce=SbMeU3{X(A#5JNMI6tkVJh3R1p}f3YFEcN@I61K(RWH9NefB#WDFz0{wg8_H z*Z=?j1JzRwc)({T}0D_xf za0?7>gTS3TckbT3dk+ZigTTXw4<9{x{OIxHCr_R{efI3>v**u%;Q5Q^K=9(l^A|5) z0Kvg)|NZ+1jDlbeDL!D>sg(rz1v4-*F|)9- zb8vET^YV$vD5z;@>gXF;+1S`RxF0=w^XB8nuiyOpr}OJ9PzRHar;B4q#jV`Q=d*e6VP)bkk{`L?39oqk(@c+q<%4te3&hKntsDZ^j2& zlFWP9Ry{rbF>ztZw9|qG^S7$ZH(i;@`sbS?^Pg9B(?pdMK64(}-I}k(ar@J&Jhr>y zchB2zE@4nk=v|*~##j>QEgkr$bp7-vRW?ibA5XsM<@K`m=hf~_pHv>cP2N(@tueKA zcjS~TjYjvHscMpM)K|XU&aj-z_Mf;(*Qw)ilfJ3-?K%<9HA81+`lPQy9-k)Hmj>GX ZVOCsqC`U;lfDx42Jzf1=);T3K0RZQfRhR$( literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/tools-report-bug.png b/src/Icons/oxygen/tools-report-bug.png new file mode 100644 index 0000000000000000000000000000000000000000..c7ace707e3a21503efe02b1b32cd913926c7dc92 GIT binary patch literal 1709 zcmV;e22%NnP)4Q?BA8iq7DN{gO5vCY)0y>mQ z)D02iOs2%mq0@yaS+dQM83P$QBb#m-W`fz&jYNUCI3FzX z=*#-C(Jf$XtC=xRY;5cX^rhh>ATbyW>r^V0KZ~)EWeP>PiLp|f&6cdw>0Bv{&7IEJ z!VHzlhDc3C1Xf{AL^uhk1wrV<;st!CGHJw~(n8}&hdt_Fk6`L9&QYGkcmp7{+wIF8 z4##dT+OQEY8jZ0&pRWyznwqxf9sX#ga3?EZC51vxYL%Q)y-~D!p}2cfjqojO9hsS# z?VNPj2t-9iMSH#8wOi}#2YS1P)23P@Ii1cBqNAfpuh-L(A~F5(i_)adB~>F%%wd*oQUYtb|gCudG6$-d<`l_ZC=fRG22vl&oPi(wj&l zye`TQIw?2FP6b9Iy{0$bFPAAl0a^D`6X0Ql^NI;--SxvFO>ZX?)8CkKBVJ9vADT*I zGXpdx7@*eAUZ8*Mdb-LO-izooQ}&LHvYy6q%y`ss9L#wn&izD-#d5P%q`iC|3txiy zHQ+jOp6B;dYHBKFWMoh#+8aUw-B78i3-2$=6trKYIhT@>asq3lJP`pNa+J}@C@|G- zxBJs~WV(&Z9PzZtV!`g<9J#)`>@9kuq=b@^k_dvM;b?EArPIx5dx&78+fBP-T@Nax z+Ep4bO6YHRr36CVeL(UyTRPXUK4=8HXrc*eAG|uIsKP3|C76iJ#b0>9d*+Nqi zJv1{gifXemsb_2!-F6CeS|+FD`7gkc!bLQ0uYo2RtQ%MgZb*@zVQ{ zkiODn{>$U>P!`mFh38+braSosbY;Q#h4+f|+zHE}pK6M3fF&6fXMC zGyK=STNFP#V0%&#T35vjx1Ym;U*eo!hIyA*LN^_;bSZHdH76v{nVcNz$$p-?l6}+- zZEzuO07(InYEAK9#2UsSpMo^TTtB+qy=NmLs5LT@@^Q@K%x0QtFj5=Z-DV4Q_)}>+ zLLY;EItXyP2y>H2TjQL35e5y zQjAI&dY6Er)QM#~VRI@wyT`_u`DyBap=CtcwKk208X-Vl^C417M2MG4rL+sv&!IX- zqYt5l-r0Z)7(WZ$v;~44T!c?UK-u8)9ci}P=^#uO!7JqYc_SkuF?j{zl|TW}&O1kVrL zxz%drYlw$JK#%fy1g)Zo$;$l>M<~xZ*x@=%n-Ax&Si?`*K{(iH{QjQJ?d{z-<5t$K(7HGLRkr^Gxv{q8E~v7}tO&00000NkvXXu0mjf DNC^_> literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/unavailable.png b/src/Icons/oxygen/unavailable.png new file mode 100644 index 0000000000000000000000000000000000000000..2c2f99eb46be90636f98984936190752350370af GIT binary patch literal 813 zcmV+|1JeA7P)E-4*}<0=h{= zK~#9!WzSn^)dc{@@z4K%&e_h+uIFq=%jRlhi`pDHEu;s75`r%D5=B@K77|LMhcYtB zu_)9aeCwfntVjt2>7mQOAXr+9^^#1|9GtD`ZtZrqbGCB}A8nt9-{Tj40h@h9LxO!V z9temQ$rQNw4io<8j=*th8yKhw!#7%Y@2*Yv^ax`yi{s-m!^7olE_Z&Nw~vw86c}Jj z6W_OP-`>~P->3c$VnnTx?4w_de8rShOxK5(ZQP zN|Z|!OC5~hy?t0~b6;C=n z)zxm_N=G8;IHwSVh$J|ijD%uMd4=Yrnr+*49Xe*Zv@SC@uH(%k>N`8dd%G=7PDs_) zOYq`*G)E4Q?%sk^EO23`--RVK`hNN^?k3WC<(delcw71NvYRrn(QjIEF!*z;P z2uhTT6iX}?Q+l6#4nX_Phs8U3RT`;kCQ?HTF$&>1CPG%%bL18opHJB{Fr;&U2HSaeDWsC5=5FFCVs!)oxmmJTNUXBK&;g!bWF-JV!{;2kpSPBY zt%j7V5fT=NZ_tEgE_}eDQKnIe0AT%Feu*)BAN9$KbX`#*QJ}75wan!|7&yquoBWFk r1U3tiK&qRTdZHuDlvzL)B>?yjfS~`FyINaO00000NkvXXu0mjf;$wU` literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/user-group-delete.png b/src/Icons/oxygen/user-group-delete.png new file mode 100644 index 0000000000000000000000000000000000000000..13d300c2d2622afbf95f2acc268cc62726e726c7 GIT binary patch literal 1365 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 literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/view-categories.png b/src/Icons/oxygen/view-categories.png new file mode 100644 index 0000000000000000000000000000000000000000..658ca0a4c4bdecc884fabf15fa4dd35e9a3b68b3 GIT binary patch literal 2248 zcmV;(2sihMP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2igb- z78e!zKuLH200>A)L_t(o!^M_OY+Th9$A9;}H}huvjAO@k?AWgD*r92KLP?Vrl!8jA zP!$4Hk)jCH1y!j^rS4d;ZL3lNyLQ_RNR=v~M2ay&w2G7jC`LfyG@&UZ4NYwte~dq8 z#xw8p-qXd*JZwRME>NFzb?!U!asKyz&iS7U|K~@wHf?Qf-Sv8X_)Cak3x&dB7={a< z_r)K|m-GNX{%=9uO?wAmu~fp#N^5k>_i47dM}#CzY4`o?zdsKE z0G{V@>EcBI1VE%=H~+|WNz)WWvVbk0h-6^DbI(1Wn;-X6y&~Ls@E}?#1W-yL)?!7- z=W@L9#v6S1-g`04Q@g-xufNWrLx)Jy6xVe*bLI?MWt_+t2B4HeltL@T;5e5a2itlFQ*aMb2J1#g&{`ujD3=R%bC>Dw07%!KjRXFE2}_Qjv*?2`QJ$EdW0Qa)8%ddBAONZ`Y~`;QFWZ zVq-~TSqmb9APqM{F7NUD6HjpPvBzi|8Q~V+$6AZlnp&-f@B6r}%iP@DzXt{e)>?ID zt(BFPm6@@zv13^moW6LI&RaYXOK(Sk(t1FW8fsCBqZEF@VSBqrxt5Tal+{|qgWn!U z?!Fs;WQ1S;>X(=}#ERWAWt#0c0AFyY1fT&jIs*;SN48Uve&7l=o5!N?C>XG3`-@BEWr44S~*+FVjQe&ys6K*V4 zh+@N@;a*CoPm>-vK<~CZSEf#Z2udqJ5G$ZSYlT?&VCG$nwR9AuF-tZBxNFZ2I*KmF zSQ2B=T49W3|5!JvF#vS=IsAglSf7tE77?NE$Pq?IMmTuaw{RRyqxDs0KOQdv6c7PB z*3IbX=+-t|D%WLZu`EfFNDzin4+1esB=3AMCvg}`tyYtbjSX2{FUvn>OY+z2b7Dp0 z7Y{uo=s;`Du3fw6>gpn&&*OO> z+qZ9LU|@iJKA$zqCLOTQtacFM#E^3oL2R1A1%<+MHDR2R_X<4!!V4Tfew0os+>i*vaBC6XQgm3~h*_=# zZ1X*47Ay2_D_~5s@2#+~9^ko}C{ZAgCWZqC4$#)tMpsuCp69W!u)y%}FiI(AW@hN` z?mbL=8@Ag5k7AxDZ*0Oha8wgmjBx$1yZtZVJR6`$>R*inQ zmP)0<+S(dTnazR$EG#T!eq#*F%gY&4TL8TI_XYM2cd=fJX!9JjR#fXTl^|xkuN^DG z+D1ezOmQ>>amv?+dvP2G-}mY5?WL=$i)+`ev2*86L?mM)NfPGg=h0f@`#z52P^nb5 z0_gPfT)MGJHH;bE;d7(3!Hy1(C^o3RMm{U`gxDB9TB>nvzREYo`?+x80>_RW%P39L zl==DjjDZ##Ns?f#p;leP8biHa+X~>e;m#)I4gLS>&JIu@R)~^@YVF$LV-dbK(82w; z_Y=km`}gn1^E`atXJ}}Mt5>hm*Vl*Zy4<{Zldi5VIy*bLapMM2J>YkLT15ko-`BYn zfS?fs+bUe`Gc8as*&{dOC1jm+9#XaXz1CdU`tcJdcYPFUG}Uk;|7a$G-1#>C&ax_kAv3 zz8pJ_qaJD#^a$T36o*sI8dueNHLlEBn+Z<;uEb#G3q387J z(=P&tPo6ya2jGF1Uw-)naO9w+&a_ZEn6TkzLlant32j=JJ zWqo~J%H^`GuC7YGUY9TorCcsc7={vtp{%T|$nsK2HrAJlQmbFS+qX`1Gnw)LKK949fxWVY$|fcERxuP=0TbfA>Vlu)TpUdycr)-+VLTCFlR zHnzhJg1`bnb3B@+ZM~;0YZ?kdg00002b3#c}2nbc| zMg#x=010qNS#tmY19kua19ky@)q>0b000?uMObuGZ)S9NVRB^vcXxL#X>MzCV_|S* zE^l&Yo9;Xs0008?NklmMM3 zxYLD#Yggh@bn8O85VfdK-&n;*eOsTjifuKh5w#{`GifHK^St+SrU^l7t7SZAh8YI# zkMGXFFv73d(w^L~X2p`Gy2df?*6wrM=tj0LK?rM3Un-3w>P=E ztzlEk(l(n}%4gMfkb@pHxR&oHN>`TU;-;-1e{NzbO2uJ24{pnF4MLOgMdNCw_I>Pw znyJ_7oThj_kxOJ7zO>3!g?eZEQ|KQj&h5sL-vFXr3MAyi#=iDcYcg673pz5Y3qQ@M zL@6!4({XCwJ(Y9u#}>A3>e`WAdS>I-`2w>ig5>!6WAjq|54CsG0Hz$;)3GqWJk|ET zFd*fs)FEn?lp?&neMTAN?syTV@=10h&dVzt%KUst;N<<}&N{3pO=PyUK zG%y1ITs=Lg2Y?iY8ReDF!x<-5Uj9AqMPK9j5HJfcY~DCAW(S035D}pIj6o?>SR|E5J*21B2bY zz#IW!|A9BxbjN}%T_5n&SHrivF=G_W7?NH45^EA&j7ZpC>f8ClgB~#F34+`;iz6zJ z*A!JvXxSGfV6H$lM4W1oq*?+4!T`a+h=a3mfTX|x14l?;YJvb@JUjrf&|47I2@n>j zPJnO#gAA7c#{@yBOoReBK8( z#s(xHQG$-guweVOV3GLC|9~+lQ&oM$#xu+VhXd2+1UztH`gVQ-Rt131FZRal00000 LNkvXXu0mjfxE+w2 literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/view-preview.png b/src/Icons/oxygen/view-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..ccc569323db4ffab40d1ffd0e1340966714588ad GIT binary patch literal 1462 zcmV;n1xfmeP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2iOc8 z4h8|nMT_1500lNlL_t(|+U=K1Y+U6XN6+`V^SbkX_!%7ANt}=-G-^d#npT2PAu3g^ zBE$m35{WHh!KPwSv4SqTt5mfrUG*UmffNBz7X>+eI0OZVi=BsKJC2=TJN7W18PCkU z_xm79u%MPztfpiENBZsV;^?n)7aw2ql}7*ur~ryD7Yi(DV8l6hmOFqD;yW6M1C0Fi zb(9qBUpvJEa)q{-N3aA^5}6q1^Sdamrbw@QD5Xf0(*#AyeEKT=a)}`w(QYSjO-+~a z$#EB>@hoS}UX&ClB~bF_0Dk$*Jpc*Gr$~vW!(jUwQE(a6nFRuD+M$c<3``sRRe=aB zGO}bsk6mj;9$MT_cV-=}EyYrsN+0C2ZMt?8=;ZFg3GultTyOEGzh2=}^k)V3tzDpp ztF)tKWKtjsAyQc)Yp^atL>2(FMhb}t9j($dv3!K`JWNB-y~AJ@45==k%)icH{QHQ6 zrqQ;%GqK8r%MBck%>qiYw>5#y%;4G@kqvQ95qKJ#lsFmSI^IUP(g{QaZ@Mbq2on^G zmVAGbr19{}eO#Sb;9yGQC0F>}WQwy>H9Db1c?w{&fKZB*y@2&Y!n{OwEFE9tOoVh` zMF6)hpoBy^$+E07FRCnFNs!114i3cdR37L0Sv@^UUn>H{IsM)IG?4FM@> z#vM^2;C-2-5i>X)5?aT2GsU8H*vR5OnGyxO8x*}e7kg2KDq~s`J z{ari++S8l1NdTpo_jl7!imA3@v7V<9Nlvb%nQb}R1h^Xl)^S5XL{MlYd35G`?Cf-r zEM+*|80O^oCEoqu7(p6j#bZY1&_-|C<_l=WWcFdMhaP?{hWCCSV;^Oxg%MuMkXrMw zp#=v@NJIo81QSS(&fH61rkk1bHGX}3f@*O$rre9!`E6cpl(x9QrUoQcJ;03p5y{#l zt_jJ7EGiXn;9@UYXsogb1nSlwARG`_WG!Id8(I9!tGir76c#OV1r ze>hV@c>?$X0w|4;U~dFC{0L0GglQ^-a)buf5{B_YgVaD9t!g}Urp!>ih*$7gom-;P zNaJ-S>G^&?t=T3&e`N?XDEMLmQY(Z6Aq4CB9+LNVsEv7O8xfOr{LXdcN;jvPduZu( zR>T<3ng?mF)XCN3B+5SOpkSmBdLcp>)ggVrs zYw|TJ^&IoLIR+@R%dK%yTqBAidJ`#xuc`hb$>2A~_~)O8cp(}j)NwRyPe2>R2DeOt z!eQQiY>;UEc`jbM&bJa(a#4lam4ITVOfFVp{>6|?d7S57JIvqZUYrCC@IMG_pl+s6EOgkVT0`pcw2jGFU`*T9_Q>IpJuMz z&A!KfgRP7ZX-TVN(H`4oa|32;0lQwM$8WLcu_u`G@24<$0OuUmf!ezD?MJv3{?scR zSo;fm21+c);=I9;Tb+RNxIF@T%L_Ov%O_Z@H`vjYCE;7P{`UXSKvZ91c6J`y`iSX; zDwQAp0A11CP7b;M!tBhHd+wPh-HGGJoVC{7E`Y-VNCS7@p?ASKzUEHzF+zA^hb-P? Qf&c&j07*qoM6N<$f_`YE^#A|> literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/view-refresh.png b/src/Icons/oxygen/view-refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..afa2a9d77403a12cf6808fd4e551f8582e2599d6 GIT binary patch literal 2182 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 literal 0 HcmV?d00001 diff --git a/src/Icons/oxygen/webui.png b/src/Icons/oxygen/webui.png new file mode 100644 index 0000000000000000000000000000000000000000..51a98345fd907a198cfa1de975ce0c6e0f9262bc GIT binary patch literal 1577 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%0Amgrks>UQ&_vqbwXMwK;$*WQ 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

g@sEpg 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 literal 0 HcmV?d00001 diff --git a/src/Icons/skin/arrow-right.gif b/src/Icons/skin/arrow-right.gif new file mode 100644 index 0000000000000000000000000000000000000000..da97e6814f8ddaeb13dba4cb61cb023b6fbaff8d GIT binary patch literal 54 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 literal 0 HcmV?d00001 diff --git a/src/Icons/skin/download.png b/src/Icons/skin/download.png new file mode 100755 index 0000000000000000000000000000000000000000..e54418cf6a591c58256111a9df9c9dbed323d9a1 GIT binary patch literal 463 zcmV;=0WkiFP)uZM2hh#T)O39`6P@JqD=xK6*mh^!DqkzB?bT zGYGH=V#OdikQ$)oO}J8G<<*xLPQL&3mVqDWTx1Lq1IdBZ;7iKC{{889;1cB8m!?ne~XMln4Y{ zAAfkzvGw7q3Q#11*g(x&iOx(=P=Dm%UMCnEmm+`w0|0Z@nvhhSy*dB@002ovPDHLk FV1g4{z=i+- literal 0 HcmV?d00001 diff --git a/src/Icons/skin/downloading.png b/src/Icons/skin/downloading.png new file mode 100644 index 0000000000000000000000000000000000000000..a58a1714e1575682a279dd138778bbdf0c22faa5 GIT binary patch literal 3270 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 Eg7TvXrT_o{ literal 0 HcmV?d00001 diff --git a/src/Icons/skin/error.png b/src/Icons/skin/error.png new file mode 100644 index 0000000000000000000000000000000000000000..37ae645ecd85d790c4982284a04ac4b1e0b4962e GIT binary patch literal 3038 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 literal 0 HcmV?d00001 diff --git a/src/Icons/skin/filteractive.png b/src/Icons/skin/filteractive.png new file mode 100644 index 0000000000000000000000000000000000000000..f72b4406c57c7f612cc519f426cc1ea5c6ef52e2 GIT binary patch literal 3211 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 literal 0 HcmV?d00001 diff --git a/src/Icons/skin/filterall.png b/src/Icons/skin/filterall.png new file mode 100644 index 0000000000000000000000000000000000000000..69d2e56f29869067e7a27f3ec7aa0ce63bd1a9ba GIT binary patch literal 3174 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 R3FZI*002ovPDHLkV1mJe&#(Xh literal 0 HcmV?d00001 diff --git a/src/Icons/skin/firewalled.png b/src/Icons/skin/firewalled.png new file mode 100644 index 0000000000000000000000000000000000000000..09010eb5625b0b5a492559120531cefbdd148dba GIT binary patch literal 1488 zcmV;>1uy!EP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iOP( z5GNKDm4v$h00mG_>L(nm9HwiIb)lv`Jc#L@lC1 zMU|izv_j&p;-Y^WR|pUi7oh@G2nABLsiK55I7GEgoV6Wqyq~l4u`};`df{H2``oOzvT! zkydGhE50Xw`l=ouyhUgG@2uVWhj02_BdvaS>D*k>>~>qKY0p0T>@7~d{Mej5c%P_f zYta&hn-IT&U*5#nWsC!z576UpkQWc2y$vo==FJKI^1t=M#lK8nd-b1D=keE{uOfWM@ZQM3jpdAY8_}_LN?xp;2|9SQS_wW<#79Fa(@K|{X;ODh%3-yfh+_yimw#)5G;U(Lh}l&{RYb4 zfjx>P`Ts4Rnqyj>ftA^vcgy~>4^3^hB+CmVdIM9oDaQkR_xQAy}{2 zdKWo&9bVpsP7zTJ-j?{;eOo0Df1$qE3gSehD3KyU?E$%K60Ls#2#SCj5D!KX0TD;G z`+MwS2cZoE1*2$hzUr%!AKNk+UkrO?9MmgJ;1PEOTH%WhB7g`YmaJGH0*zV&v_f=_ zCJEwWm>$6i5CF|0WITD(ro*b$X)eSR9#VyT2Uy^e6nAcn^NyXpW5Rk31j=&3=7kLc zGs91hpq#?sIix@b$UI(HvFVA6d&?dZD3SrAL#T3mx<-}saXRDVU{3$=07O||TW7u3 zrDiAS^blr;P>rAkoCVrSIZ7j&Pc>YOg-{g=Aa^hvq7zFsKfvpVavpJQYYP+(4-YA) zGbEVdb_cK+g7eS@y5KET+0ktUw0Pi74DW?;RDY+(ova=Th6JUw~E^SUQCM0YqECCJB z9{4%&z zYzf*cecM>wx>J4g?5dn88onX;N|82D_f+8kUz=m&4zHbG2T=xt0lDTFfoAhNu>t%k z&bOLHZTZqyHd=q@^L+2&doFo)t*TUNO`s_#o_Y2HUpKVZh0F^^Jnc1MTv{lFZs%02 z3f@4~HY(8%c56#lzqG;1jVGPUPyRH!_lHd_l8&#P0vg?twZ=sagGq4B+Co4(g?7M#r+E*S}F=kME{kMN>z1ZKnH)mTL3SnpUNy4$?4C z7l;%hpeCmype2+gWX_Q4ayF^m{MU=xJAWP~_OWyRWl)w?@b%-p@Y&Hk>YI&ZUhf3r z%AQnrCS$>NZmo8;4I|n$;MVv7bvXnZ;KhPVDNv qNf~|RT(;e4g#Fdk?+@d+UVaOsFXejzRI!5q00007On_qum%9^DG5CQ literal 0 HcmV?d00001 diff --git a/src/Icons/skin/knob.gif b/src/Icons/skin/knob.gif new file mode 100644 index 0000000000000000000000000000000000000000..755e06e0df8d1f23b476bce8511b9bae2fa5f0d8 GIT binary patch literal 198 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 Q4FCWD07*qoM6N<$g0BaLIsgCw literal 0 HcmV?d00001 diff --git a/src/Icons/skin/qbittorrent16.png b/src/Icons/skin/qbittorrent16.png new file mode 100644 index 0000000000000000000000000000000000000000..436cce3bd5c35a8afe3c12a2564fc99b6781c3fa GIT binary patch literal 965 zcmV;$13LVPP)_9-qd&O&$1c9Q@jIdzm@Z~eZ|tMl^{RrT z=oQB!$byW!8~3qq+L&}A%+34QuG^H%qucYae!q#{z(*>jVR>;1R^Nv`@D0W>CdA;; z4-&L2A8mVx2YWUwXNcX73zz%@Z-|}`iU&k#2%BPl#6Uw%m?Q~xCP-*?Jw=6uY)BJ58K8b2{ zBvN1|En{{ng|}at$DwKU=VDrXMG`oBEaf;sH(>15!}Hmzxe58)PC1RH8Nl&L(iGQe zv5Hv*b2$-$TfgQ93-2=~+N0btg8vTbh4zAbnTx{}&mUHUFwT!gMLW<^C4R$mdaJi@ neEs7a=ib6nQG-Cx{}o^W5ORRtD3MCE00000NkvXXu0mjfS{%Ix literal 0 HcmV?d00001 diff --git a/src/Icons/skin/qbittorrent22.png b/src/Icons/skin/qbittorrent22.png new file mode 100644 index 0000000000000000000000000000000000000000..7a0deda6a2e17c9b391dc80e60c35749fc59d6fe GIT binary patch literal 1444 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 literal 0 HcmV?d00001 diff --git a/src/Icons/skin/qbittorrent_mono.svg b/src/Icons/skin/qbittorrent_mono.svg new file mode 100644 index 000000000..1c43bd2eb --- /dev/null +++ b/src/Icons/skin/qbittorrent_mono.svg @@ -0,0 +1,83 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/src/Icons/skin/qbittorrent_mono_dark.png b/src/Icons/skin/qbittorrent_mono_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..dba86fece0f07dea96045586a1531a89b0693ec7 GIT binary patch literal 1513 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 literal 0 HcmV?d00001 diff --git a/src/Icons/skin/queued.png b/src/Icons/skin/queued.png new file mode 100644 index 0000000000000000000000000000000000000000..963f7125bf223f12a399ccb8b79159846dcf74e7 GIT binary patch literal 3014 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 IM6N<$f{x*tmjD0& literal 0 HcmV?d00001 diff --git a/src/Icons/skin/ratio.png b/src/Icons/skin/ratio.png new file mode 100644 index 0000000000000000000000000000000000000000..40d00c42d8d2db3d9429194bd24be55a5edaac24 GIT binary patch literal 483 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)W_BSZGszDNnt-Mxd%8G=Se#xu z+1}eJQRG%+@f&UyN5{##Ei7Z4vp8DzH8?w;H4P2% zb`6eh37OEDQ8+QXM9SoUsqjf={yCrbo&PLzued_g@M_|N*8i^Sch5S~keIL_YCq#^ zpLLT+HaS+V@^TVE@#{Qv*2&kzh^gTz2`XzH0T{LRd^lEJB8fPsOLf#JtT2nMl1 zVjww?8a!dp&S02r!N4yM)c6(^gTz2`AT>yU5grRYY<>(<78@C?>lyHZqrmWdcETSR zE1M7o^sp&1aEV=DuxaFDVCBMZ!0&Gi3`goeF?@Sv05s%2BQRjt7?@a&GZQQSVAuR` z4@i?O_CQ2L<$nfwXB-CXWdQn{5m|@@tHN)u8Hfeg4FJVEWd?kt(171xh&BKqzyN9= VzITaaw2lA(002ovPDHLkV1meDvKIgV literal 0 HcmV?d00001 diff --git a/src/Icons/skin/slider-area.gif b/src/Icons/skin/slider-area.gif new file mode 100644 index 0000000000000000000000000000000000000000..f22edcdfd102c3e8b184a5f3d20d36f6a4753eb3 GIT binary patch literal 78 zcmZ?wbhEHbPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igk+ z6A>i#dFe+003ZNKL_t(|+U&hqjAUDO9k%v4cZwnBn(NK)^?R?`{d#)MZn8->$>t!o zO;aRni#7oof(4s^WdnwO4EW1G2K-@t82T|h!v63CNd`^Bk|@}sC6N}}w8-Y%BYS*9 z4LQbe?>)oz$2sQ?5jP?uvNEf(>g5HhG9xoG;>Nw_th3JAd#_C&|Fz#_Tpd@()p2#K za1asFL}Gg@!`4O$o<$E@_HgFW>~pE}9hdyB`}~9;C}nUmDslhe7^O0o?m9+SL+R?c zIj!L6-gR=v43xpj(t02ZuQhj;7Gs zUdrou1-w_s)p2#4dI&+-7$ms1+lP<>%mB|IWeZlh4ZbxN&phIJHrw?xfR}uluTw2h*0^Y0R>bN>iJ>pnm*iW##ok0i!m|~n=6 zSj(8^8vBP+oQw)sd$|?VE8x94u8yl?G3Z7DJ6jq0y%

U<_A;m6w3;c}Wjl;Mv`ucSu3# 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 literal 0 HcmV?d00001 diff --git a/src/Icons/skin/stalledDL.png b/src/Icons/skin/stalledDL.png new file mode 100644 index 0000000000000000000000000000000000000000..60fd87bdd2e06c3135308247ea1c5716cefb39b6 GIT binary patch literal 3188 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 X{C)?j=Luy800000NkvXXu0mjft@94J literal 0 HcmV?d00001 diff --git a/src/Icons/skin/tabs.gif b/src/Icons/skin/tabs.gif new file mode 100644 index 0000000000000000000000000000000000000000..c8b5b0c6439d0cca7c57645ec33bb400a79eca75 GIT binary patch literal 2060 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 literal 0 HcmV?d00001 diff --git a/src/Icons/slow.png b/src/Icons/slow.png new file mode 100644 index 0000000000000000000000000000000000000000..1196bd28ad41d3fea908e8c375f73116bf44c877 GIT binary patch literal 1720 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 FV1m^XbN>JU literal 0 HcmV?d00001 diff --git a/src/Icons/sphere.png b/src/Icons/sphere.png new file mode 100644 index 0000000000000000000000000000000000000000..8cb92a1150cf57120b5bc4dab8bfab7a41fb442a GIT binary patch literal 337 zcmeAS@N?(olHy`uVBq!ia0vp^+#ogwGm!MqPT>SnEa{HEjtmSN`?>!lvI6-P0X`wF zk7PM|dwV~A{8(98xn;|irAwFY-@pIp(W9?ky=rW1eEIU_vuDrt?b~) z=*yQc#l^+*=g&_~O`SS*>b!aLjvP7C(a|ww%9N_Asqc zyLRnbvSi8c-@i9*+_-7erq{1u|NsC0?c2Bcj4eh$H!zk2`2{mLJiCzwvL>2=b zE)2qq4727)00r4gJbhi+ue0zAix^E4T^$P)^7nLc4B@z*oS?vGpvkq#$Z^K2LvLh~ zf?g$To3O*EyK9ZcjI(Rb96rAO5Ko%%ry}lxlZH(0fhdEP)YH7<}OQtKa`in=b!%@LTr3tmVr8=dXVM$Extb(_jBhoTmL>xccS)+xLI|U$E-M ze-oz}{~tX41=qj~WBlh1YG7gEWZ>fFX1ICx3&ZCxzZib~W@fl_;|s&7Lo*v07#J9s zV2ZC_zsq2tuf!lEz`>xTz{ema%Ee%yr@(OY`dzr~EHH+MhzNtRzA%HVBs+tIC=0{e z4}TdRJ>_P&d{qRl7;dt@t~|rdJD(Y}R5=)UxS1GK71$Z>Jp96-ry~bf%m`!Lef0Bx zR`C`FX=zCYEe$D#>o=b>Jbn6{VQP;zgR&euBZ^{}h7}v0Fq}AbgTcyNgCWdc2Ck5{ Z003k@U_tDpTVVhI002ovPDHLkV1f<`p5g!i literal 0 HcmV?d00001 diff --git a/src/Icons/url.png b/src/Icons/url.png new file mode 100644 index 0000000000000000000000000000000000000000..542ac36bb852514213a2824b7903aa900d18afd2 GIT binary patch literal 722 zcmV;@0xkWCP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXV` z2>~MTFL<~B00L4;L_t(2&n?o)P7`qez~SG2wsxF06qzp2uogvu2r(v@04gWq5;ZZY z7vt3j(8wF$*~EiaFB-#1F`DQ>5AJ9%Xi7}j0+gkc($aR?X*)As{GQ(5%<2~i6u<7;@lGTt=FzIe&8R*XtGj@skB|`FzqQg~@ zY}X|YU$(>oTnn`_=timG6KdX^*rIhrr+pxZ9#b)gifC1-ZZp~K+w4$i^o{Nu9ZJmR zGQa4$xX-}dd0NaIs@6wMicxdAs0QoU(o!`%6+G zkwp~8ZJ~gHV>8%Iq5|IoC%v0_h2b1A7fS|4_ynsi0_iiu7s9PsOhiY}Gabx%Iyp_J;iAZI|4x zL}6naYxxnzyB{)q@X+LaDx&HWzhhRBU?!EY$XsZq;PX>T3#!Xo)K;HRUVKAtqbUAY z3ZR<3D77)P$QbpW4xHc-T*pQ_+(G2NA~Nr(Y^8w1f3^PhuX(>TzyJUM07*qoM6N<$ Ef@_{b_5c6? literal 0 HcmV?d00001 diff --git a/src/Info.plist b/src/Info.plist new file mode 100644 index 000000000..8d31cb652 --- /dev/null +++ b/src/Info.plist @@ -0,0 +1,60 @@ + + + + + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + torrent + + CFBundleTypeIconFile + qBitTorrentDocument + CFBundleTypeName + BitTorrent Document + CFBundleTypeMIMETypes + + application/x-bittorrent + + CFBundleTypeRole + Viewer + LSHandlerRank + Owner + LSItemContentTypes + + org.bittorrent.torrent + + LSIsAppleDefaultForType + + + + CFBundleURLTypes + + + CFBundleURLSchemes + + magnet + + CFBundleURLName + BitTorrent Magnet URL + + + CFBundleIconFile + qbittorrent_mac.icns + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleGetInfoString + 2.8.1 + CFBundleSignature + ???? + CFBundleExecutable + qbittorrent + CFBundleIdentifier + org.qbittorrent + NOTE + This file was generated by Qt/QMake. + + diff --git a/src/about.qrc b/src/about.qrc new file mode 100644 index 000000000..b7126e9c4 --- /dev/null +++ b/src/about.qrc @@ -0,0 +1,6 @@ + + + gpl.html + + + diff --git a/src/about.ui b/src/about.ui new file mode 100644 index 000000000..122763fd9 --- /dev/null +++ b/src/about.ui @@ -0,0 +1,302 @@ + + + Christophe Dumez + AboutDlg + + + + 0 + 0 + 504 + 320 + + + + + 504 + 320 + + + + About qBittorrent + + + + + + + + + 22 + 22 + + + + + 22 + 22 + + + + + + + + + + + + 0 + 0 + + + + <h3><b>qBittorrent</b></h3> + + + Qt::RichText + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + + + + About + + + + + + + + + :/Icons/skin/mascot.png + + + + + + + + 0 + 0 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + Qt::RichText + + + true + + + Qt::AlignCenter + + + true + + + true + + + + + + + + Author + + + + 6 + + + + + + + + + Sans Serif + 9 + 50 + false + false + true + false + + + + Name: + + + + + + + Christophe Dumez + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + Sans Serif + 9 + 50 + false + false + true + false + + + + Country: + + + + + + + France + + + + + + + + Sans Serif + 9 + 50 + false + false + true + false + + + + E-mail: + + + + + + + chris@qbittorrent.org + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Thanks to + + + + 6 + + + + + + + + + Translation + + + + 6 + + + + + QTextEdit::NoWrap + + + + + + + + License + + + + 6 + + + + + + + + + + + + + + + + + diff --git a/src/about_imp.h b/src/about_imp.h new file mode 100644 index 000000000..488df18ef --- /dev/null +++ b/src/about_imp.h @@ -0,0 +1,106 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef ABOUT_H +#define ABOUT_H + +#include "ui_about.h" +#include + +class about : public QDialog, private Ui::AboutDlg{ + Q_OBJECT + + public: + ~about() { + qDebug("Deleting about dlg"); + } + + about(QWidget *parent): QDialog(parent){ + setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + // Set icons + logo->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/qbittorrent22.png"))); + //Title + lb_name->setText(QString::fromUtf8("

")+tr("qBittorrent")+QString::fromUtf8(" "VERSION"

")); + // Thanks + QString thanks_txt; + thanks_txt += QString::fromUtf8("

I would first like to thank sourceforge.net for hosting qBittorrent project and for their support.

"); + thanks_txt += QString::fromUtf8("

I am pleased that people from all over the world are contributing to qBittorrent: Ishan Arora (India), Arnaud Demaizière (France) and Stephanos Antaris (Greece). Their help is greatly appreciated

"); + thanks_txt += QString::fromUtf8("

I also want to thank Στέφανος Αντάρης (santaris@csd.auth.gr) and Mirco Chinelli (infinity89@fastwebmail.it) for working on Mac OS X packaging.

"); + thanks_txt += QString::fromUtf8("

I am grateful to Peter Koeleman (peter@qbittorrent.org) and Mohammad Dib (mdib@qbittorrent.org) for working on qBittorrent port to Windows.

"); + thanks_txt += QString::fromUtf8("

Thanks a lot to our graphist Mateusz Toboła (tobejodok@qbittorrent.org) for his great work.

"); + te_thanks->setHtml(thanks_txt); + // Translation + QString trans_txt = "

"+tr("I would like to thank the following people who volunteered to translate qBittorrent:")+"

"; + trans_txt += QString::fromUtf8("
  • Arabic: SDERAWI (abz8868@msn.com) and sn51234 (nesseyan@gmail.com)
  • \ +
  • Armenian: Hrant Ohanyan (hrantohanyan@mail.am)
  • \ +
  • Brazilian: Nick Marinho (nickmarinho@gmail.com)
  • \ +
  • Bulgarian: Tsvetan & Boyko Bankoff (emerge_life@users.sourceforge.net)
  • \ +
  • Catalan: Francisco Luque Contreras (frannoe@ya.com)
  • \ +
  • Chinese (Simplified): Guo Yue (yue.guo0418@gmail.com)
  • \ +
  • Chinese (Traditional): Yi-Shun Wang (dnextstep@gmail.com)
  • \ +
  • Croatian: Oliver Mucafir (oliver.untwist@gmail.com)
  • \ +
  • Czech: Jirka Vilim (web@tets.cz)
  • \ +
  • Danish: Mathias Nielsen (comoneo@gmail.com)
  • \ +
  • Dutch: Pieter Heyvaert (pieter_heyvaert@hotmail.com)
  • \ +
  • Finnish: Niklas Laxström (nikerabbit@users.sourceforge.net) and Pekka Niemi (pekka.niemi@iki.fi)
  • \ +
  • Galician: Marcos Lans (marcoslansgarza@gmail.com)
  • \ +
  • German: Niels Hoffmann (zentralmaschine@users.sourceforge.net)
  • \ +
  • Greek: Tsvetan Bankov (emerge_life@users.sourceforge.net)
  • \ +
  • Hungarian: Majoros Péter (majoros.peterj@gmail.com)
  • \ +
  • Italian: Matteo Sechi (bu17714@gmail.com)
  • \ +
  • Japanese: Masato Hashimoto (cabezon.hashimoto@gmail.com)
  • \ +
  • Korean: Jin Woo Sin (jin828sin@users.sourceforge.net)
  • \ +
  • Lithuanian: Naglis Jonaitis (njonaitis@gmail.com)
  • \ +
  • Norwegian: Tomaso
  • \ +
  • Polish: Mariusz Fik (fisiu@opensuse.org)
  • \ +
  • Portuguese: Nick Marinho (nickmarinho@gmail.com)
  • \ +
  • Romanian: Obada Denis (obadadenis@users.sourceforge.net)
  • \ +
  • Russian: Nick Khazov (m2k3d0n@users.sourceforge.net) and Alexey Morsov (samurai@ricom.ru)
  • \ +
  • Serbian: Anaximandar Milet (anaximandar@operamail.com)
  • \ +
  • Slovak: helix84
  • \ +
  • Spanish: Francisco Luque Contreras (frannoe@ya.com)
  • \ +
  • Swedish: Daniel Nylander (po@danielnylander.se)
  • \ +
  • Turkish: Hasan YILMAZ (iletisim@hedefturkce.com) and Erdem Bingöl (erdem84@gmail.com)
  • \ +
  • Ukrainian: Andrey Shpachenko (masterfix@users.sourceforge.net) and Oleh Prypin (blaxpirit@gmail.com)
"); + trans_txt += "

"+tr("Please contact me if you would like to translate qBittorrent into your own language.")+"

"; + te_translation->setHtml(trans_txt); + // License + te_license->append(QString::fromUtf8("
")); + QFile licensefile(":/gpl.html"); + if(licensefile.open(QIODevice::ReadOnly|QIODevice::Text)) { + te_license->setHtml(licensefile.readAll()); + licensefile.close(); + } + show(); + } +}; + +#endif diff --git a/src/bandwidth_limit.ui b/src/bandwidth_limit.ui new file mode 100644 index 000000000..25bf4caed --- /dev/null +++ b/src/bandwidth_limit.ui @@ -0,0 +1,97 @@ + + + bandwidth_dlg + + + + 0 + 0 + 338 + 83 + + + + Bandwidth allocation + + + + + + + + 0 + + + 1000 + + + 0 + + + Qt::Horizontal + + + + + + + + + + 10000 + + + 0 + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + rejected() + bandwidth_dlg + reject() + + + 221 + 73 + + + 221 + 82 + + + + + buttonBox + accepted() + bandwidth_dlg + accept() + + + 277 + 59 + + + 343 + 80 + + + + + diff --git a/src/confirmdeletiondlg.ui b/src/confirmdeletiondlg.ui new file mode 100644 index 000000000..1e53b5d62 --- /dev/null +++ b/src/confirmdeletiondlg.ui @@ -0,0 +1,153 @@ + + + confirmDeletionDlg + + + + 0 + 0 + 463 + 128 + + + + + 0 + 0 + + + + Deletion confirmation - qBittorrent + + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + Are you sure you want to delete the selected torrents from the transfer list? + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + + + + + + + + + false + + + Remember choice + + + + + + + 24 + 24 + + + + + + + + + 0 + 0 + + + + + true + + + + Also delete the files on the hard disk + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + confirmDeletionDlg + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + confirmDeletionDlg + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/deletionconfirmationdlg.h b/src/deletionconfirmationdlg.h new file mode 100644 index 000000000..186ebc0fc --- /dev/null +++ b/src/deletionconfirmationdlg.h @@ -0,0 +1,80 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef DELETIONCONFIRMATIONDLG_H +#define DELETIONCONFIRMATIONDLG_H + +#include +#include "ui_confirmdeletiondlg.h" +#include "preferences.h" +#include "iconprovider.h" + +class DeletionConfirmationDlg : public QDialog, private Ui::confirmDeletionDlg { + Q_OBJECT + + public: + DeletionConfirmationDlg(QWidget *parent=0): QDialog(parent) { + setupUi(this); + // Icons + lbl_warn->setPixmap(IconProvider::instance()->getIcon("dialog-warning").pixmap(lbl_warn->height())); + lbl_warn->setFixedWidth(lbl_warn->height()); + rememberBtn->setIcon(IconProvider::instance()->getIcon("object-locked")); + + move(misc::screenCenter(this)); + checkPermDelete->setChecked(Preferences().deleteTorrentFilesAsDefault()); + connect(checkPermDelete, SIGNAL(clicked()), this, SLOT(updateRememberButtonState())); + buttonBox->setFocus(); + } + + bool shouldDeleteLocalFiles() const { + return checkPermDelete->isChecked(); + } + + static bool askForDeletionConfirmation(bool *delete_local_files) { + DeletionConfirmationDlg dlg; + if(dlg.exec() == QDialog::Accepted) { + *delete_local_files = dlg.shouldDeleteLocalFiles(); + return true; + } + return false; + } + +private slots: + void updateRememberButtonState() { + rememberBtn->setEnabled(checkPermDelete->isChecked() != Preferences().deleteTorrentFilesAsDefault()); + } + + void on_rememberBtn_clicked() { + Preferences().setDeleteTorrentFilesAsDefault(checkPermDelete->isChecked()); + rememberBtn->setEnabled(false); + } +}; + +#endif // DELETIONCONFIRMATIONDLG_H diff --git a/src/dnsupdater.cpp b/src/dnsupdater.cpp new file mode 100644 index 000000000..d4b4ef284 --- /dev/null +++ b/src/dnsupdater.cpp @@ -0,0 +1,288 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include "dnsupdater.h" +#include "qbtsession.h" + +DNSUpdater::DNSUpdater(QObject *parent) : + QObject(parent), m_state(OK), m_service(DNS::NONE) +{ + updateCredentials(); + + // Load saved settings from previous session + QIniSettings settings("qBittorrent", "qBittorrent"); + m_lastIPCheckTime = settings.value("DNSUpdater/lastUpdateTime").toDateTime(); + m_lastIP = QHostAddress(settings.value("DNSUpdater/lastIP").toString()); + + // Start IP checking timer + m_ipCheckTimer.setInterval(IP_CHECK_INTERVAL_MS); + connect(&m_ipCheckTimer, SIGNAL(timeout()), SLOT(checkPublicIP())); + m_ipCheckTimer.start(); + + // Check lastUpdate to avoid flooding + if(!m_lastIPCheckTime.isValid() || + m_lastIPCheckTime.secsTo(QDateTime::currentDateTime())*1000 > IP_CHECK_INTERVAL_MS) { + checkPublicIP(); + } +} + +DNSUpdater::~DNSUpdater() { + // Save lastupdate time and last ip + QIniSettings settings("qBittorrent", "qBittorrent"); + settings.setValue("DNSUpdater/lastUpdateTime", m_lastIPCheckTime); + settings.setValue("DNSUpdater/lastIP", m_lastIP.toString()); +} + +void DNSUpdater::checkPublicIP() +{ + Q_ASSERT(m_state == OK); + QNetworkAccessManager *manager = new QNetworkAccessManager(this); + connect(manager, SIGNAL(finished(QNetworkReply*)), + SLOT(ipRequestFinished(QNetworkReply*))); + m_lastIPCheckTime = QDateTime::currentDateTime(); + QNetworkRequest request; + request.setUrl(QUrl("http://checkip.dyndns.org")); + request.setRawHeader("User-Agent", "qBittorrent/"VERSION" chris@qbittorrent.org"); + manager->get(request); +} + +void DNSUpdater::ipRequestFinished(QNetworkReply *reply) +{ + qDebug() << Q_FUNC_INFO; + if(reply->error()) { + // Error + qWarning() << Q_FUNC_INFO << "Error:" << reply->errorString(); + } else { + // Parse response + QRegExp ipregex("Current IP Address:\\s+([^<]+)"); + QString ret = reply->readAll(); + if(ipregex.indexIn(ret) >= 0) { + QString ip_str = ipregex.cap(1); + qDebug() << Q_FUNC_INFO << "Regular expression captured the following IP:" << ip_str; + QHostAddress new_ip(ip_str); + if(!new_ip.isNull()) { + if(m_lastIP != new_ip) { + qDebug() << Q_FUNC_INFO << "The IP address changed, report the change to DynDNS..."; + qDebug() << m_lastIP.toString() << "->" << new_ip.toString(); + m_lastIP = new_ip; + updateDNSService(); + } + } else { + qWarning() << Q_FUNC_INFO << "Failed to construct a QHostAddress from the IP string"; + } + } else { + qWarning() << Q_FUNC_INFO << "Regular expression failed ot capture the IP address"; + } + } + // Clean up + reply->deleteLater(); + sender()->deleteLater(); +} + +void DNSUpdater::updateDNSService() +{ + qDebug() << Q_FUNC_INFO; + // Prepare request + QNetworkAccessManager *manager = new QNetworkAccessManager(this); + connect(manager, SIGNAL(finished(QNetworkReply*)), + SLOT(ipUpdateFinished(QNetworkReply*))); + m_lastIPCheckTime = QDateTime::currentDateTime(); + QNetworkRequest request; + request.setUrl(getUpdateUrl()); + request.setRawHeader("User-Agent", "qBittorrent/"VERSION" chris@qbittorrent.org"); + manager->get(request); +} + +QUrl DNSUpdater::getUpdateUrl() const +{ + QUrl url; +#ifdef QT_NO_OPENSSL + url.setScheme("http"); +#else + url.setScheme("https"); +#endif + url.setUserName(m_username); + url.setPassword(m_password); + + Q_ASSERT(!m_lastIP.isNull()); + // Service specific + switch(m_service) { + case DNS::DYNDNS: + url.setHost("members.dyndns.org"); + break; + case DNS::NOIP: + url.setHost("dynupdate.no-ip.com"); + break; + default: + qWarning() << "Unrecognized Dynamic DNS service!"; + Q_ASSERT(0); + } + url.setPath("/nic/update"); + url.addQueryItem("hostname", m_domain); + url.addQueryItem("myip", m_lastIP.toString()); + Q_ASSERT(url.isValid()); + qDebug() << Q_FUNC_INFO << url.toString(); + return url; +} + +void DNSUpdater::ipUpdateFinished(QNetworkReply *reply) +{ + if(reply->error()) { + // Error + qWarning() << Q_FUNC_INFO << "Error:" << reply->errorString(); + } else { + // Pase reply + processIPUpdateReply(reply->readAll()); + } + // Clean up + reply->deleteLater(); + sender()->deleteLater(); +} + +void DNSUpdater::processIPUpdateReply(const QString &reply) +{ + qDebug() << Q_FUNC_INFO << reply; + QString code = reply.split(" ").first(); + qDebug() << Q_FUNC_INFO << "Code:" << code; + if(code == "good" || code == "nochg") { + QBtSession::instance()->addConsoleMessage(tr("Your dynamic DNS was successfuly updated."), "green"); + return; + } + if(code == "911" || code == "dnserr") { + QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes."), + "red"); + m_lastIP.clear(); + // It will retry in 30 minutes because the timer was not stopped + return; + } + // Everything bellow is an error, stop updating until the user updates something + m_ipCheckTimer.stop(); + m_lastIP.clear(); + if(code == "nohost") { + QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: hostname supplied does not exist under specified account."), + "red"); + m_state = INVALID_CREDS; + return; + } + if(code == "badauth") { + QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: Invalid username/password."), "red"); + m_state = INVALID_CREDS; + return; + } + if(code == "badagent") { + QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org."), + "red"); + m_state = FATAL; + return; + } + if(code == "!donator") { + QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org.").arg("!donator"), + "red"); + m_state = FATAL; + return; + } + if(code == "abuse") { + QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: Your username was blocked due to abuse."), + "red"); + m_state = FATAL; + return; + } +} + +void DNSUpdater::updateCredentials() +{ + if(m_state == FATAL) return; + Preferences pref; + bool change = false; + // Get DNS service information + if(m_service != pref.getDynDNSService()) { + m_service = pref.getDynDNSService(); + change = true; + } + if(m_domain != pref.getDynDomainName()) { + m_domain = pref.getDynDomainName(); + QRegExp domain_regex("^(?:(?!\\d|-)[a-zA-Z0-9\\-]{1,63}\\.)+[a-zA-Z]{2,}$"); + if(domain_regex.indexIn(m_domain) < 0) { + QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: supplied domain name is invalid."), + "red"); + m_lastIP.clear(); + m_ipCheckTimer.stop(); + m_state = INVALID_CREDS; + return; + } + change = true; + } + if(m_username != pref.getDynDNSUsername()) { + m_username = pref.getDynDNSUsername(); + if(m_username.length() < 4) { + QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: supplied username is too short."), + "red"); + m_lastIP.clear(); + m_ipCheckTimer.stop(); + m_state = INVALID_CREDS; + return; + } + change = true; + } + if(m_password != pref.getDynDNSPassword()) { + m_password = pref.getDynDNSPassword(); + if(m_password.length() < 4) { + QBtSession::instance()->addConsoleMessage(tr("Dynamic DNS error: supplied password is too short."), + "red"); + m_lastIP.clear(); + m_ipCheckTimer.stop(); + m_state = INVALID_CREDS; + return; + } + change = true; + } + + if(m_state == INVALID_CREDS && change) { + m_state = OK; // Try again + m_ipCheckTimer.start(); + checkPublicIP(); + } +} + +QUrl DNSUpdater::getRegistrationUrl(int service) +{ + switch(service) { + case DNS::DYNDNS: + return QUrl("https://www.dyndns.com/account/services/hosts/add.html"); + case DNS::NOIP: + return QUrl("http://www.no-ip.com/services/managed_dns/free_dynamic_dns.html"); + default: + Q_ASSERT(0); + } + return QUrl(); +} diff --git a/src/dnsupdater.h b/src/dnsupdater.h new file mode 100644 index 000000000..3ea9a5cd3 --- /dev/null +++ b/src/dnsupdater.h @@ -0,0 +1,81 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef DNSUPDATER_H +#define DNSUPDATER_H + +#include +#include +#include +#include +#include +#include "preferences.h" + +/*! + * Based on http://www.dyndns.com/developers/specs/ + */ +class DNSUpdater : public QObject +{ + Q_OBJECT +public: + explicit DNSUpdater(QObject *parent = 0); + ~DNSUpdater(); + static QUrl getRegistrationUrl(int service); + +public slots: + void updateCredentials(); + +private slots: + void checkPublicIP(); + void ipRequestFinished(QNetworkReply* reply); + void updateDNSService(); + void ipUpdateFinished(QNetworkReply* reply); + +private: + QUrl getUpdateUrl() const; + void processIPUpdateReply(const QString &reply); + +private: + QHostAddress m_lastIP; + QDateTime m_lastIPCheckTime; + QTimer m_ipCheckTimer; + int m_state; + // Service creds + DNS::Service m_service; + QString m_domain; + QString m_username; + QString m_password; + +private: + static const int IP_CHECK_INTERVAL_MS = 1800000; // 30 min + enum State { OK, INVALID_CREDS, FATAL }; +}; + +#endif // DNSUPDATER_H diff --git a/src/downloadfromurldlg.h b/src/downloadfromurldlg.h new file mode 100644 index 000000000..364c49b77 --- /dev/null +++ b/src/downloadfromurldlg.h @@ -0,0 +1,91 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef DOWNLOADFROMURL_H +#define DOWNLOADFROMURL_H + +#include +#include +#include +#include +#include +#include +#include "ui_downloadfromurldlg.h" + +class downloadFromURL : public QDialog, private Ui::downloadFromURL{ + Q_OBJECT + + public: + downloadFromURL(QWidget *parent): QDialog(parent){ + setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + setModal(true); + show(); + // Paste clipboard if there is an URL in it + QString clip_txt = qApp->clipboard()->text(); + if(clip_txt.startsWith("http://", Qt::CaseInsensitive) || clip_txt.startsWith("https://", Qt::CaseInsensitive) || clip_txt.startsWith("ftp://", Qt::CaseInsensitive) || clip_txt.startsWith("magnet:", Qt::CaseInsensitive) || clip_txt.startsWith("bc://bt/", Qt::CaseInsensitive)) { + textUrls->setText(clip_txt); + } + } + + ~downloadFromURL(){} + + signals: + void urlsReadyToBeDownloaded(const QStringList& torrent_urls); + + public slots: + void on_downloadButton_clicked(){ + QString urls = textUrls->toPlainText(); + QStringList url_list = urls.split(QString::fromUtf8("\n")); + QString url; + QStringList url_list_cleaned; + foreach(url, url_list){ + url = url.trimmed(); + if(!url.isEmpty()){ + if(url_list_cleaned.indexOf(QRegExp(url, Qt::CaseInsensitive, QRegExp::FixedString)) < 0){ + url_list_cleaned << url; + } + } + } + if(!url_list_cleaned.size()){ + QMessageBox::critical(0, tr("No URL entered"), tr("Please type at least one URL.")); + return; + } + emit urlsReadyToBeDownloaded(url_list_cleaned); + qDebug("Emitted urlsReadytobedownloaded signal"); + close(); + } + + void on_cancelButton_clicked(){ + close(); + } +}; + +#endif diff --git a/src/downloadfromurldlg.ui b/src/downloadfromurldlg.ui new file mode 100644 index 000000000..0c253ee29 --- /dev/null +++ b/src/downloadfromurldlg.ui @@ -0,0 +1,136 @@ + + + downloadFromURL + + + + 0 + 0 + 482 + 220 + + + + Download from urls + + + + 6 + + + 9 + + + + + 6 + + + 0 + + + + + + Sans Serif + 12 + 75 + false + true + false + false + + + + Add torrent links + + + + + + + + + false + + + + + + + + 16777215 + 17 + + + + + Sans Serif + 9 + 50 + true + false + false + false + + + + Both HTTP and Magnet links are supported + + + + + + + 6 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Download + + + + + + + Cancel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + diff --git a/src/downloadthread.cpp b/src/downloadthread.cpp new file mode 100644 index 000000000..c052ce3b3 --- /dev/null +++ b/src/downloadthread.cpp @@ -0,0 +1,261 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include +#include +#include + +#include "downloadthread.h" +#include "preferences.h" +#ifndef DISABLE_GUI +#include "rsssettings.h" +#endif +#include "qinisettings.h" + +/** Download Thread **/ + +DownloadThread::DownloadThread(QObject* parent) : QObject(parent) { + connect(&m_networkManager, SIGNAL(finished (QNetworkReply*)), this, SLOT(processDlFinished(QNetworkReply*))); +#ifndef QT_NO_OPENSSL + connect(&m_networkManager, SIGNAL(sslErrors(QNetworkReply*,QList)), this, SLOT(ignoreSslErrors(QNetworkReply*,QList))); +#endif +} + +void DownloadThread::processDlFinished(QNetworkReply* reply) { + QString url = reply->url().toString(); + qDebug("Download finished: %s", qPrintable(url)); + // Check if the request was successful + if(reply->error() != QNetworkReply::NoError) { + // Failure + qDebug("Download failure (%s), reason: %s", qPrintable(url), qPrintable(errorCodeToString(reply->error()))); + emit downloadFailure(url, errorCodeToString(reply->error())); + reply->deleteLater(); + return; + } + // Check if the server ask us to redirect somewhere lese + const QVariant redirection = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if(redirection.isValid()) { + // We should redirect + qDebug("Redirecting from %s to %s", qPrintable(url), qPrintable(redirection.toUrl().toString())); + m_redirectMapping.insert(redirection.toUrl().toString(), url); + downloadUrl(redirection.toUrl().toString()); + reply->deleteLater(); + return; + } + // Checking if it was redirected, restoring initial URL + if(m_redirectMapping.contains(url)) { + url = m_redirectMapping.take(url); + } + // Success + QTemporaryFile *tmpfile = new QTemporaryFile; + tmpfile->setAutoRemove(false); + if (tmpfile->open()) { + QString filePath = tmpfile->fileName(); + qDebug("Temporary filename is: %s", qPrintable(filePath)); + if(reply->isOpen() || reply->open(QIODevice::ReadOnly)) { + // TODO: Support GZIP compression + tmpfile->write(reply->readAll()); + tmpfile->close(); + // XXX: For some reason, tmpfile has to be destroyed before + // the signal is sent or the file stays locked on Windows + // for some reason. + delete tmpfile; + // Send finished signal + emit downloadFinished(url, filePath); + } else { + delete tmpfile; + // Error when reading the request + emit downloadFailure(url, tr("I/O Error")); + } + } else { + delete tmpfile; + emit downloadFailure(url, tr("I/O Error")); + } + // Clean up + reply->deleteLater(); +} + +#ifndef DISABLE_GUI +void DownloadThread::loadCookies(const QString &host_name, QString url) { + const QList raw_cookies = RssSettings().getHostNameCookies(host_name); + QNetworkCookieJar *cookie_jar = m_networkManager.cookieJar(); + QList cookies; + qDebug("Loading cookies for host name: %s", qPrintable(host_name)); + foreach(const QByteArray& raw_cookie, raw_cookies) { + QList cookie_parts = raw_cookie.split('='); + if(cookie_parts.size() == 2) { + qDebug("Loading cookie: %s", raw_cookie.constData()); + cookies << QNetworkCookie(cookie_parts.first(), cookie_parts.last()); + } + } + cookie_jar->setCookiesFromUrl(cookies, url); + m_networkManager.setCookieJar(cookie_jar); +} +#endif + +void DownloadThread::downloadTorrentUrl(const QString &url) { + // Process request + QNetworkReply *reply = downloadUrl(url); + connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(checkDownloadSize(qint64,qint64))); +} + +QNetworkReply* DownloadThread::downloadUrl(const QString &url){ + // Update proxy settings + applyProxySettings(); +#ifndef DISABLE_GUI + // Load cookies + QString host_name = QUrl::fromEncoded(url.toUtf8()).host(); + if(!host_name.isEmpty()) + loadCookies(host_name, url); +#endif + // Process download request + qDebug("url is %s", qPrintable(url)); + const QUrl qurl = QUrl::fromEncoded(url.toUtf8()); + QNetworkRequest request(qurl); + // Spoof Firefox 3.5 user agent to avoid + // Web server banning + request.setRawHeader("User-Agent", "Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5"); + qDebug("Downloading %s...", request.url().toEncoded().data()); + qDebug("%d cookies for this URL", m_networkManager.cookieJar()->cookiesForUrl(url).size()); + for(int i=0; icookiesForUrl(url).size(); ++i) { + qDebug("%s=%s", m_networkManager.cookieJar()->cookiesForUrl(url).at(i).name().data(), m_networkManager.cookieJar()->cookiesForUrl(url).at(i).value().data()); + qDebug("Domain: %s, Path: %s", qPrintable(m_networkManager.cookieJar()->cookiesForUrl(url).at(i).domain()), qPrintable(m_networkManager.cookieJar()->cookiesForUrl(url).at(i).path())); + } + return m_networkManager.get(request); +} + +void DownloadThread::checkDownloadSize(qint64 bytesReceived, qint64 bytesTotal) { + QNetworkReply *reply = qobject_cast(sender()); + if(!reply) return; + if(bytesTotal > 0) { + // Total number of bytes is available + if(bytesTotal > 1048576) { + // More than 1MB, this is probably not a torrent file, aborting... + reply->abort(); + reply->deleteLater(); + } else { + disconnect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(checkDownloadSize(qint64,qint64))); + } + } else { + if(bytesReceived > 1048576) { + // More than 1MB, this is probably not a torrent file, aborting... + reply->abort(); + reply->deleteLater(); + } + } +} + +void DownloadThread::applyProxySettings() { + QNetworkProxy proxy; + const Preferences pref; + if(pref.isProxyEnabled()) { + // Proxy enabled + proxy.setHostName(pref.getProxyIp()); + proxy.setPort(pref.getProxyPort()); + // Default proxy type is HTTP, we must change if it is SOCKS5 + const int proxy_type = pref.getProxyType(); + if(proxy_type == Proxy::SOCKS5 || proxy_type == Proxy::SOCKS5_PW) { + qDebug() << Q_FUNC_INFO << "using SOCKS proxy"; + proxy.setType(QNetworkProxy::Socks5Proxy); + } else { + qDebug() << Q_FUNC_INFO << "using HTTP proxy"; + proxy.setType(QNetworkProxy::HttpProxy); + } + // Authentication? + if(pref.isProxyAuthEnabled()) { + qDebug("Proxy requires authentication, authenticating"); + proxy.setUser(pref.getProxyUsername()); + proxy.setPassword(pref.getProxyPassword()); + } + } else { + proxy.setType(QNetworkProxy::NoProxy); + } + m_networkManager.setProxy(proxy); +} + +QString DownloadThread::errorCodeToString(QNetworkReply::NetworkError status) { + switch(status){ + case QNetworkReply::HostNotFoundError: + return tr("The remote host name was not found (invalid hostname)"); + case QNetworkReply::OperationCanceledError: + return tr("The operation was canceled"); + case QNetworkReply::RemoteHostClosedError: + return tr("The remote server closed the connection prematurely, before the entire reply was received and processed"); + case QNetworkReply::TimeoutError: + return tr("The connection to the remote server timed out"); + case QNetworkReply::SslHandshakeFailedError: + return tr("SSL/TLS handshake failed"); + case QNetworkReply::ConnectionRefusedError: + return tr("The remote server refused the connection"); + case QNetworkReply::ProxyConnectionRefusedError: + return tr("The connection to the proxy server was refused"); + case QNetworkReply::ProxyConnectionClosedError: + return tr("The proxy server closed the connection prematurely"); + case QNetworkReply::ProxyNotFoundError: + return tr("The proxy host name was not found"); + case QNetworkReply::ProxyTimeoutError: + return tr("The connection to the proxy timed out or the proxy did not reply in time to the request sent"); + case QNetworkReply::ProxyAuthenticationRequiredError: + return tr("The proxy requires authentication in order to honour the request but did not accept any credentials offered"); + case QNetworkReply::ContentAccessDenied: + return tr("The access to the remote content was denied (401)"); + case QNetworkReply::ContentOperationNotPermittedError: + return tr("The operation requested on the remote content is not permitted"); + case QNetworkReply::ContentNotFoundError: + return tr("The remote content was not found at the server (404)"); + case QNetworkReply::AuthenticationRequiredError: + return tr("The remote server requires authentication to serve the content but the credentials provided were not accepted"); + case QNetworkReply::ProtocolUnknownError: + return tr("The Network Access API cannot honor the request because the protocol is not known"); + case QNetworkReply::ProtocolInvalidOperationError: + return tr("The requested operation is invalid for this protocol"); + case QNetworkReply::UnknownNetworkError: + return tr("An unknown network-related error was detected"); + case QNetworkReply::UnknownProxyError: + return tr("An unknown proxy-related error was detected"); + case QNetworkReply::UnknownContentError: + return tr("An unknown error related to the remote content was detected"); + case QNetworkReply::ProtocolFailure: + return tr("A breakdown in protocol was detected"); + default: + return tr("Unknown error"); + } +} + +#ifndef QT_NO_OPENSSL +void DownloadThread::ignoreSslErrors(QNetworkReply* reply, const QList &errors) { + Q_UNUSED(errors) + // Ignore all SSL errors + reply->ignoreSslErrors(); +} +#endif diff --git a/src/downloadthread.h b/src/downloadthread.h new file mode 100644 index 000000000..3115c3588 --- /dev/null +++ b/src/downloadthread.h @@ -0,0 +1,76 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef DOWNLOADTHREAD_H +#define DOWNLOADTHREAD_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QNetworkAccessManager; +QT_END_NAMESPACE + +class DownloadThread : public QObject { + Q_OBJECT + +public: + DownloadThread(QObject* parent = 0); + QNetworkReply* downloadUrl(const QString &url); + void downloadTorrentUrl(const QString &url); + //void setProxy(QString IP, int port, QString username, QString password); + +signals: + void downloadFinished(const QString &url, const QString &file_path); + void downloadFailure(const QString &url, const QString &reason); + +private slots: + void processDlFinished(QNetworkReply* reply); + void checkDownloadSize(qint64 bytesReceived, qint64 bytesTotal); +#ifndef QT_NO_OPENSSL + void ignoreSslErrors(QNetworkReply*,const QList&); +#endif + +private: + QString errorCodeToString(QNetworkReply::NetworkError status); + void applyProxySettings(); +#ifndef DISABLE_GUI + void loadCookies(const QString &host_name, QString url); +#endif + +private: + QNetworkAccessManager m_networkManager; + QHash m_redirectMapping; + +}; + +#endif diff --git a/src/executionlog.cpp b/src/executionlog.cpp new file mode 100644 index 000000000..c175c44dc --- /dev/null +++ b/src/executionlog.cpp @@ -0,0 +1,32 @@ +#include "executionlog.h" +#include "ui_executionlog.h" +#include "qbtsession.h" +#include "iconprovider.h" + +ExecutionLog::ExecutionLog(QWidget *parent) : + QWidget(parent), + ui(new Ui::ExecutionLog) +{ + ui->setupUi(this); + ui->tabConsole->setTabIcon(0, IconProvider::instance()->getIcon("view-calendar-journal")); + ui->tabConsole->setTabIcon(1, IconProvider::instance()->getIcon("view-filter")); + ui->textConsole->setHtml(QBtSession::instance()->getConsoleMessages().join("
")); + connect(QBtSession::instance(), SIGNAL(newConsoleMessage(QString)), SLOT(addLogMessage(QString))); + ui->textBannedPeers->setHtml(QBtSession::instance()->getPeerBanMessages().join("
")); + connect(QBtSession::instance(), SIGNAL(newBanMessage(QString)), SLOT(addBanMessage(QString))); +} + +ExecutionLog::~ExecutionLog() +{ + delete ui; +} + +void ExecutionLog::addLogMessage(const QString &msg) +{ + ui->textConsole->setHtml(msg+ui->textConsole->toHtml()); +} + +void ExecutionLog::addBanMessage(const QString &msg) +{ + ui->textBannedPeers->setHtml(msg+ui->textBannedPeers->toHtml()); +} diff --git a/src/executionlog.h b/src/executionlog.h new file mode 100644 index 000000000..bc51e27eb --- /dev/null +++ b/src/executionlog.h @@ -0,0 +1,28 @@ +#ifndef EXECUTIONLOG_H +#define EXECUTIONLOG_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { + class ExecutionLog; +} +QT_END_NAMESPACE + +class ExecutionLog : public QWidget +{ + Q_OBJECT + +public: + explicit ExecutionLog(QWidget *parent = 0); + ~ExecutionLog(); + +public slots: + void addLogMessage(const QString &msg); + void addBanMessage(const QString &msg); + +private: + Ui::ExecutionLog *ui; +}; + +#endif // EXECUTIONLOG_H diff --git a/src/executionlog.ui b/src/executionlog.ui new file mode 100644 index 000000000..9e8e05b6f --- /dev/null +++ b/src/executionlog.ui @@ -0,0 +1,51 @@ + + + ExecutionLog + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + QTabWidget::East + + + 0 + + + + General + + + + + + + + + + Blocked IPs + + + + + + + + + + + + + + diff --git a/src/filesystemwatcher.h b/src/filesystemwatcher.h new file mode 100644 index 000000000..a16ac0d9b --- /dev/null +++ b/src/filesystemwatcher.h @@ -0,0 +1,290 @@ +#ifndef FILESYSTEMWATCHER_H +#define FILESYSTEMWATCHER_H + +#include +#include +#include +#include +#include +#include + +#ifndef Q_WS_WIN +#include +#include +#include +#if defined(Q_WS_MAC) || defined(Q_OS_FREEBSD) +#include +#include +#include +#else +#include +#endif +#endif + +#include "misc.h" + +#ifndef CIFS_MAGIC_NUMBER +#define CIFS_MAGIC_NUMBER 0xFF534D42 +#endif + +#ifndef NFS_SUPER_MAGIC +#define NFS_SUPER_MAGIC 0x6969 +#endif + +#ifndef SMB_SUPER_MAGIC +#define SMB_SUPER_MAGIC 0x517B +#endif + +const int WATCH_INTERVAL = 10000; // 10 sec +const int MAX_PARTIAL_RETRIES = 5; + +/* + * Subclassing QFileSystemWatcher in order to support Network File + * System watching (NFS, CIFS) on Linux and Mac OS. + */ +class FileSystemWatcher: public QFileSystemWatcher { + Q_OBJECT + +private: +#ifndef Q_WS_WIN + QList watched_folders; + QPointer watch_timer; +#endif + QStringList m_filters; + // Partial torrents + QHash m_partialTorrents; + QPointer m_partialTorrentTimer; + +#ifndef Q_WS_WIN +private: + static bool isNetworkFileSystem(QString path) { + QString file = path; + if(!file.endsWith(QDir::separator())) + file += QDir::separator(); + file += "."; + struct statfs buf; + if(!statfs(file.toLocal8Bit().constData(), &buf)) { +#ifdef Q_WS_MAC + // XXX: should we make sure HAVE_STRUCT_FSSTAT_F_FSTYPENAME is defined? + return (strcmp(buf.f_fstypename, "nfs") == 0 || strcmp(buf.f_fstypename, "cifs") == 0 || strcmp(buf.f_fstypename, "smbfs") == 0); +#else + return (buf.f_type == (long)CIFS_MAGIC_NUMBER || buf.f_type == (long)NFS_SUPER_MAGIC || buf.f_type == (long)SMB_SUPER_MAGIC); +#endif + } else { + std::cerr << "Error: statfs() call failed for " << qPrintable(file) << ". Supposing it is a local folder..." << std::endl; + switch(errno) { + case EACCES: + std::cerr << "Search permission is denied for a component of the path prefix of the path" << std::endl; + break; + case EFAULT: + std::cerr << "Buf or path points to an invalid address" << std::endl; + break; + case EINTR: + std::cerr << "This call was interrupted by a signal" << std::endl; + break; + case EIO: + std::cerr << "I/O Error" << std::endl; + break; + case ELOOP: + std::cerr << "Too many symlinks" << std::endl; + break; + case ENAMETOOLONG: + std::cerr << "path is too long" << std::endl; + break; + case ENOENT: + std::cerr << "The file referred by path does not exist" << std::endl; + break; + case ENOMEM: + std::cerr << "Insufficient kernel memory" << std::endl; + break; + case ENOSYS: + std::cerr << "The file system does not detect this call" << std::endl; + break; + case ENOTDIR: + std::cerr << "A component of the path is not a directory" << std::endl; + break; + case EOVERFLOW: + std::cerr << "Some values were too large to be represented in the struct" << std::endl; + break; + default: + std::cerr << "Unknown error" << std::endl; + } + std::cerr << "Errno: " << errno << std::endl; + return false; + } + + } +#endif + +public: + FileSystemWatcher(QObject *parent): QFileSystemWatcher(parent) { + m_filters << "*.torrent"; + connect(this, SIGNAL(directoryChanged(QString)), this, SLOT(scanLocalFolder(QString))); + } + + ~FileSystemWatcher() { +#ifndef Q_WS_WIN + if(watch_timer) + delete watch_timer; +#endif + if(m_partialTorrentTimer) + delete m_partialTorrentTimer; + } + + QStringList directories() const { + QStringList dirs; +#ifndef Q_WS_WIN + if(watch_timer) { + foreach (const QDir &dir, watched_folders) + dirs << dir.canonicalPath(); + } +#endif + dirs << QFileSystemWatcher::directories(); + return dirs; + } + + void addPath(const QString & path) { +#ifndef Q_WS_WIN + QDir dir(path); + if (!dir.exists()) + return; + // Check if the path points to a network file system or not + if(isNetworkFileSystem(path)) { + // Network mode + qDebug("Network folder detected: %s", qPrintable(path)); + qDebug("Using file polling mode instead of inotify..."); + watched_folders << dir; + // Set up the watch timer + if (!watch_timer) { + watch_timer = new QTimer(this); + connect(watch_timer, SIGNAL(timeout()), this, SLOT(scanNetworkFolders())); + watch_timer->start(WATCH_INTERVAL); // 5 sec + } + } else { +#endif + // Normal mode + qDebug("FS Watching is watching %s in normal mode", qPrintable(path)); + QFileSystemWatcher::addPath(path); + scanLocalFolder(path); +#ifndef Q_WS_WIN + } +#endif + } + + void removePath(const QString & path) { +#ifndef Q_WS_WIN + QDir dir(path); + for (int i = 0; i < watched_folders.count(); ++i) { + if (QDir(watched_folders.at(i)) == dir) { + watched_folders.removeAt(i); + if (watched_folders.isEmpty()) + delete watch_timer; + return; + } + } +#endif + // Normal mode + QFileSystemWatcher::removePath(path); + } + +protected slots: + void scanLocalFolder(QString path) { + qDebug("scanLocalFolder(%s) called", qPrintable(path)); + QStringList torrents; + // Local folders scan + addTorrentsFromDir(QDir(path), torrents); + // Report detected torrent files + if(!torrents.empty()) { + qDebug("The following files are being reported: %s", qPrintable(torrents.join("\n"))); + emit torrentsAdded(torrents); + } + } + + void scanNetworkFolders() { +#ifndef Q_WS_WIN + qDebug("scanNetworkFolders() called"); + QStringList torrents; + // Network folders scan + foreach (const QDir &dir, watched_folders) { + //qDebug("FSWatcher: Polling manually folder %s", qPrintable(dir.path())); + addTorrentsFromDir(dir, torrents); + } + // Report detected torrent files + if(!torrents.empty()) { + qDebug("The following files are being reported: %s", qPrintable(torrents.join("\n"))); + emit torrentsAdded(torrents); + } +#endif + } + + void processPartialTorrents() { + QStringList no_longer_partial; + + // Check which torrents are still partial + foreach(const QString& torrent_path, m_partialTorrents.keys()) { + if(!QFile::exists(torrent_path)) { + m_partialTorrents.remove(torrent_path); + continue; + } + if(misc::isValidTorrentFile(torrent_path)) { + no_longer_partial << torrent_path; + m_partialTorrents.remove(torrent_path); + } else { + if(m_partialTorrents[torrent_path] >= MAX_PARTIAL_RETRIES) { + m_partialTorrents.remove(torrent_path); + QFile::rename(torrent_path, torrent_path+".invalid"); + } else { + m_partialTorrents[torrent_path]++; + } + } + } + + // Stop the partial timer if necessary + if(m_partialTorrents.empty()) { + m_partialTorrentTimer->stop(); + m_partialTorrentTimer->deleteLater(); + qDebug("No longer any partial torrent."); + } else { + qDebug("Still %d partial torrents after delayed processing.", m_partialTorrents.count()); + m_partialTorrentTimer->start(WATCH_INTERVAL); + } + // Notify of new torrents + if(!no_longer_partial.isEmpty()) + emit torrentsAdded(no_longer_partial); + } + +signals: + void torrentsAdded(QStringList &pathList); + +private: + void startPartialTorrentTimer() { + Q_ASSERT(!m_partialTorrents.isEmpty()); + if(!m_partialTorrentTimer) { + m_partialTorrentTimer = new QTimer(); + connect(m_partialTorrentTimer, SIGNAL(timeout()), SLOT(processPartialTorrents())); + m_partialTorrentTimer->setSingleShot(true); + m_partialTorrentTimer->start(WATCH_INTERVAL); + } + } + + void addTorrentsFromDir(const QDir &dir, QStringList &torrents) { + const QStringList files = dir.entryList(m_filters, QDir::Files, QDir::Unsorted); + foreach(const QString &file, files) { + const QString file_abspath = dir.absoluteFilePath(file); + if(misc::isValidTorrentFile(file_abspath)) { + torrents << file_abspath; + } else { + if(!m_partialTorrents.contains(file_abspath)) { + qDebug("Partial torrent detected at: %s", qPrintable(file_abspath)); + qDebug("Delay the file's processing..."); + m_partialTorrents.insert(file_abspath, 0); + } + } + } + if(!m_partialTorrents.empty()) + startPartialTorrentTimer(); + } + +}; + +#endif // FILESYSTEMWATCHER_H diff --git a/src/geoip/README b/src/geoip/README new file mode 100644 index 000000000..9d001dca3 --- /dev/null +++ b/src/geoip/README @@ -0,0 +1,12 @@ +If you wish to embed GeoIP database into qBittorrent executable, please download put GeoIP.dat in this folder. + +GeoIP Database can be downloaded from here: +* http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz +Note that the database should be uncompressed. + +Embedding GeoIP database into qBittorrent executable is advised for: +* Windows +* Mac OS X +* Linux distributions that don't provide GeoIP database in a separate package + +On Linux operating system, since this is not the default behavior, you also need to pass --with-geoip-database-embedded parameter to the configure file. diff --git a/src/geoip/geoip.pri b/src/geoip/geoip.pri new file mode 100644 index 000000000..c19c1e049 --- /dev/null +++ b/src/geoip/geoip.pri @@ -0,0 +1,19 @@ +INCLUDEPATH += $$PWD + +HEADERS += $$PWD/geoipmanager.h + +SOURCES += $$PWD/geoipmanager.cpp + +# Add GeoIP resource file if the GeoIP database +# should be embedded in qBittorrent executable +contains(DEFINES, WITH_GEOIP_EMBEDDED) { + exists("GeoIP.dat") { + message("GeoIP.dat was found in src/geoip/.") + RESOURCES += $$PWD/geoip.qrc + } else { + DEFINES -= WITH_GEOIP_EMBEDDED + error("GeoIP.dat was not found in src/geoip/ folder, please follow instructions in src/geoip/README.") + } +} else { + message("GeoIP database will not be embedded in qBittorrent executable.") +} diff --git a/src/geoip/geoip.qrc b/src/geoip/geoip.qrc new file mode 100644 index 000000000..5764e34f5 --- /dev/null +++ b/src/geoip/geoip.qrc @@ -0,0 +1,5 @@ + + + GeoIP.dat + + diff --git a/src/geoip/geoipmanager.cpp b/src/geoip/geoipmanager.cpp new file mode 100644 index 000000000..be3be6c3b --- /dev/null +++ b/src/geoip/geoipmanager.cpp @@ -0,0 +1,202 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include "geoipmanager.h" + +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include + +#include "misc.h" + +using namespace libtorrent; + +QString GeoIPManager::geoipFolder(bool embedded) { +#ifdef WITH_GEOIP_EMBEDDED + if(embedded) + return ":/geoip/"; + return misc::QDesktopServicesDataLocation()+"geoip"+QDir::separator(); +#else + Q_UNUSED(embedded); + if(QFile::exists("/usr/local/share/GeoIP/GeoIP.dat")) + return "/usr/local/share/GeoIP/"; + if(QFile::exists("/var/lib/GeoIP/GeoIP.dat")) + return "/var/lib/GeoIP/"; + return "/usr/share/GeoIP/"; +#endif +} + +QString GeoIPManager::geoipDBpath(bool embedded) { + return geoipFolder(embedded)+"GeoIP.dat"; +} + +#ifdef WITH_GEOIP_EMBEDDED +void GeoIPManager::exportEmbeddedDb() { + if(!QFile::exists(geoipDBpath(false)) || QFile(geoipDBpath(false)).size() != QFile(geoipDBpath(true)).size()) { // Export is required + qDebug("A local Geoip database update is required, proceeding..."); + // Create geoip folder is necessary + QDir gfolder(geoipFolder(false)); + if(!gfolder.exists()) { + if(!gfolder.mkpath(geoipFolder(false))) { + std::cerr << "Failed to create geoip folder at " << qPrintable(geoipFolder(false)) << std::endl; + return; + } + } + // Remove destination files + if(QFile::exists(geoipDBpath(false))) + misc::safeRemove(geoipDBpath(false)); + // Copy from executable to hard disk + qDebug("%s -> %s", qPrintable(geoipDBpath(true)), qPrintable(geoipDBpath(false))); + if(!QFile::copy(geoipDBpath(true), geoipDBpath(false))) { + std::cerr << "ERROR: Failed to copy geoip.dat from executable to hard disk" << std::endl; + } + qDebug("Local Geoip database was updated"); + } +} +#endif + +void GeoIPManager::loadDatabase(session *s) { +#ifdef WITH_GEOIP_EMBEDDED + exportEmbeddedDb(); +#endif + if(QFile::exists(geoipDBpath(false))) { + qDebug("Loading GeoIP database from %s...", qPrintable(geoipDBpath(false))); + s->load_country_db(geoipDBpath(false).toLocal8Bit().constData()); + } else { + qDebug("ERROR: Impossible to find local Geoip Database"); + } +} + +const char country_code[253][3] = +{ "--","AP","EU","AD","AE","AF","AG","AI","AL","AM","AN", + "AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB", + "BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO", + "BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD", + "CF","CG","CH","CI","CK","CL","CM","CN","CO","CR", + "CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO", + "DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ", + "FK","FM","FO","FR","FX","GA","GB","GD","GE","GF", + "GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT", + "GU","GW","GY","HK","HM","HN","HR","HT","HU","ID", + "IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO", + "JP","KE","KG","KH","KI","KM","KN","KP","KR","KW", + "KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT", + "LU","LV","LY","MA","MC","MD","MG","MH","MK","ML", + "MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV", + "MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI", + "NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF", + "PG","PH","PK","PL","PM","PN","PR","PS","PT","PW", + "PY","QA","RE","RO","RU","RW","SA","SB","SC","SD", + "SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO", + "SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH", + "TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW", + "TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE", + "VG","VI","VN","VU","WF","WS","YE","YT","RS","ZA", + "ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE", + "BL","MF"}; + +static const uint num_countries = (unsigned)(sizeof(country_code)/sizeof(country_code[0])); + +const char * country_name[253] = +{"N/A","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Netherlands Antilles", + "Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados", + "Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia", + "Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the", + "Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica", + "Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic", + "Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji", + "Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","France, Metropolitan","Gabon","United Kingdom","Grenada","Georgia","French Guiana", + "Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala", + "Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia", + "Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan", + "Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait", + "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania", + "Luxembourg","Latvia","Libyan Arab Jamahiriya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali", + "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives", + "Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua", + "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia", + "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau", + "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan", + "Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname", + "Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand", + "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan", + "Tanzania, United Republic of","Ukraine","Uganda","United States Minor Outlying Islands","United States","Uruguay","Uzbekistan","Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela", + "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa", + "Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey", + "Saint Barthelemy","Saint Martin"}; + +QString GeoIPManager::CountryISOCodeToName(const char* iso) { + if(iso[0] == 0) return "N/A"; + for(uint i = 0; i < num_countries; ++i) { + if(iso[0] == country_code[i][0] && iso[1] == country_code[i][1]) { + return QLatin1String(country_name[i]); + } + } + qDebug("GeoIPManager: Country name resolution failed for: %c%c", iso[0], iso[1]); + return "N/A"; +} + +// http://www.iso.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_elements.htm +QIcon GeoIPManager::CountryISOCodeToIcon(const char* iso) { + if(iso[0] == 0 || iso[0] == '!') return QIcon(); + const QString isoStr = QString(QByteArray(iso, 2)).toLower(); + return QIcon(":/Icons/flags/"+isoStr+".png"); +} + diff --git a/src/geoip/geoipmanager.h b/src/geoip/geoipmanager.h new file mode 100644 index 000000000..00bb730fa --- /dev/null +++ b/src/geoip/geoipmanager.h @@ -0,0 +1,55 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef GEOIPMANAGER_H +#define GEOIPMANAGER_H + +#include +#include +#include + +class GeoIPManager : public QObject { + Q_OBJECT + +public: + static void loadDatabase(libtorrent::session *s); + static QIcon CountryISOCodeToIcon(const char* iso); + static QString CountryISOCodeToName(const char* iso); + +private: + static QString geoipFolder(bool embedded=false); + static QString geoipDBpath(bool embedded=false); +#ifdef WITH_GEOIP_EMBEDDED + static void exportEmbeddedDb(); +#endif +}; + + +#endif // GEOIP_H diff --git a/src/gpl.html b/src/gpl.html new file mode 100644 index 000000000..312bb1f2c --- /dev/null +++ b/src/gpl.html @@ -0,0 +1,508 @@ +

qBittorrent is licensed under the GNU General Public License version 2 with the +addition of the following special exception:

+

+In addition, as a special exception, the copyright holders give permission to +link this program with the OpenSSL project's "OpenSSL" library (or with +modified versions of it that use the same license as the "OpenSSL" library), +and distribute the linked executables. You must obey the GNU General Public +License in all respects for all of the code used other than "OpenSSL". If you +modify file(s), you may extend this exception to your version of the file(s), +but you are not obligated to do so. If you do not wish to do so, delete this +exception statement from your version.

+---------- +

GNU General Public License, version 2

+
+ +

Table of Contents

+ + +
+ +

GNU GENERAL PUBLIC LICENSE

+

+Version 2, June 1991 +

+ +
 
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.  
+51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ 
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+ +

Preamble

+ +

+ The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. +

+ +

+ When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. +

+ +

+ To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. +

+ +

+ For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. +

+ +

+ We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. +

+ +

+ Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. +

+ +

+ Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. +

+ +

+ The precise terms and conditions for copying, distribution and +modification follow. +

+ + +

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+ + +

+0. + This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". +

+ +

+Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. +

+ +

+1. + You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. +

+ +

+You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. +

+ +

+2. + You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: +

+ +
+
+
+ a) + You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. +
+
+
+ b) + You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. +
+
+
+ c) + If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) +
+
+ +

+These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. +

+ +

+Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. +

+ +

+In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. +

+ +

+3. + You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: +

+ + + + +
+
+
+ a) + Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, +
+
+
+ b) + Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, +
+
+
+ c) + Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) +
+
+ +

+The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. +

+ +

+If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. +

+ +

+4. + You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. +

+ +

+5. + You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. +

+ +

+6. + Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. +

+ +

+7. + If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. +

+ +

+If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. +

+ +

+It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. +

+ +

+This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. +

+ +

+8. + If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. +

+ +

+9. + The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. +

+ +

+Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. +

+ +

+10. + If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. +

+ +

NO WARRANTY

+ +

+11. + BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. +

+ +

+12. + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. +

+ +

END OF TERMS AND CONDITIONS

+ +

How to Apply These Terms to Your New Programs

+ +

+ If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. +

+ +

+ To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. +

+ +
 
+one line to give the program's name and an idea of what it does. 
+Copyright (C) yyyy  name of author 
+ 
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+ 
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+ 
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+MA  02110-1301, USA.
+
+ +

+Also add information on how to contact you by electronic and paper mail. +

+ +

+If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: +

+ +
 
+Gnomovision version 69, Copyright (C) year name of author 
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+type `show w'.  This is free software, and you are welcome
+to redistribute it under certain conditions; type `show c' 
+for details.
+
+ +

+The hypothetical commands `show w' and `show c' should show +the appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and +`show c'; they could even be mouse-clicks or menu items--whatever +suits your program. +

+ +

+You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: +

+ + +
 
+Yoyodyne, Inc., hereby disclaims all copyright
+interest in the program `Gnomovision'
+(which makes passes at compilers) written 
+by James Hacker.
+ 
+signature of Ty Coon, 1 April 1989
+Ty Coon, President of Vice
+
+ +

+This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the +GNU Lesser General Public License +instead of this License. +

\ No newline at end of file diff --git a/src/headlessloader.h b/src/headlessloader.h new file mode 100644 index 000000000..f66a186ad --- /dev/null +++ b/src/headlessloader.h @@ -0,0 +1,108 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez, Frédéric Lassabe + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef HEADLESSLOADER_H +#define HEADLESSLOADER_H + +#include +#include +#include "preferences.h" +#include "qbtsession.h" + +class HeadlessLoader: public QObject { + Q_OBJECT + +public: + HeadlessLoader(const QStringList &torrentCmdLine) { + Preferences pref; + // Enable Web UI + pref.setWebUiEnabled(true); + // Instanciate Bittorrent Object + connect(QBtSession::instance(), SIGNAL(newConsoleMessage(QString)), this, SLOT(displayConsoleMessage(QString))); + // Resume unfinished torrents + QBtSession::instance()->startUpTorrents(); + // Process command line parameters + processParams(torrentCmdLine); + // Display some information to the user + std::cout << std::endl << "******** " << qPrintable(tr("Information")) << " ********" << std::endl; + std::cout << qPrintable(tr("To control qBittorrent, access the Web UI at http://localhost:%1").arg(QString::number(pref.getWebUiPort()))) << std::endl; + std::cout << qPrintable(tr("The Web UI administrator user name is: %1").arg(pref.getWebUiUsername())) << std::endl; + qDebug() << "Password:" << pref.getWebUiPassword(); + if(pref.getWebUiPassword() == "32fe0bd2bb001911bb8bcfe23fc92b63") { + std::cout << qPrintable(tr("The Web UI administrator password is still the default one: %1").arg("adminadmin")) << std::endl; + std::cout << qPrintable(tr("This is a security risk, please consider changing your password from program preferences.")) << std::endl; + } + } + + ~HeadlessLoader() { + QBtSession::drop(); + } + +public slots: + // Call this function to exit qBittorrent headless loader + // and return to prompt (object will be deleted by main) + void exit() { + qApp->quit(); + } + + void displayConsoleMessage(const QString &msg) { + std::cout << qPrintable(msg) << std::endl; + } + + void processParams(const QString& params_str) { + processParams(params_str.split(" ", QString::SkipEmptyParts)); + } + + // As program parameters, we can get paths or urls. + // This function parse the parameters and call + // the right addTorrent function, considering + // the parameter type. + void processParams(const QStringList& params) { + foreach(QString param, params) { + param = param.trimmed(); + if(param.startsWith(QString::fromUtf8("http://"), Qt::CaseInsensitive) || param.startsWith(QString::fromUtf8("ftp://"), Qt::CaseInsensitive) || param.startsWith(QString::fromUtf8("https://"), Qt::CaseInsensitive)) { + QBtSession::instance()->downloadFromUrl(param); + }else{ + if(param.startsWith("bc://bt/", Qt::CaseInsensitive)) { + qDebug("Converting bc link to magnet link"); + param = misc::bcLinkToMagnet(param); + } + if(param.startsWith("magnet:", Qt::CaseInsensitive)) { + QBtSession::instance()->addMagnetUri(param); + } else { + QBtSession::instance()->addTorrent(param); + } + } + } + } + +}; + +#endif diff --git a/src/hidabletabwidget.h b/src/hidabletabwidget.h new file mode 100644 index 000000000..0f941ec65 --- /dev/null +++ b/src/hidabletabwidget.h @@ -0,0 +1,64 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef HIDABLETABWIDGET_H +#define HIDABLETABWIDGET_H + +#include +#include + +class HidableTabWidget : public QTabWidget { +public: + + void showTabBar(bool show) { + tabBar()->setVisible(show); + } + +protected: + void tabInserted(int index) { + QTabWidget::tabInserted(index); + if(count() == 1) { + showTabBar(false); + } else { + showTabBar(true); + } + } + + void tabRemoved(int index) { + QTabWidget::tabInserted(index); + if(count() == 1) { + showTabBar(false); + } else { + showTabBar(true); + } + } +}; + +#endif // HIDABLETABWIDGET_H diff --git a/src/ico.cpp b/src/ico.cpp new file mode 100644 index 000000000..652489f5c --- /dev/null +++ b/src/ico.cpp @@ -0,0 +1,462 @@ +/* + * kimgio import filter for MS Windows .ico files + * + * Distributed under the terms of the LGPL + * Copyright (c) 2000 Malte Starostik + * + */ + +#include "ico.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace +{ + // Global header (see http://www.daubnet.com/formats/ICO.html) + struct IcoHeader + { + enum Type { Icon = 1, Cursor }; + quint16 reserved; + quint16 type; + quint16 count; + }; + + inline QDataStream& operator >>( QDataStream& s, IcoHeader& h ) + { + return s >> h.reserved >> h.type >> h.count; + } + + // Based on qt_read_dib et al. from qimage.cpp + // (c) 1992-2002 Trolltech AS. + struct BMP_INFOHDR + { + static const quint32 Size = 40; + quint32 biSize; // size of this struct + quint32 biWidth; // pixmap width + quint32 biHeight; // pixmap height + quint16 biPlanes; // should be 1 + quint16 biBitCount; // number of bits per pixel + enum Compression { RGB = 0 }; + quint32 biCompression; // compression method + quint32 biSizeImage; // size of image + quint32 biXPelsPerMeter; // horizontal resolution + quint32 biYPelsPerMeter; // vertical resolution + quint32 biClrUsed; // number of colors used + quint32 biClrImportant; // number of important colors + }; + const quint32 BMP_INFOHDR::Size; + + QDataStream& operator >>( QDataStream &s, BMP_INFOHDR &bi ) + { + s >> bi.biSize; + if ( bi.biSize == BMP_INFOHDR::Size ) + { + s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount; + s >> bi.biCompression >> bi.biSizeImage; + s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter; + s >> bi.biClrUsed >> bi.biClrImportant; + } + return s; + } + +#if 0 + QDataStream &operator<<( QDataStream &s, const BMP_INFOHDR &bi ) + { + s << bi.biSize; + s << bi.biWidth << bi.biHeight; + s << bi.biPlanes; + s << bi.biBitCount; + s << bi.biCompression; + s << bi.biSizeImage; + s << bi.biXPelsPerMeter << bi.biYPelsPerMeter; + s << bi.biClrUsed << bi.biClrImportant; + return s; + } +#endif + + // Header for every icon in the file + struct IconRec + { + unsigned char width; + unsigned char height; + quint16 colors; + quint16 hotspotX; + quint16 hotspotY; + quint32 size; + quint32 offset; + }; + + inline QDataStream& operator >>( QDataStream& s, IconRec& r ) + { + return s >> r.width >> r.height >> r.colors + >> r.hotspotX >> r.hotspotY >> r.size >> r.offset; + } + + struct LessDifference + { + LessDifference( unsigned s, unsigned c ) + : size( s ), colors( c ) {} + + bool operator ()( const IconRec& lhs, const IconRec& rhs ) const + { + // closest size match precedes everything else + if ( std::abs( int( lhs.width - size ) ) < + std::abs( int( rhs.width - size ) ) ) return true; + else if ( std::abs( int( lhs.width - size ) ) > + std::abs( int( rhs.width - size ) ) ) return false; + else if ( colors == 0 ) + { + // high/true color requested + if ( lhs.colors == 0 ) return true; + else if ( rhs.colors == 0 ) return false; + else return lhs.colors > rhs.colors; + } + else + { + // indexed icon requested + if ( lhs.colors == 0 && rhs.colors == 0 ) return false; + else if ( lhs.colors == 0 ) return false; + else return std::abs( int( lhs.colors - colors ) ) < + std::abs( int( rhs.colors - colors ) ); + } + } + unsigned size; + unsigned colors; + }; + + bool loadFromDIB( QDataStream& stream, const IconRec& rec, QImage& icon ) + { + BMP_INFOHDR header; + stream >> header; + if ( stream.atEnd() || header.biSize != BMP_INFOHDR::Size || + header.biSize > rec.size || + header.biCompression != BMP_INFOHDR::RGB || + ( header.biBitCount != 1 && header.biBitCount != 4 && + header.biBitCount != 8 && header.biBitCount != 24 && + header.biBitCount != 32 ) ) return false; + + unsigned paletteSize, paletteEntries; + + if (header.biBitCount > 8) + { + paletteEntries = 0; + paletteSize = 0; + } + else + { + paletteSize = (1 << header.biBitCount); + paletteEntries = paletteSize; + if (header.biClrUsed && header.biClrUsed < paletteSize) + paletteEntries = header.biClrUsed; + } + + // Always create a 32-bit image to get the mask right + // Note: this is safe as rec.width, rec.height are bytes + icon = QImage( rec.width, rec.height, QImage::Format_ARGB32 ); + if ( icon.isNull() ) return false; + + QVector< QRgb > colorTable( paletteSize ); + + colorTable.fill( QRgb( 0 ) ); + for ( unsigned i = 0; i < paletteEntries; ++i ) + { + unsigned char rgb[ 4 ]; + stream.readRawData( reinterpret_cast< char* >( &rgb ), + sizeof( rgb ) ); + colorTable[ i ] = qRgb( rgb[ 2 ], rgb[ 1 ], rgb[ 0 ] ); + } + + unsigned bpl = ( rec.width * header.biBitCount + 31 ) / 32 * 4; + + unsigned char* buf = new unsigned char[ bpl ]; + for ( unsigned y = rec.height; !stream.atEnd() && y--; ) + { + stream.readRawData( reinterpret_cast< char* >( buf ), bpl ); + unsigned char* pixel = buf; + QRgb* p = reinterpret_cast< QRgb* >( icon.scanLine(y)); + switch ( header.biBitCount ) + { + case 1: + for ( unsigned x = 0; x < rec.width; ++x ) + *p++ = colorTable[ + ( pixel[ x / 8 ] >> ( 7 - ( x & 0x07 ) ) ) & 1 ]; + break; + case 4: + for ( unsigned x = 0; x < rec.width; ++x ) + if ( x & 1 ) *p++ = colorTable[ pixel[ x / 2 ] & 0x0f ]; + else *p++ = colorTable[ pixel[ x / 2 ] >> 4 ]; + break; + case 8: + for ( unsigned x = 0; x < rec.width; ++x ) + *p++ = colorTable[ pixel[ x ] ]; + break; + case 24: + for ( unsigned x = 0; x < rec.width; ++x ) + *p++ = qRgb( pixel[ 3 * x + 2 ], + pixel[ 3 * x + 1 ], + pixel[ 3 * x ] ); + break; + case 32: + for ( unsigned x = 0; x < rec.width; ++x ) + *p++ = qRgba( pixel[ 4 * x + 2 ], + pixel[ 4 * x + 1 ], + pixel[ 4 * x ], + pixel[ 4 * x + 3] ); + break; + } + } + delete[] buf; + + if ( header.biBitCount < 32 ) + { + // Traditional 1-bit mask + bpl = ( rec.width + 31 ) / 32 * 4; + buf = new unsigned char[ bpl ]; + for ( unsigned y = rec.height; y--; ) + { + stream.readRawData( reinterpret_cast< char* >( buf ), bpl ); + QRgb* p = reinterpret_cast< QRgb* >(icon.scanLine(y)); + for ( unsigned x = 0; x < rec.width; ++x, ++p ) + if ( ( ( buf[ x / 8 ] >> ( 7 - ( x & 0x07 ) ) ) & 1 ) ) + *p &= RGB_MASK; + } + delete[] buf; + } + return true; + } +} + +ICOHandler::ICOHandler() +{ +} + +bool ICOHandler::canRead() const +{ + if (canRead(device())) { + setFormat("ico"); + return true; + } + return false; +} + +bool ICOHandler::read(QImage *outImage) +{ + + qint64 offset = device()->pos(); + + QDataStream stream( device() ); + stream.setByteOrder( QDataStream::LittleEndian ); + IcoHeader header; + stream >> header; + if ( stream.atEnd() || !header.count || + ( header.type != IcoHeader::Icon && header.type != IcoHeader::Cursor) ) + return false; + + unsigned requestedSize = 32; + unsigned requestedColors = QApplication::desktop()->depth() > 8 ? 0 : QApplication::desktop()->depth(); + int requestedIndex = -1; +#if 0 + if ( io->parameters() ) + { + QStringList params = QString(io->parameters()).split( ';', QString::SkipEmptyParts ); + QMap< QString, QString > options; + for ( QStringList::ConstIterator it = params.begin(); + it != params.end(); ++it ) + { + QStringList tmp = (*it).split( '=', QString::SkipEmptyParts ); + if ( tmp.count() == 2 ) options[ tmp[ 0 ] ] = tmp[ 1 ]; + } + if ( options[ "index" ].toUInt() ) + requestedIndex = options[ "index" ].toUInt(); + if ( options[ "size" ].toUInt() ) + requestedSize = options[ "size" ].toUInt(); + if ( options[ "colors" ].toUInt() ) + requestedColors = options[ "colors" ].toUInt(); + } +#endif + + typedef std::vector< IconRec > IconList; + IconList icons; + for ( unsigned i = 0; i < header.count; ++i ) + { + if ( stream.atEnd() ) + return false; + IconRec rec; + stream >> rec; + icons.push_back( rec ); + } + IconList::const_iterator selected; + if (requestedIndex >= 0) { + selected = std::min( icons.begin() + requestedIndex, icons.end() ); + } else { + selected = std::min_element( icons.begin(), icons.end(), + LessDifference( requestedSize, requestedColors ) ); + } + if ( stream.atEnd() || selected == icons.end() || + offset + selected->offset > device()->size() ) + return false; + + device()->seek( offset + selected->offset ); + QImage icon; + if ( loadFromDIB( stream, *selected, icon ) ) + { + icon.setText( "X-Index", 0, QString::number( selected - icons.begin() ) ); + if ( header.type == IcoHeader::Cursor ) + { + icon.setText( "X-HotspotX", 0, QString::number( selected->hotspotX ) ); + icon.setText( "X-HotspotY", 0, QString::number( selected->hotspotY ) ); + } + + *outImage = icon; + return true; + } + return false; +} + +bool ICOHandler::write(const QImage &/*image*/) +{ +#if 0 + if (image.isNull()) + return; + + QByteArray dibData; + QDataStream dib(dibData, QIODevice::ReadWrite); + dib.setByteOrder(QDataStream::LittleEndian); + + QImage pixels = image; + QImage mask; + if (io->image().hasAlphaBuffer()) + mask = image.createAlphaMask(); + else + mask = image.createHeuristicMask(); + mask.invertPixels(); + for ( int y = 0; y < pixels.height(); ++y ) + for ( int x = 0; x < pixels.width(); ++x ) + if ( mask.pixel( x, y ) == 0 ) pixels.setPixel( x, y, 0 ); + + if (!qt_write_dib(dib, pixels)) + return; + + uint hdrPos = dib.device()->at(); + if (!qt_write_dib(dib, mask)) + return; + memmove(dibData.data() + hdrPos, dibData.data() + hdrPos + BMP_WIN + 8, dibData.size() - hdrPos - BMP_WIN - 8); + dibData.resize(dibData.size() - BMP_WIN - 8); + + QDataStream ico(device()); + ico.setByteOrder(QDataStream::LittleEndian); + IcoHeader hdr; + hdr.reserved = 0; + hdr.type = Icon; + hdr.count = 1; + ico << hdr.reserved << hdr.type << hdr.count; + IconRec rec; + rec.width = image.width(); + rec.height = image.height(); + if (image.numColors() <= 16) + rec.colors = 16; + else if (image.depth() <= 8) + rec.colors = 256; + else + rec.colors = 0; + rec.hotspotX = 0; + rec.hotspotY = 0; + rec.dibSize = dibData.size(); + ico << rec.width << rec.height << rec.colors + << rec.hotspotX << rec.hotspotY << rec.dibSize; + rec.dibOffset = ico.device()->at() + sizeof(rec.dibOffset); + ico << rec.dibOffset; + + BMP_INFOHDR dibHeader; + dib.device()->at(0); + dib >> dibHeader; + dibHeader.biHeight = image.height() << 1; + dib.device()->at(0); + dib << dibHeader; + + ico.writeRawBytes(dibData.data(), dibData.size()); + return true; +#endif + return false; +} + +QByteArray ICOHandler::name() const +{ + return "ico"; +} + +bool ICOHandler::canRead(QIODevice *device) +{ + if (!device) { + qWarning("ICOHandler::canRead() called with no device"); + return false; + } + + const qint64 oldPos = device->pos(); + + char head[8]; + qint64 readBytes = device->read(head, sizeof(head)); + const bool readOk = readBytes == sizeof(head); + + if (device->isSequential()) { + while (readBytes > 0) + device->ungetChar(head[readBytes-- - 1]); + } else { + device->seek(oldPos); + } + + if ( !readOk ) + return false; + + return head[2] == '\001' && head[3] == '\000' && // type should be 1 + ( head[6] == 16 || head[6] == 32 || head[6] == 64 ) && // width can only be one of those + ( head[7] == 16 || head[7] == 32 || head[7] == 64 ); // same for height +} + +class ICOPlugin : public QImageIOPlugin +{ +public: + QStringList keys() const; + Capabilities capabilities(QIODevice *device, const QByteArray &format) const; + QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; +}; + +QStringList ICOPlugin::keys() const +{ + return QStringList() << "ico" << "ICO"; +} + +QImageIOPlugin::Capabilities ICOPlugin::capabilities(QIODevice *device, const QByteArray &format) const +{ + if (format == "ico" || format == "ICO") + return Capabilities(CanRead); + if (!format.isEmpty()) + return 0; + if (!device->isOpen()) + return 0; + + Capabilities cap; + if (device->isReadable() && ICOHandler::canRead(device)) + cap |= CanRead; + return cap; +} + +QImageIOHandler *ICOPlugin::create(QIODevice *device, const QByteArray &format) const +{ + QImageIOHandler *handler = new ICOHandler; + handler->setDevice(device); + handler->setFormat(format); + return handler; +} + +Q_EXPORT_STATIC_PLUGIN(ICOPlugin) +Q_EXPORT_PLUGIN2(ico, ICOPlugin) diff --git a/src/ico.h b/src/ico.h new file mode 100644 index 000000000..a9cf548b8 --- /dev/null +++ b/src/ico.h @@ -0,0 +1,52 @@ +/* + * ico.h - kimgio import filter for MS Windows .ico files + * + * Distributed under the terms of the LGPL + * Copyright (c) 2000 Malte Starostik + * + */ + +// You can use QImageIO::setParameters() to request a specific +// Icon out of an .ico file: +// +// Options consist of a name=value pair and are separated by a semicolon. +// Available options are: +// size= select the icon that most closely matches (pixels) +// default: 32 +// colors= select the icon that has colors (or comes closest) +// default: 1 << display depth or 0 (RGB) if display depth > 8 +// index= select the indexth icon from the file. If this option +// is present, the size and colors options will be ignored. +// default: none +// If both size and colors are given, size takes precedence. +// +// The old format is still supported: +// the parameters consist of a single string in the form +// "[:]" which correspond to the options above +// +// If an icon was returned (i.e. the file is valid and the index option +// if present was not out of range), the icon's index within the .ico +// file is returned in the text tag "X-Index" of the image. +// If the icon is in fact a cursor, its hotspot coordinates are returned +// in the text tags "X-HotspotX" and "X-HotspotY". + +#ifndef _ICO_H_ +#define _ICO_H_ + +#include + +class ICOHandler : public QImageIOHandler +{ +public: + ICOHandler(); + + bool canRead() const; + bool read(QImage *image); + bool write(const QImage &image); + + QByteArray name() const; + + static bool canRead(QIODevice *device); +}; + +#endif diff --git a/src/iconprovider.cpp b/src/iconprovider.cpp new file mode 100644 index 000000000..3954c843a --- /dev/null +++ b/src/iconprovider.cpp @@ -0,0 +1,118 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include "iconprovider.h" +#include "preferences.h" + +IconProvider* IconProvider::m_instance = 0; + +IconProvider::IconProvider() +{ +#if defined(Q_WS_X11) && (QT_VERSION >= QT_VERSION_CHECK(4,6,0)) + m_useSystemTheme = Preferences().useSystemIconTheme(); +#endif +} + +IconProvider * IconProvider::instance() +{ + if(!m_instance) + m_instance = new IconProvider; + return m_instance; +} + +void IconProvider::drop() +{ + if(m_instance) { + delete m_instance; + m_instance = 0; + } +} + +QIcon IconProvider::getIcon(const QString &iconId) +{ +#if defined(Q_WS_X11) && (QT_VERSION >= QT_VERSION_CHECK(4,6,0)) + if(m_useSystemTheme) { + QIcon icon = QIcon::fromTheme(iconId, QIcon(":/Icons/oxygen/"+iconId+".png")); + icon = generateDifferentSizes(icon); + return icon; + } +#endif + return QIcon(":/Icons/oxygen/"+iconId+".png"); +} + +#if defined(Q_WS_X11) && (QT_VERSION >= QT_VERSION_CHECK(4,6,0)) +void IconProvider::useSystemIconTheme(bool enable) +{ + m_useSystemTheme = enable; +} + +// Makes sure the icon is at least available in 16px and 24px size +// It scales the icon from the theme if necessary +// Otherwise, the UI looks broken if the icon is not available +// in the correct size. +QIcon IconProvider::generateDifferentSizes(const QIcon &icon) +{ + QIcon new_icon; + QList required_sizes; + required_sizes << QSize(16, 16) << QSize(24, 24); + QList modes; + modes << QIcon::Normal << QIcon::Active << QIcon::Selected << QIcon::Disabled; + foreach(const QSize& size, required_sizes) { + foreach(QIcon::Mode mode, modes) { + QPixmap pixoff = icon.pixmap(size, mode, QIcon::Off); + if(pixoff.height() > size.height()) + pixoff = pixoff.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); + new_icon.addPixmap(pixoff, mode, QIcon::Off); + QPixmap pixon = icon.pixmap(size, mode, QIcon::On); + if(pixon.height() > size.height()) + pixon = pixoff.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); + new_icon.addPixmap(pixon, mode, QIcon::On); + } + } + return new_icon; +} +#endif + +QString IconProvider::getIconPath(const QString &iconId) +{ +#if defined(Q_WS_X11) && (QT_VERSION >= QT_VERSION_CHECK(4,6,0)) + if(m_useSystemTheme) { + QString path = QDir::temp().absoluteFilePath(iconId+".png"); + if(!QFile::exists(path)) { + const QIcon icon = QIcon::fromTheme(iconId); + if(icon.isNull()) return ":/Icons/oxygen/"+iconId+".png"; + QPixmap px = icon.pixmap(32); + px.save(path); + } + return path; + } +#endif + return ":/Icons/oxygen/"+iconId+".png"; +} diff --git a/src/iconprovider.h b/src/iconprovider.h new file mode 100644 index 000000000..eec415330 --- /dev/null +++ b/src/iconprovider.h @@ -0,0 +1,63 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef ICONPROVIDER_H +#define ICONPROVIDER_H + +#include +#include + +class IconProvider +{ + Q_DISABLE_COPY(IconProvider); + +private: + explicit IconProvider(); + static IconProvider* m_instance; + +public: + static IconProvider* instance(); + static void drop(); + QIcon getIcon(const QString& iconId); + QString getIconPath(const QString &iconId); + +#if defined(Q_WS_X11) && (QT_VERSION >= QT_VERSION_CHECK(4,6,0)) +public: + void useSystemIconTheme(bool enable); + +private: + QIcon generateDifferentSizes(const QIcon& icon); + +private: + bool m_useSystemTheme; +#endif +}; + +#endif // ICONPROVIDER_H diff --git a/src/icons.qrc b/src/icons.qrc new file mode 100644 index 000000000..c5a98445d --- /dev/null +++ b/src/icons.qrc @@ -0,0 +1,352 @@ + + + Icons/url.png + Icons/loading.png + Icons/3-state-checkbox.gif + Icons/sphere.png + Icons/slow_off.png + Icons/sphere2.png + Icons/magnet.png + Icons/slow.png + Icons/L.gif + Icons/skin/qbittorrent_mono_light.png + Icons/skin/seeding.png + Icons/skin/splash.png + Icons/skin/tabs.gif + Icons/skin/qbittorrent16.png + Icons/skin/connected.png + Icons/skin/qbittorrent22.png + Icons/skin/disconnected.png + Icons/skin/mascot.png + Icons/skin/paused.png + Icons/skin/slider-area.gif + Icons/skin/stalledDL.png + Icons/skin/error.png + Icons/skin/qbittorrent_mono_dark.png + Icons/skin/handle-icon-horizontal.gif + Icons/skin/qbittorrent32.png + Icons/skin/knob.gif + Icons/skin/filterall.png + Icons/skin/uploading.png + Icons/skin/queued.png + Icons/skin/checking.png + Icons/skin/handle-icon.gif + Icons/skin/arrow-right.gif + Icons/skin/filterinactive.png + Icons/skin/firewalled.png + Icons/skin/downloading.png + Icons/skin/toolbox-divider.gif + Icons/skin/stalledUP.png + Icons/skin/filteractive.png + Icons/skin/bg-handle-horizontal.gif + Icons/skin/download.png + Icons/skin/ratio.png + Icons/flags/sm.png + Icons/flags/lt.png + Icons/flags/th.png + Icons/flags/sd.png + Icons/flags/mr.png + Icons/flags/by.png + Icons/flags/sc.png + Icons/flags/mz.png + Icons/flags/tt.png + Icons/flags/kp.png + Icons/flags/re.png + Icons/flags/um.png + Icons/flags/ec.png + Icons/flags/fk.png + Icons/flags/aw.png + Icons/flags/lb.png + Icons/flags/vg.png + Icons/flags/do.png + Icons/flags/ee.png + Icons/flags/ck.png + Icons/flags/gn.png + Icons/flags/cg.png + Icons/flags/ao.png + Icons/flags/dk.png + Icons/flags/ms.png + Icons/flags/sg.png + Icons/flags/bw.png + Icons/flags/br.png + Icons/flags/cn.png + Icons/flags/ua.png + Icons/flags/ae.png + Icons/flags/tg.png + Icons/flags/ge.png + Icons/flags/ne.png + Icons/flags/km.png + Icons/flags/bf.png + Icons/flags/nf.png + Icons/flags/az.png + Icons/flags/sl.png + Icons/flags/md.png + Icons/flags/ph.png + Icons/flags/mc.png + Icons/flags/mq.png + Icons/flags/ng.png + Icons/flags/vu.png + Icons/flags/et.png + Icons/flags/bj.png + Icons/flags/nl.png + Icons/flags/ad.png + Icons/flags/tv.png + Icons/flags/fj.png + Icons/flags/to.png + Icons/flags/ru.png + Icons/flags/jp.png + Icons/flags/ma.png + Icons/flags/bz.png + Icons/flags/vn.png + Icons/flags/bt.png + Icons/flags/ht.png + Icons/flags/kw.png + Icons/flags/tr.png + Icons/flags/sy.png + Icons/flags/nr.png + Icons/flags/nz.png + Icons/flags/np.png + Icons/flags/uz.png + Icons/flags/in.png + Icons/flags/ga.png + Icons/flags/sa.png + Icons/flags/tl.png + Icons/flags/ly.png + Icons/flags/lr.png + Icons/flags/cz.png + Icons/flags/bm.png + Icons/flags/us.png + Icons/flags/ye.png + Icons/flags/gs.png + Icons/flags/sb.png + Icons/flags/hm.png + Icons/flags/ke.png + Icons/flags/so.png + Icons/flags/ni.png + Icons/flags/cm.png + Icons/flags/li.png + Icons/flags/gp.png + Icons/flags/co.png + Icons/flags/kz.png + Icons/flags/de.png + Icons/flags/mm.png + Icons/flags/gb.png + Icons/flags/mx.png + Icons/flags/la.png + Icons/flags/au.png + Icons/flags/gu.png + Icons/flags/gw.png + Icons/flags/lc.png + Icons/flags/st.png + Icons/flags/nc.png + Icons/flags/ch.png + Icons/flags/cd.png + Icons/flags/mh.png + Icons/flags/pg.png + Icons/flags/bh.png + Icons/flags/kr.png + Icons/flags/is.png + Icons/flags/gh.png + Icons/flags/mp.png + Icons/flags/ca.png + Icons/flags/bi.png + Icons/flags/yt.png + Icons/flags/it.png + Icons/flags/kn.png + Icons/flags/ve.png + Icons/flags/cu.png + Icons/flags/bs.png + Icons/flags/rs.png + Icons/flags/tw.png + Icons/flags/bd.png + Icons/flags/pr.png + Icons/flags/lk.png + Icons/flags/sn.png + Icons/flags/gr.png + Icons/flags/gm.png + Icons/flags/na.png + Icons/flags/om.png + Icons/flags/tz.png + Icons/flags/as.png + Icons/flags/no.png + Icons/flags/mv.png + Icons/flags/ki.png + Icons/flags/eg.png + Icons/flags/tj.png + Icons/flags/sj.png + Icons/flags/fi.png + Icons/flags/lv.png + Icons/flags/cx.png + Icons/flags/ci.png + Icons/flags/vi.png + Icons/flags/be.png + Icons/flags/mw.png + Icons/flags/zw.png + Icons/flags/si.png + Icons/flags/dm.png + Icons/flags/jo.png + Icons/flags/hk.png + Icons/flags/me.png + Icons/flags/va.png + Icons/flags/pm.png + Icons/flags/qa.png + Icons/flags/cc.png + Icons/flags/kh.png + Icons/flags/id.png + Icons/flags/ai.png + Icons/flags/mn.png + Icons/flags/gd.png + Icons/flags/mt.png + Icons/flags/gq.png + Icons/flags/hr.png + Icons/flags/sv.png + Icons/flags/dz.png + Icons/flags/kg.png + Icons/flags/gy.png + Icons/flags/bv.png + Icons/flags/ag.png + Icons/flags/hn.png + Icons/flags/ml.png + Icons/flags/fo.png + Icons/flags/pw.png + Icons/flags/mg.png + Icons/flags/iq.png + Icons/flags/jm.png + Icons/flags/bo.png + Icons/flags/sk.png + Icons/flags/sh.png + Icons/flags/tf.png + Icons/flags/mk.png + Icons/flags/my.png + Icons/flags/es.png + Icons/flags/py.png + Icons/flags/ax.png + Icons/flags/ls.png + Icons/flags/tn.png + Icons/flags/ps.png + Icons/flags/bn.png + Icons/flags/dj.png + Icons/flags/cs.png + Icons/flags/pl.png + Icons/flags/cl.png + Icons/flags/pf.png + Icons/flags/gi.png + Icons/flags/bb.png + Icons/flags/ws.png + Icons/flags/cy.png + Icons/flags/pt.png + Icons/flags/ba.png + Icons/flags/gl.png + Icons/flags/ie.png + Icons/flags/fr.png + Icons/flags/tm.png + Icons/flags/er.png + Icons/flags/cr.png + Icons/flags/af.png + Icons/flags/mu.png + Icons/flags/lu.png + Icons/flags/pk.png + Icons/flags/am.png + Icons/flags/ar.png + Icons/flags/uy.png + Icons/flags/hu.png + Icons/flags/pn.png + Icons/flags/gf.png + Icons/flags/ir.png + Icons/flags/pe.png + Icons/flags/nu.png + Icons/flags/ro.png + Icons/flags/mo.png + Icons/flags/za.png + Icons/flags/ky.png + Icons/flags/zm.png + Icons/flags/se.png + Icons/flags/il.png + Icons/flags/fm.png + Icons/flags/sr.png + Icons/flags/pa.png + Icons/flags/cv.png + Icons/flags/tc.png + Icons/flags/an.png + Icons/flags/sz.png + Icons/flags/io.png + Icons/flags/rw.png + Icons/flags/eh.png + Icons/flags/cf.png + Icons/flags/gt.png + Icons/flags/al.png + Icons/flags/ug.png + Icons/flags/td.png + Icons/flags/at.png + Icons/flags/vc.png + Icons/flags/tk.png + Icons/flags/bg.png + Icons/flags/wf.png + Icons/oxygen/preferences-system.png + Icons/oxygen/unavailable.png + Icons/oxygen/document-edit-verify.png + Icons/oxygen/list-remove.png + Icons/oxygen/dialog-warning.png + Icons/oxygen/mail-folder-inbox.png + Icons/oxygen/edit-clear-history.png + Icons/oxygen/edit-copy.png + Icons/oxygen/folder-documents.png + Icons/oxygen/document-edit.png + Icons/oxygen/security-low.png + Icons/oxygen/insert-link.png + Icons/oxygen/network-wired.png + Icons/oxygen/mail-mark-read.png + Icons/oxygen/go-up.png + Icons/oxygen/application-exit.png + Icons/oxygen/edit-rename.png + Icons/oxygen/edit-cut.png + Icons/oxygen/gear32.png + Icons/oxygen/media-playback-start.png + Icons/oxygen/user-group-delete.png + Icons/oxygen/edit-find-user.png + Icons/oxygen/media-playback-pause.png + Icons/oxygen/tab-close.png + Icons/oxygen/inode-directory.png + Icons/oxygen/tools-report-bug.png + Icons/oxygen/view-filter.png + Icons/oxygen/services.png + Icons/oxygen/view-preview.png + Icons/oxygen/view-refresh.png + Icons/oxygen/text-plain.png + Icons/oxygen/edit-delete.png + Icons/oxygen/chronometer.png + Icons/oxygen/dialog-cancel.png + Icons/oxygen/task-attention.png + Icons/oxygen/preferences-system-network.png + Icons/oxygen/document-properties.png + Icons/oxygen/user-group-new.png + Icons/oxygen/security-high.png + Icons/oxygen/network-server.png + Icons/oxygen/wallet-open.png + Icons/oxygen/preferences-web-browser-cookies.png + Icons/oxygen/list-add.png + Icons/oxygen/edit-paste.png + Icons/oxygen/folder-remote.png + Icons/oxygen/help-about.png + Icons/oxygen/document-save.png + Icons/oxygen/gear.png + Icons/oxygen/view-categories.png + Icons/oxygen/document-new.png + Icons/oxygen/dialog-information.png + Icons/oxygen/preferences-other.png + Icons/oxygen/object-locked.png + Icons/oxygen/view-calendar-journal.png + Icons/oxygen/application-rss+xml.png + Icons/oxygen/document-encrypt.png + Icons/oxygen/help-contents.png + Icons/oxygen/preferences-desktop.png + Icons/oxygen/application-x-mswinurl.png + Icons/oxygen/go-down.png + Icons/oxygen/document-import.png + Icons/oxygen/download.png + Icons/oxygen/edit-find.png + Icons/oxygen/edit-clear.png + Icons/oxygen/webui.png + Icons/oxygen/folder-new.png + + \ No newline at end of file diff --git a/src/lang.qrc b/src/lang.qrc new file mode 100644 index 000000000..44d40d0da --- /dev/null +++ b/src/lang.qrc @@ -0,0 +1,37 @@ + + + lang/qbittorrent_nl.qm + lang/qbittorrent_hu.qm + lang/qbittorrent_ru.qm + lang/qbittorrent_zh_TW.qm + lang/qbittorrent_tr.qm + lang/qbittorrent_fi.qm + lang/qbittorrent_sk.qm + lang/qbittorrent_ja.qm + lang/qbittorrent_el.qm + lang/qbittorrent_ca.qm + lang/qbittorrent_pt.qm + lang/qbittorrent_it.qm + lang/qbittorrent_fr.qm + lang/qbittorrent_uk.qm + lang/qbittorrent_zh.qm + lang/qbittorrent_lt.qm + lang/qbittorrent_ko.qm + lang/qbittorrent_nb.qm + lang/qbittorrent_sv.qm + lang/qbittorrent_de.qm + lang/qbittorrent_gl.qm + lang/qbittorrent_sr.qm + lang/qbittorrent_pt_BR.qm + lang/qbittorrent_da.qm + lang/qbittorrent_cs.qm + lang/qbittorrent_hy.qm + lang/qbittorrent_pl.qm + lang/qbittorrent_bg.qm + lang/qbittorrent_ar.qm + lang/qbittorrent_es.qm + lang/qbittorrent_en.qm + lang/qbittorrent_hr.qm + lang/qbittorrent_ro.qm + + \ No newline at end of file diff --git a/src/lang/qbittorrent_ar.qm b/src/lang/qbittorrent_ar.qm new file mode 100644 index 0000000000000000000000000000000000000000..79ccf25ee8c900493be721b9ba8a02b8cc289c1e GIT binary patch literal 106467 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 S@BQ-L`@dW}GW^S}6aNbaRE{eE literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_ar.ts b/src/lang/qbittorrent_ar.ts new file mode 100644 index 000000000..07fc4e652 --- /dev/null +++ b/src/lang/qbittorrent_ar.ts @@ -0,0 +1,6763 @@ + + + + + AboutDlg + + + About qBittorrent + معلومات عن البرنامج + + + + About + معلومات + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + Author + المؤلف + + + + Name: + ‫الاسم: + + + + Country: + البلد‫: + + + + E-mail: + البريد الإلكتروني : + + + + Christophe Dumez + كريستوف دوميز + + + + France + فرنسا + + + + Translation + الترجمة + + + + License + الترخيص + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + chris@qbittorrent.org + chris@qbittorrent.org + + + + Thanks to + شكرا لهؤلاء + + + + AdvancedSettings + + Property + خاصية + + + Value + قيمة + + + + Disk write cache size + كمية الذاكرة المخصصة للكتابة + + + + MiB + ميجابايت + + + + Outgoing ports (Min) [0: Disabled] + منافذ الخروج (الأدنى) [٠ : معطلة] + + + + Outgoing ports (Max) [0: Disabled] + منافذ الخروج (الأقصى) [٠ : معطلة] + + + + Recheck torrents on completion + إعادة تأكيد البيانات بعد الانتهاء + + + + Transfer list refresh interval + المدة بين اعادة تحديث الصفحة + + + + ms + milliseconds + ms + + + + Setting + الخيار + + + + Value + Value set for this setting + القيمة + + + + Resolve peer countries (GeoIP) + اظهار أعلام الدول + + + + Resolve peer host names + اظهار اسم المستخدم للقرين + + + + Maximum number of half-open connections [0: Disabled] + أكبر كمية من الاتصالات النصف مفتوحة [٠ : معطلة] + + + + Strict super seeding + الرفع القوي المخصص + + + + Network Interface (requires restart) + Network Interface (requires restart) + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + Any interface + + + + IP Address to report to trackers (requires restart) + IP Address to report to trackers (requires restart) + + + + Display program on-screen notifications + اظهار بالونات المعلومات + + + Display program notification balloons + اظهار بالونات المعلومات + + + + Enable embedded tracker + تشغيل خدمة التراكر الداخلي + + + + Embedded tracker port + منفذ التراكر الداخلي + + + + Check for software updates + البحث عن التحديثات + + + + Use system icon theme + استخدام أيقونات النظام + + + + Confirm torrent deletion + تأكيد حذف التورنت + + + Display program notification baloons + اظهار بالونات المعلومات + + + + Ignore transfer limits on local network + تجاهل حدود النقل على الشبكة المحلية + + + Include TCP/IP overhead in transfer limits + ادراج TCP/IP على حدود النقل + + + + AutomatedRssDownloader + + + Automated RSS Downloader + تنزيل.RSS.آلي + + + + Enable the automated RSS downloader + تفعيل.تنزيل.RSS.آلي + + + + Download rules + قواعد.التحميل + + + + Rule definition + تعريف.القاعدة + + + + Must contain: + يجب أن تتكون من : + + + + Must not contain: + لا يجب أن تتكون من : + + + + Use regular expressions + إستخدام التعابير العادية + + + + Import... + استيراد... + + + + Export... + تصدير... + + + + ... + ... + + + + Assign label: + تعيين التسمية : + + + + Save to a different directory + إختر مكان للحفظ + + + + Save to: + مكان الحفظ: + + + + Apply rule to feeds: + تطبيق القاعدة على: + + + + Matching RSS articles + Matching RSS articles + + + + New rule name + اسم قاعدة جديد + + + + Please type the name of the new download rule. + اكتب اسم القاعدة. + + + + + Rule name conflict + تعارض في اسم القاعدة + + + + + A rule with this name already exists, please choose another name. + تعارض في اسم القاعدة اختر اسم اخر. + + + + Are you sure you want to remove the download rule named %1? + Are you sure you want to remove the download rule named %1? + + + + Are you sure you want to remove the selected download rules? + Are you sure you want to remove the selected download rules? + + + + Rule deletion confirmation + تأكيد حذف القاعدة + + + + Destination directory + المجلد المستهدف + + + + Invalid action + حركة خاطئة + + + + The list is empty, there is nothing to export. + اللائحة خالية و لا توجد مواد للتصدير. + + + + Where would you like to save the list? + أين تريد حفظ اللائحة؟ + + + + Rules list (*.rssrules) + Rules list (*.rssrules) + + + + I/O Error + I/O Error + + + + Failed to create the destination file + خطأ في انشاء الملف + + + + Please point to the RSS download rules file + Please point to the RSS download rules file + + + + Rules list (*.rssrules *.filters) + Rules list (*.rssrules *.filters) + + + + Import Error + خطأ في الاستيراد + + + + Failed to import the selected rules file + خطأ في استيراد ملف القواعد + + + + Add new rule... + اضافة قاعدة جديدة... + + + + Delete rule + حذف القاعدة + + + + Rename rule... + اعادة تسمية القاعدة... + + + + Delete selected rules + حذف القاعدة + + + + Rule renaming + اعادة تسمية القاعدة + + + + Please type the new rule name + اكتب اسم القاعدة + + + + Regex mode: use Perl-like regular expressions + Regex mode: use Perl-like regular expressions + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + لقد وصلت الى الحد الاقصى الذي حددته.%1. + + + Removing torrent %1... + Removing torrent %1... + + + Pausing torrent %1... + Pausing torrent %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + البرنامج مقيد بالمنفذ: %1 + + + UPnP support [ON] + دعم UPnP [ON] + + + UPnP support [OFF] + دعم UPnP [OFF] + + + NAT-PMP support [ON] + NAT-PMP support [ON] + + + NAT-PMP support [OFF] + NAT-PMP support [OFF] + + + HTTP user agent is %1 + HTTP user agent is %1 + + + Using a disk cache size of %1 MiB + استخدام ذاكرة بكمية %1 ميجابايت + + + DHT support [ON], port: UDP/%1 + DHT support [ON], port: UDP/%1 + + + DHT support [OFF] + DHT support [OFF] + + + PeX support [ON] + PeX support [ON] + + + PeX support [OFF] + PeX support [OFF] + + + Restart is required to toggle PeX support + يجب اعادة تشغيل البرنامج لتفعيل PeX + + + Local Peer Discovery [ON] + ايجاد القرناء المحليين [ON] + + + Local Peer Discovery support [OFF] + ايجاد القرناء المحليين [OFF] + + + Encryption support [ON] + التشفير [ON] + + + Encryption support [FORCED] + التشفير [FORCED] + + + Encryption support [OFF] + التشفير [OFF] + + + The Web UI is listening on port %1 + واجهة الويب تستمع على المنفذ %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + واجهة الويب غير قادرة على استخدام المنفذ %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' تم حذفه من قائمة النقل و من القرص الصلب. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' تم حذفه من قائمة النقل. + + + '%1' is not a valid magnet URI. + '%1' ليس رابطا مغناطيسيا. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' موجود من قبل في قائمة النقل. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1'تم بدء تحميله + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + تمت اضافة '%1' الى قائمة التحميل. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + لا يمكن فك تشفير ملف التورنت '%1' + + + This file is either corrupted or this isn't a torrent. + هذا ليس ملف تورنت أو أنه تالف. + + + Note: new trackers were added to the existing torrent. + ملاحظة:تمت اضافة التراكر الجديد الى ملف التورنت. + + + Note: new URL seeds were added to the existing torrent. + ملاحظة:تمت اضافة URL الجديد الى ملف التورنت. + + + Error: The torrent %1 does not contain any file. + Error: The torrent %1 does not contain any file. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>تم حجبه نظرا لمنقي الاي بي لديك</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>تم حجبه نظرا لوجود قطع فاسدة</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Recursive download of file %1 embedded in torrent %2 + + + Unable to decode %1 torrent file. + غير قادر على فك تشفير ملف التورنت %1. + + + Torrent name: %1 + Torrent name: %1 + + + Torrent size: %1 + Torrent size: %1 + + + Save path: %1 + مكان الحفظ:%1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + The torrent was downloaded in %1. + + + Thank you for using qBittorrent. + شكرا لاستخدامك qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 has finished downloading + + + An I/O error occured, '%1' paused. + خطأ في I/O '%1' تم ايقافه. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port mapping failure, message: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port mapping successful, message: %1 + + + File sizes mismatch for torrent %1, pausing it. + File sizes mismatch for torrent %1, pausing it. + + + Fast resume data was rejected for torrent %1, checking again... + Fast resume data was rejected for torrent %1, البحث مجددا... + + + Reason: %1 + السبب:%1 + + + Url seed lookup failed for url: %1, message: %2 + Url seed lookup failed for url: %1, message: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + جاري تحميل '%1' الرجاء الانتظار... + + + + ConsoleDlg + + qBittorrent log viewer + عارض سجل qBittorrent + + + General + عام + + + Blocked IPs + الاي بي المحجوب + + + + CookiesDlg + + + Cookies management + Cookies management + + + + Key + As in Key/Value pair + المفتاح + + + + Value + As in Key/Value pair + القيمة + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + تم تحديث dynamic DNS بنجاح. + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + خطأ في Dynamic DNS :الخدمة غير متوفرة حاليا ستتم إعادة المحاولة بعد 30 دقيقة. + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + خطأ في Dynamic DNS :اسم المستخدم غير موجود. + + + + Dynamic DNS error: Invalid username/password. + خطأ في Dynamic DNS :اسم المستخدم او كلمة المرور خاطئة. + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + خطأ في Dynamic DNS :البرنامج تمت اضافته للقائمة السوداء الرجاء إرسال الخطأ الى http://bugs.qbittorrent.org. + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + خطأ في Dynamic DNS :%1 تم استرجاعه من الخدمة, الرجاء إرسال الخطأ الى http://bugs.qbittorrent.org. + + + + Dynamic DNS error: Your username was blocked due to abuse. + خطأ في Dynamic DNS :اسم المستخدم تم تعطيله لكثرة التحديثات. + + + + Dynamic DNS error: supplied domain name is invalid. + خطأ في Dynamic DNS :اسم النطاق خاطئ. + + + + Dynamic DNS error: supplied username is too short. + خطأ في Dynamic DNS :اسم المستخدم قصير جداً. + + + + Dynamic DNS error: supplied password is too short. + خطأ في Dynamic DNS :كلمة المرور قصيرة جداً. + + + + DownloadThread + + + + I/O Error + I/O Error + + + + The remote host name was not found (invalid hostname) + اسم المستخدم غير موجود أو خاطئ + + + + The operation was canceled + العملية الغيت + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + الخادم اغلق الإتصال نهائيا, قبل انهاء ومعالجة الطلب + + + + The connection to the remote server timed out + إنقطع الإتصال مع الخادم + + + + SSL/TLS handshake failed + SSL/TLS handshake failed + + + + The remote server refused the connection + الخادم رفض الإتصال + + + + The connection to the proxy server was refused + رفض الإتصال مع خادم البروكسي + + + + The proxy server closed the connection prematurely + الإتصال مع خادم البروكسي اغلق تماما + + + + The proxy host name was not found + لا يوجد اسم مستخدم للبروكسي + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + الإتصال مع البروكسي انقطع ام لم يرد في الفترة المطلوبة + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + البروكسي يتطلب اثبات + + + + The access to the remote content was denied (401) + الدخول ممنوع.(401) + + + + The operation requested on the remote content is not permitted + العملية مرفوضة + + + + The remote content was not found at the server (404) + المعلومات غير موجودة في الخادم + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + الخادم يتطلب اثبات لعرض البيانات لكنه رفض اثباتك + + + + The Network Access API cannot honor the request because the protocol is not known + لا يمكن الدخول للشبكة عن طريق API لان البروتوكول غير معروف + + + + The requested operation is invalid for this protocol + العملية للبروتوكول خطأ + + + + An unknown network-related error was detected + خطأ شبكة غير معروف + + + + An unknown proxy-related error was detected + خطأ غير معروف للبروكسي + + + + An unknown error related to the remote content was detected + خطأ خادم متعلق بالمعلومات + + + + A breakdown in protocol was detected + يوجد خطأ في البروتوكول + + + + Unknown error + خطأ غير معروف + + + + EventManager + + + + Working + يعمل + + + + Updating... + جاري التحديث... + + + + + Not working + لا يعمل + + + + + Not contacted yet + لم يتم الاتصال + + + + + this session + هذه الجلسة + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + تم رفعه %1 + + + + %1 max + e.g. 10 max + %1 أقصى + + + + + %1/s + e.g. 120 KiB/s + %1/s + + + + ExecutionLog + + Form + اللائحة + + + + General + عام + + + + Blocked IPs + الاي بي المحجوب + + + + FeedDownloader + + RSS Feed downloader + RSS Feed downloader + + + RSS feed: + RSS feed: + + + Feed name + اسم الرابط + + + Automatically download torrents from this feed + التحميل تلقائيا من هذا الرابط + + + Download filters + منقيات التحميل + + + Filters: + المنقيات: + + + Filter settings + خيارات المنقي + + + Matches: + يشابه: + + + Does not match: + لا بشابه: + + + Destination folder: + المجلد المستهدف: + + + ... + ... + + + Filter testing + تجربة المنقي + + + Torrent title: + اسم ملف التورنت: + + + Result: + النتيجة: + + + Test + تجربة + + + Import... + إدخال... + + + Export... + إخراج... + + + Rename filter + اعادة تسمية المنقي + + + Remove filter + إزالة المنقي + + + Add filter + أضف منقي + + + + FeedDownloaderDlg + + New filter + منقي جديد + + + Please choose a name for this filter + اختر اسما للمنقي رجاءً + + + Filter name: + اسم المنقي: + + + Invalid filter name + اسم المنقي غير صالح + + + The filter name cannot be left empty. + لا يمكن ترك اسم منقي فارغ. + + + This filter name is already in use. + اسم المنقي مستخدم مسبقا. + + + Choose save path + اختر مكان الحفظ + + + Filter testing error + خطأ في تجربة المنقي + + + Please specify a test torrent name. + اختر اسما لتجربته. + + + matches + يشابه + + + does not match + لا يشابه + + + Select file to import + اختر ملفا للاستيراد + + + Filters Files + ملفات المنقيات + + + Import successful + الإدخال ناجح + + + Filters import was successful. + إدخال المنقي تم بنجاح. + + + Import failure + إدخال فاشل + + + Filters could not be imported due to an I/O error. + لا يمكن إدخال المنقي نظرا لوجود خطأ في I/O. + + + Select destination file + اختر الملف المطلوب + + + Export successful + الإخراج ناجح + + + Filters export was successful. + تم إخراج المنقي بنجاح. + + + Export failure + إخراج فاشل + + + Filters could not be exported due to an I/O error. + لا يمكن إخراج المنقي نظرا لوجود خطأ في I/O. + + + + FeedList + + Unread + غير مقروء + + + + FeedListWidget + + + RSS feeds + RSS feeds + + + + Unread + غير مقروء + + + + GUI + + Open Torrent Files + فتح ملف تورنت + + + Torrent Files + ملفات التورنت + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent ليس البرنامج المفضل لفتح ملفات التورنت او الروابط الممغنطة +هل تريد ربط qBittorrent بملفات التورنت او الروابط الممغنطة ؟ + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + DL سرعة: %1 كيلو ب/ث + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + UP سرعة: %1 كيلو ب/ث + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + تم الانتهاء من تحميل %1. + + + I/O Error + i.e: Input/Output Error + خطأ في I/O + + + Search + البحث + + + RSS + RSS + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + خطأ في تحميل الرابط + + + Couldn't download file at url: %1, reason: %2. + خطأ في تحميل الرابط: %1, السبب: %2. + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + خطأ I/O حصل للملف %1 + السبب: %2 + + + Set the password... + ادخل كلمة المرور... + + + Transfers + النقل + + + Torrent file association + الإرتباط بملف التورنت + + + Password update + تحديث كلمة المرور + + + The UI lock password has been successfully updated + The UI lock password has been successfully updated + + + Transfers (%1) + النقل (%1) + + + Download completion + انتهاء التحميل + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + التأكد عند التحميل تقدميا + + + The torrent %1 contains torrent files, do you want to proceed with their download? + الملف %1 به ملفات تورنت اخرى هل تريد التحميل؟ + + + Yes + نعم + + + No + لا + + + Never + ابدا + + + Global Upload Speed Limit + حدود سرعة الرفع العامة + + + Global Download Speed Limit + حدود سرعة التحميل العامة + + + A newer version is available + إصدار أحدث متوفر + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + هناك اصدار جديد %1, هل ترغب في التحديث؟ + + + Impossible to update qBittorrent + من المستحيل تحديث qBittorrent + + + qBittorrent failed to update, reason: %1 + لا يمكن تحديث البرنامج,السبب %1 + + + UI lock password + كلمة مرور قفل الواجهة + + + Please type the UI lock password: + أدخل كلمة مرور قفل الواجهة: + + + Invalid password + كلمة مرور خاطئة + + + The password is invalid + كلمة المرور خاطئة + + + Exiting qBittorrent + Exiting qBittorrent + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + توجد ملفات فعالة . +هل تريد الخروج؟ + + + Always + دائما + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Down: %2/s, Up: %3/s) + + + Options were saved successfully. + تم حفظ الخيارات بنجاح. + + + + GeoIP + + Australia + استراليا + + + Argentina + ارجنتينا + + + Austria + النمسا + + + United Arab Emirates + الامارات العربية المتحدة + + + Brazil + البرازيل + + + Bulgaria + بلغاريا + + + Belarus + بيلاروس + + + Belgium + بلجيكا + + + Bosnia + البوسنة + + + Canada + كندا + + + Czech Republic + التشيك + + + China + الصين + + + Costa Rica + كوستاريكا + + + Switzerland + سويسرا + + + Germany + المانيا + + + Denmark + الدنمارك + + + Algeria + الجزائر + + + Spain + اسبانيا + + + Egypt + مصر + + + Finland + فنلندا + + + France + فرنسا + + + United Kingdom + بريطانيا + + + Greece + اليونان + + + Georgia + جورجيا + + + Hungary + هنغاريا + + + Croatia + كرواتيا + + + Italy + ايطاليا + + + India + الهند + + + Israel + اسرائيل + + + Ireland + ايرلندا + + + Iceland + ايسلندا + + + Indonesia + اندونيسيا + + + Japan + اليابان + + + South Korea + كوريا الجنوبية + + + Luxembourg + لكسمبورغ + + + Malaysia + مالبزيا + + + Mexico + المكسيك + + + Serbia + الصرب + + + Morocco + المغرب + + + Netherlands + هولندا + + + Norway + النرويج + + + New Zealand + نيوزبلندا + + + Portugal + البرتغال + + + Poland + بولندا + + + Pakistan + باكستان + + + Philippines + الفلبين + + + Russia + روسيا + + + Romania + رومانيا + + + France (Reunion Island) + فرنسا جزيرة الالتقاء + + + Saudi Arabia + السعودية + + + Sweden + السويد + + + Slovakia + سلوفاكيا + + + Singapore + سنغافورة + + + Slovenia + سلوفانيا + + + Taiwan + تايوان + + + Turkey + تركيا + + + Thailand + تايلند + + + USA + امريكا + + + Ukraine + اوكرانيا + + + South Africa + افريقيا الجنوبية + + + + HeadlessLoader + + + Information + معلومات + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + To control qBittorrent, access the Web UI at http://localhost:%1 + + + + The Web UI administrator user name is: %1 + إسم المستخدم لواجهة الويب هو:%1 + + + + The Web UI administrator password is still the default one: %1 + كلمة السر لواجهة الويب هي:%1 + + + + This is a security risk, please consider changing your password from program preferences. + خطر امني غير كلمة السر. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + تم رفضك لكثرة المحاولات الفاشلة. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - T: %2 + + + + HttpServer + + + File + ملف + + + + Edit + تعديل + + + + Help + مساعدة + + + Delete from HD + مسح من القرص الصلب + + + + Download Torrents from their URL or Magnet link + حمل تورنت من رابط او مغناطيس + + + + Only one link per line + رابط واحد لكل سطر + + + + Download local torrent + حمل تورنت محلي + + + + Torrent files were correctly added to download list. + ملفات التورنت تمت اضافتها بنجاح لقائمة التحميل. + + + + Point to torrent file + التوجيه الى ملف تورنت + + + + Download + تحميل + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + هل انت متأكد من رغبتك في حذف التورنت من قائمة النقل و من القرص الصلب؟ + + + + Download rate limit must be greater than 0 or disabled. + حد التحميل يجب ان يكون أكبر من 0 او معطل. + + + + Upload rate limit must be greater than 0 or disabled. + حد الرفع يجب ان أكبر من يكون 0 او معطل. + + + + Maximum number of connections limit must be greater than 0 or disabled. + حد الاتصالات يجب ان يكون أكبر من 0 او معطل. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + حد الاتصالات لكل تورنت يجب ان يكون أكبر من 0 او معطل. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + حد وحدة الرفع لكل تورنت يجب ان يكون أكبر من 0 او معطل. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + غير قادر على حفظ الخيارات , لا يمكن الاتصال بالبرنامج حاليا. + + + + Language + اللغة + + + + Downloaded + Is the file downloaded or not? + تم تحميله + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + منفذ الاتصال يجب ان يكون بين 1024 و 65535. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + منفذ الاتصال لواجهة الويب يجب ان تكون بين 1024 و 65535. + + + + The Web UI username must be at least 3 characters long. + اسم المستخدم يجب ان يحتوي على 3 احرف على الاقل. + + + + The Web UI password must be at least 3 characters long. + كلمة المرور يجب ان تحتوي على 3 احرف على الاقل. + + + + Save + حفظ + + + + qBittorrent client is not reachable + لا يمكن الوصول للبرنامج + + + + HTTP Server + خادم HTTP + + + + The following parameters are supported: + الأسماء المسموحة: + + + + Torrent path + مكان التورنت + + + + Torrent name + إسم التورنت + + + + LegalNotice + + + Legal Notice + ملاحظة قانونية + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + البرنامج هذا يستخدم تقنية المشاركة و اي معلومات تنتج عنه هي من مسؤوليتك انت فقط. + + + + Press %1 key to accept and continue... + اضغط %1 للقبول و المتابعة... + + + + Legal notice + ملاحظة قانونية + + + + Cancel + الغاء + + + + I Agree + انا اوافق + + + + LineEdit + + + Clear the text + مسح النص + + + + MainWindow + + + &Edit + &تعديل + + + + &Tools + &أدوات + + + + &File + &ملف + + + + &Help + &مساعدة + + + + &View + &عرض + + + &Add File... + &أضف ملف... + + + E&xit + &خروج + + + + &Options... + &خيارات... + + + Add &URL... + أضف &URL... + + + + Torrent &creator + انشاء &تورنت + + + Log viewer + عرض السجل + + + + + Alternative speed limits + السرعات البديلة + + + + Top &tool bar + الشريط &العلوي + + + + Display top tool bar + عرض الشريط العلوي + + + + &Speed in title bar + &السرعة في شريط المهام + + + + Show transfer speed in title bar + عرض السرعة في شريط المهام + + + + &About + &معلومات + + + + Auto-Shutdown on downloads completion + ايقاف الكمبيوتر بعد انهاء التحميل + + + + &Pause + &ايقاف مؤقت + + + + &Delete + &حذف + + + + P&ause All + &ايقاف الكل + + + + &Resume + &الاكمال + + + + &Add torrent file... + &فتح ملف تورنت... + + + + + Exit + خروج + + + + R&esume All + &اكمال الكل + + + + Visit &Website + زيارة &الموقع + + + + Add &link to torrent... + فتح &رابط تورنت... + + + Preview file + استعراض الملف + + + Clear log + مسح السجل + + + + Report a &bug + ابلاغ عن &خلل + + + + Set upload limit... + ضع حد الرفع... + + + + Set download limit... + ضع حد التحميل... + + + + &Documentation + &التعليمات + + + + Set global download limit... + ضع حد التحميل العام... + + + + Set global upload limit... + ضع حد الرفع العام... + + + + Exit qBittorrent + اطفاء البرنامج + + + + Suspend system + ايقاف مؤقت للنظام + + + + Shutdown system + ايقاف النظام + + + + Disabled + معطل + + + &Log viewer... + &عرض السجل... + + + Shutdown computer when downloads complete + ايقاف الكمبيوتر بعد انهاء التحميل + + + + + Lock qBittorrent + قفل البرنامج + + + + Ctrl+L + Ctrl+L + + + Shutdown qBittorrent when downloads complete + ايقاف تشغيل الكمبيوتر بعد انهاء التحميل + + + + Import existing torrent... + استيراد ملف التورنت... + + + + Import torrent... + استيراد ملف التورنت... + + + + Donate money + تبرع و لا تصير قعيطي + + + + If you like qBittorrent, please donate! + تبرع! + + + + Execution &Log + &السجل + + + + + Execution Log + السجل + + + + &RSS reader + &قارئ RSS + + + + Search &engine + محرك &البحث + + + + Decrease priority + تقليص الاهمية + + + + Increase priority + زيادة الاهمية + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + ادخل كلمة المرور... + + + + Transfers + النقل + + + + Torrent file association + الإرتباط بملف التورنت + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent ليس البرنامج المفضل لفتح ملفات التورنت او الروابط الممغنطة +هل تريد ربط qBittorrent بملفات التورنت او الروابط الممغنطة ؟ + + + + + + UI lock password + كلمة مرور قفل الواجهة + + + + + + Please type the UI lock password: + أدخل كلمة مرور قفل الواجهة: + + + + The password should contain at least 3 characters + كلمة المرور يجب ان لا تقل عن ثلاثة رموز + + + + Password update + تحديث كلمة المرور + + + + The UI lock password has been successfully updated + تم تحديث كلمة المرور + + + + RSS + RSS + + + + Search + البحث + + + + Transfers (%1) + النقل (%1) + + + + Download completion + انتهاء التحميل + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + تم الانتهاء من تحميل %1. + + + + I/O Error + i.e: Input/Output Error + I/O Error + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + خطأ I/O حصل للملف %1 + السبب: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + التأكد عند التحميل تقدميا + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + الملف %1 به ملفات تورنت اخرى هل تريد التحميل؟ + + + + + Yes + نعم + + + + + No + لا + + + + Never + أبدا + + + + Url download error + خطأ في تحميل الرابط + + + + Couldn't download file at url: %1, reason: %2. + خطأ في تحميل الرابط: %1, السبب: %2. + + + + Global Upload Speed Limit + حدود سرعة الرفع العامة + + + + Global Download Speed Limit + حدود سرعة التحميل العامة + + + + + Invalid password + كلمة مرور خاطئة + + + + The password is invalid + كلمة المرور خاطئة + + + + Exiting qBittorrent + جاري اطفاء البرنامج + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + توجد ملفات فعالة . +هل تريد الخروج؟ + + + + Always + دائما + + + + Open Torrent Files + فتح ملف تورنت + + + + Torrent Files + ملفات التورنت + + + + Options were saved successfully. + تم حفظ الخيارات بنجاح. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + DL speed: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + UP speed: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Down: %2/s, Up: %3/s) + + + + A newer version is available + هناك إصدار أحدث متوفر + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + هناك اصدار جديد %1, هل ترغب في التحديث؟ + + + + Impossible to update qBittorrent + لا يمكن تحديث qBittorrent + + + + qBittorrent failed to update, reason: %1 + لا يمكن تحديث البرنامج,السبب %1 + + + + PeerAdditionDlg + + + Invalid IP + اي بي غير صحيح + + + + The IP you provided is invalid. + الاي بي الذي ادخلته غير صحيح. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + اي بي + + + + Connection + الاتصال + + + + Client + i.e.: Client application + العميل + + + + Progress + i.e: % downloaded + الحالة + + + + Down Speed + i.e: Download speed + سرعة التحميل + + + + Up Speed + i.e: Upload speed + سرعة الرفع + + + + Downloaded + i.e: total data downloaded + تم تحميله + + + + Uploaded + i.e: total data uploaded + تم رفعه + + + + Add a new peer... + اضافة قرين جديد... + + + + Copy IP + نسخ الايبي + + + + Limit download rate... + وضع حد التحميل... + + + + Limit upload rate... + وضع حد الرفع... + + + + Ban peer permanently + منع القرين نهائيا + + + + + Peer addition + اضافة القرناء + + + + The peer was added to this torrent. + تم اضافة القرين للملف. + + + + The peer could not be added to this torrent. + لم تتم اضافة القرين للملف. + + + + Are you sure? -- qBittorrent + هل أنت متأكد؟ -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + هل انت متأكد من رغبتك في منع القرناء؟ + + + + &Yes + &نعم + + + + &No + &لا + + + + Manually banning peer %1... + Manually banning peer %1... + + + + Upload rate limiting + وضع حد الرفع + + + + Download rate limiting + وضع حد التحميل + + + + Preferences + + UI + User Interface + واجهة المستخدم + + + + Downloads + التحميل + + + + Connection + الاتصال + + + + Speed + السرعة + + + Bittorrent + Bittorrent + + + Proxy + Proxy + + + + Web UI + واجهة المستخدم التصفحية + + + + Advanced + متقدم + + + Language: + اللغة: + + + + (Requires restart) + يحتاج لاعادة تشغيل + + + Visual style: + المظهر: + + + Transfer list + قائمة النقل + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + استخدام الوان متضادة للاسطر + + + + + Start / Stop Torrent + تشغيل / إيقاف التورنت + + + + + No action + بلا تأثير + + + File system + نظام الملفات + + + + Copy .torrent files to: + نسخ ملفات .torrent الى المجلد: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + + + + Listening Port + منفذ الاستماع + + + + Connections Limits + حد الاتصالات + + + + Proxy Server + خادم البروكسي + + + + Enable bandwidth management (uTP) + تفعيل خاصية إدارة ضغط الشبكة (uTP) + + + + Enable Local Peer Discovery to find more peers + ايجاد القرناء المحليين + + + + Encryption mode: + نظام التشفير: + + + + Prefer encryption + تفضيل التشفير + + + + Require encryption + طلب التشفير + + + + Disable encryption + تعطيل التشفير + + + Torrent queueing + Torrent queueing + + + + Maximum active downloads: + الحد الاقصى للتحميلات الفعالة: + + + + Maximum active uploads: + الحد الاقصى للرفع الفعال: + + + + Maximum active torrents: + الحد الاقصى للملفات الفعالة: + + + + When adding a torrent + عند اضافة تورنت + + + + Display torrent content and some options + اعرض المحتويات و بعض الخيارات + + + Listening port + منفذ الاستماع + + + + Port used for incoming connections: + الاتصالات تستمع على المنفذ: + + + + Random + عشوائي + + + Enable UPnP port mapping + Enable UPnP port mapping + + + Enable NAT-PMP port mapping + Enable NAT-PMP port mapping + + + Connections limit + حد الاتصالات + + + + Global maximum number of connections: + اكبر كمية من الاتصالات الممكنة: + + + + Maximum number of connections per torrent: + اكبر كمية من الاتصالات الممكنة لكل تورنت: + + + + Maximum number of upload slots per torrent: + حد وحدة الرفع لكل تورنت : + + + + + Upload: + الرفع: + + + + + Download: + التحميل: + + + + + + + KiB/s + KiB/s + + + Global speed limits + حد الرفع العام + + + + Remove folder + حذف المجلد + + + + + Behavior + التصرف + + + + Language + اللغة + + + Alternative global speed limits + حد السرعة المحدودة + + + + to + time1 to time2 + الى + + + + Every day + كل يوم + + + + Week days + ايام الاسبوع + + + + Week ends + عطلة الاسبوع + + + Bittorrent features + خصائص Bittorrent + + + Enable DHT network (decentralized) + Enable DHT network (decentralized) + + + Use a different port for DHT and Bittorrent + استخدام منفذ مختلف DHT and Bittorrent + + + + DHT port: + منفذ DHT : + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + + + Enable Peer Exchange / PeX (requires restart) + Enable Peer Exchange / PeX (يحتاج لاعادة تشغيل) + + + Enable Local Peer Discovery + ايجاد القرناء المحليين + + + Enabled + مفعل + + + Forced + Forced + + + Disabled + معطل + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP إتصالات (تراكرز , Web seeds,محرك البحث) + + + + Host: + الاسم: + + + Peer Communications + اتصالات القرناء + + + + SOCKS4 + SOCKS4 + + + + Type: + النوع: + + + + + Options + خيارات + + + Visual Appearance + المظهر + + + + Action on double-click + ردة الفعل للنقر المزدوج + + + + Downloading torrents: + تحميل تورنت: + + + Start / Stop + تشغيل/ايقاف + + + + + Open destination folder + فتح المجلد المستهدف + + + + Completed torrents: + الملفات المنتهية: + + + + Desktop + سطح المكتب + + + + Show splash screen on start up + اظهار شاشة السبلاش عند بدء التشغيل + + + + Start qBittorrent minimized + بدء البرنامج مصغرا + + + Show qBittorrent icon in notification area + اظهار الايقونة في شريط المهام + + + Use monochrome system tray icon (requires restart) + Use monochrome system tray icon (requires restart) + + + + Minimize qBittorrent to notification area + تصغير البرنامج الى شريط المهام + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + اغلاق البرنامج الى شريط المهام + + + + Tray icon style: + مظهر أيقونة شريط المهام: + + + + Normal + عادي + + + + Monochrome (Dark theme) + Monochrome (Dark theme) + + + + Monochrome (Light theme) + Monochrome (Light theme) + + + + Ask for program exit confirmation + تأكيد اغلاق البرنامج + + + + User Interface Language: + لغة واجهة المستخدم: + + + + Transfer List + قائمة النقل + + + + Show qBittorrent in notification area + اظهار الايقونة في شريط المهام + + + + Power Management + التحكم بالطاقة + + + + Inhibit system sleep when torrents are active + عدم ايقاف تشغيل الكمبيوتر قبل انهاء التحميل + + + + Do not start the download automatically + The torrent will be added to download list in pause state + عدم بدء التحميل تلقائيا + + + + Hard Disk + القرص + + + + Save files to location: + حفظ الملفات الى: + + + + Append the label of the torrent to the save path + وضع الملصق في مجلد الحفظ + + + + Pre-allocate disk space for all files + Pre-allocate disk space for all files + + + + Keep incomplete torrents in: + حفظ الملفات الغير منتهية في: + + + Append .!qB extension to incomplete files' names + وضع علامة !qB للملفات الغير منتهية + + + + Automatically add torrents from: + التحميل تلقائيا من: + + + + Add folder... + اضافة مجلد جديد... + + + + Email notification upon download completion + ارسال ايميل عند انتهاء التحميل + + + + Destination email: + الايميل: + + + + SMTP server: + SMTP server: + + + + This server requires a secure connection (SSL) + الخادم يتطلب إتصالاً محمياً (SSL) + + + + Run an external program on torrent completion + تشغيل برنامج عند انتهاء التحميل + + + + Otherwise, the proxy server is only used for tracker connections + البروكسي سيفعل على إتصالات المتتبعات فقط + + + + Use proxy for peer connections + إستخدام البروكسي على إتصالات القرناء + + + + Global Rate Limits + حد السرعة العام + + + + Apply rate limit to uTP connections + تفعيل حد السرعة على إتصالات uTP + + + + Apply rate limit to transport overhead + تفعيل حد السرعة على النقل و التحميل + + + + Alternative Global Rate Limits + حد السرعات البديلة + + + + Schedule the use of alternative rate limits + تفعيل السرعة البديلة في وقت محدد + + + + Use HTTPS instead of HTTP + إستخدام HTTPS بدلاً من HTTP + + + + Import SSL Certificate + إستيراد شهادة SSL + + + + Import SSL Key + إستيراد مفتاح SSL + + + + Certificate: + شهادة: + + + + Key: + مفتاح: + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + Update my dynamic domain name + تحديث Dynamic Dns + + + + Service: + الخدمة: + + + + Register + تسجيل + + + + Domain name: + إسم النطاق: + + + Use %f to pass the torrent path in parameters + Use %f to pass the torrent path in parameters + + + + Use UPnP / NAT-PMP port forwarding from my router + استخدام UPnP / NAT-PMP لفتح المنافذ تلقائيا + + + Proxy server + خادم البروكسي + + + + IP Filtering + تنقية الايبي + + + + Reload the filter + تحديث المنقيات + + + Schedule the use of alternative speed limits + تفعيل السرعة البديلة في وقت محدد + + + + from + from (time1 to time2) + من + + + + When: + متى: + + + + Privacy + الخصوصية + + + + Enable DHT (decentralized network) to find more peers + تفعيل DHT لإيجاد قرناء أكثر + + + + Use a different port for DHT and BitTorrent + استخدام منفذ مختلف DHT and Bittorrent + + + + Enable Peer Exchange (PeX) to find more peers + تفعيل PeX لإيجاد قرناء أكثر + + + + Look for peers on your local network + ايجاد القرناء المحليين + + + + Torrent Queueing + صف التورنت + + + + Share Ratio Limiting + حد نسبة المشاركة + + + + Use UPnP / NAT-PMP to forward the port from my router + استخدام UPnP / NAT-PMP لفتح المنافذ تلقائيا + + + + Bypass authentication for localhost + Bypass authentication for localhost + + + Protocol encryption: + Protocol encryption: + + + Share ratio limiting + حد نسبة المشاركة + + + + Seed torrents until their ratio reaches + رفع التورنت الى نسبة + + + + then + ثم + + + + Pause them + ايقاف مؤقت + + + + Remove them + حذف التورنت + + + + (None) + (None) + + + User Interface + واجهة المستخدم + + + + BitTorrent + BitTorrent + + + + HTTP + HTTP + + + + + Port: + منفذ: + + + + + + Authentication + اثبات + + + + Append .!qB extension to incomplete files + وضع علامة !qB للملفات الغير منتهية + + + + + + + Username: + اسم المستخدم: + + + + + + + Password: + كلمة المرور: + + + + Enable Web User Interface (Remote control) + Enable Web User Interface (Remote control) + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + عنوان المنقي (.dat, .p2p, .p2b): + + + HTTP Server + HTTP Server + + + + PreviewSelect + + + Name + الاسم + + + + Size + الحجم + + + + Progress + الحالة + + + + + + Preview impossible + لايمكن الاستعراض + + + + + + Sorry, we can't preview this file + نأسف لكن لا يمكن استعراض الملف + + + + ProgramUpdater + + Could not create the file %1 + خطأ في انشاء الملف %1 + + + Failed to download the update at %1 + %1 is an URL + فشل تحميل التحديث في %1 + + + + PropListDelegate + + + Not downloaded + لم تتحمل + + + + + Normal + Normal (priority) + عادي + + + + + High + High (priority) + مرتفع + + + + Mixed + Mixed (priorities + مختلط + + + + + Maximum + Maximum (priority) + اقصى اهمية + + + + PropTabBar + + + General + عام + + + + Trackers + مواقع التتبع + + + + Peers + القرناء + + + + HTTP Sources + مصادر HTTP + + + + Content + المحتوى + + + URL Seeds + URL seeds + + + Files + الملفات + + + + PropertiesWidget + + + Save path: + مكان الحفظ: + + + + Torrent hash: + Torrent hash: + + + + Share ratio: + نسبة المشاركة: + + + + + Downloaded: + تم تحميل: + + + + Availability: + التواجد: + + + + Transfer + نقل + + + + Uploaded: + تم رفع: + + + + Wasted: + تم تضييع: + + + + UP limit: + حد الرفع: + + + + DL limit: + حد التحميل: + + + Time elapsed: + وقت مضى: + + + + Connections: + الاتصالات: + + + + Time active: + Time (duration) the torrent is active (not paused) + مدة النشاط: + + + + Reannounce in: + Reannounce in: + + + + Information + المعلومات + + + + Created on: + انشئ في: + + + + Pieces size: + حجم القطعة: + + + + Comment: + تعليق: + + + + Torrent content: + محتوى التورنت: + + + + Select All + اختيار الكل + + + + Select None + اختيار لا شئ + + + General + عام + + + Trackers + تراكرات + + + Peers + القرناء + + + URL seeds + URL seeds + + + Files + الملفات + + + + Normal + عادي + + + + High + مرتفع + + + + Maximum + اقصى اهمية + + + + + Do not download + لا تحمل + + + + + this session + هذه الجلسة + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Seeded for %1 + + + + %1 max + e.g. 10 max + %1 اقصى + + + + + I/O Error + خطأ I/O + + + + This file does not exist yet. + هذا الملف لا يوجد بعد. + + + + This folder does not exist yet. + هذا المجلد لا يوجد بعد. + + + + Rename... + اعد التسمية... + + + + Priority + الأفضلية + + + + Rename the file + اعادة تسمية الملف + + + + New name: + الاسم الجديد: + + + + + The file could not be renamed + لا يمكن اعادة تسمية الملف + + + + This file name contains forbidden characters, please choose a different one. + اختر اسما بدون رموز خاصة. + + + + + This name is already in use in this folder. Please use a different name. + الاسم مستخدم مسبقا , اختر اسما اخر. + + + + The folder could not be renamed + لا يمكن اعادة تسمية المجلد + + + + New url seed + New HTTP source + New url seed + + + + New url seed: + New url seed: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + This url seed is already in the list. + + + + + Choose save path + اختر مكان الحفظ + + + Save path creation error + خطأ في اختيار مكان الحفظ + + + Could not create the save path + خطأ في انشاء مكان الحفظ + + + + QBtSession + + + + %1 reached the maximum ratio you set. + لقد وصلت الى الحد الاقصى الذي حددته.%1. + + + + Removing torrent %1... + Removing torrent %1... + + + + Pausing torrent %1... + Pausing torrent %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + البرنامج مقيد بالمنفذ: %1 + + + UPnP support [ON] + دعم UPnP [ON] + + + UPnP support [OFF] + دعم تشغيل والتركيب العالمي [غير شغال] + + + NAT-PMP support [ON] + NAT-PMP support [ON] + + + NAT-PMP support [OFF] + NAT-PMP support [OFF] + + + + HTTP user agent is %1 + HTTP user agent is %1 + + + Using a disk cache size of %1 MiB + استخدام ذاكرة بكمية %1 ميجابايت + + + + DHT support [ON], port: UDP/%1 + DHT support [ON], port: UDP/%1 + + + + + DHT support [OFF] + DHT support [OFF] + + + + PeX support [ON] + PeX support [ON] + + + + PeX support [OFF] + PeX support [OFF] + + + + Restart is required to toggle PeX support + يجب اعادة تشغيل البرنامج لتفعيل PeX + + + Local Peer Discovery [ON] + ايجاد القرناء المحليين [ON] + + + + Local Peer Discovery support [OFF] + ايجاد القرناء المحليين [OFF] + + + + Encryption support [ON] + التشفير [ON] + + + + Encryption support [FORCED] + التشفير [بالقوة] + + + + Encryption support [OFF] + التشفير [غير شغال] + + + + Embedded Tracker [ON] + خدمة التراكر الداخلي [يعمل] + + + + Failed to start the embedded tracker! + فشل محاولة تشغيل خدمة التراكر الداخلي! + + + + Embedded Tracker [OFF] + التراكر الداخلي [مغلق] + + + + The Web UI is listening on port %1 + واجهة الويب تستمع على المنفذ %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + واجهة الويب غير قادرة على استخدام المنفذ %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' تم حذفه من قائمة النقل و من القرص الصلب. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' تم حذفه من قائمة النقل. + + + + '%1' is not a valid magnet URI. + '%1' ليس رابطا مغناطيسيا. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' موجود من قبل في قائمة النقل. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1'تم بدء تحميله + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + تمت اضافة '%1' الى قائمة التحميل. + + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP support [ON] + + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP support [OFF] + + + + Reporting IP address %1 to trackers... + Reporting IP address %1 to trackers... + + + + Local Peer Discovery support [ON] + Local Peer Discovery support [ON] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + لا يمكن فك تشفير ملف التورنت '%1' + + + + This file is either corrupted or this isn't a torrent. + هذا ليس ملف تورنت أو أنه تالف. + + + + Error: The torrent %1 does not contain any file. + Error: The torrent %1 does not contain any file. + + + + Note: new trackers were added to the existing torrent. + ملاحظة:تمت اضافة التراكر الجديد الى ملف التورنت. + + + + Note: new URL seeds were added to the existing torrent. + ملاحظة:تمت اضافة URL الجديد الى ملف التورنت. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>تم حجبه نظرا لمنقي الاي بي لديك</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>تم حجبه نظرا لوجود قطع فاسدة</i> + + + + The network interface defined is invalid: %1 + The network interface defined is invalid: %1 + + + + Trying any other network interface available instead. + Trying any other network interface available instead. + + + + Listening on IP address %1 on network interface %2... + Listening on IP address %1 on network interface %2... + + + + Failed to listen on network interface %1 + Failed to listen on network interface %1 + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Recursive download of file %1 embedded in torrent %2 + + + + + Unable to decode %1 torrent file. + غير قادر على فك تشفير ملف التورنت %1. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + سيتم ايقاف الكمبيوتر خلال 15 ثانية ما لم تلغى العملية... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + سيتم اطفاء الكمبيوتر خلال 15 ثانية ما لم تلغى العملية... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + سيتم ايقاف البرنامج خلال 15 ثانية ما لم تلغى العملية... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Successfuly parsed the provided IP filter: %1 rules were applied. + + + + Error: Failed to parse the provided IP filter. + Error: Failed to parse the provided IP filter. + + + + Torrent name: %1 + Torrent name: %1 + + + + Torrent size: %1 + حجم التورنت:%1 + + + + Save path: %1 + مكان الحفظ:%1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + The torrent was downloaded in %1. + + + + Thank you for using qBittorrent. + شكرا لاستخدامك qBittorrent. + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 has finished downloading + + + + An I/O error occured, '%1' paused. + خطأ في I/O '%1' تم ايقافه. + + + + + Reason: %1 + السبب:%1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port mapping failure, message: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port mapping successful, message: %1 + + + + File sizes mismatch for torrent %1, pausing it. + File sizes mismatch for torrent %1, pausing it. + + + + Fast resume data was rejected for torrent %1, checking again... + Fast resume data was rejected for torrent %1, checking again... + + + + Url seed lookup failed for url: %1, message: %2 + Url seed lookup failed for url: %1, message: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + جاري تحميل '%1' الرجاء الانتظار... + + + + RSS + + + Search + البحث + + + + New subscription + اشتراك جديد + + + + + + Mark items read + اعتبرها مقروءة + + + + Update all + تحديث الكل + + + RSS feeds + RSS feeds + + + + RSS Downloader... + RSS Downloader... + + + + Settings... + الخيارات... + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + + + Article title + اسم المقالة + + + Feed URL + Feed URL + + + + + Delete + حذف + + + + Rename... + اعادة تسمية... + + + + Rename + اعادة تسمية + + + + + Update + تحديث + + + + New subscription... + اشتراك جديد... + + + + + Update all feeds + تحديث الكل + + + + Download torrent + تحميل التورنت + + + + Open news URL + فتح الرابط + + + + Copy feed URL + نسخ feed URL + + + RSS feed downloader... + RSS feed downloader... + + + + New folder... + مجلد جديد... + + + + Manage cookies... + Manage cookies... + + + + Refresh RSS streams + تحديث RSS streams + + + + RSSImp + + + Please type a rss stream url + الرجاء كتابة رابط RSS + + + + Stream URL: + Stream URL: + + + + + Are you sure? -- qBittorrent + هل أنت متأكد؟ -- qBittorrent + + + + + &Yes + &نعم + + + + + &No + &لا + + + + Please choose a folder name + اختر اسما للمجلد + + + + Folder name: + اسم الملف: + + + + New folder + مجلد جديد + + + + Overwrite attempt + محاولة اعادة الكتابة + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + لا يمكنك اعادة الكتابة على %1. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + الملف مستخدم مسبقا. + + + + Are you sure you want to delete these elements from the list? + هل انت متأكد من رغبتك في حذف التورنت من قائمة النقل؟ + + + + Are you sure you want to delete this element from the list? + هل انت متأكد من رغبتك في حذف الملف من قائمة النقل؟ + + + + Please choose a new name for this RSS feed + اختر اسما لاشتراك RSS + + + + New feed name: + اسم الرابط الجديد: + + + + Name already in use + الاسم مستخدم مسبقا + + + + This name is already used by another item, please choose another one. + الاسم مستخدم مسبقا , اختر اسما اخر. + + + + Date: + التاريخ: + + + + Author: + المؤلف: + + + + Unread + غير مقروء + + + + RssArticle + + No description available + لا يوجد وصف + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + تحميل %1 تلقائيا من هذا الرابط %2... + + + + RssItem + + No description available + لا يوجد وصف + + + + RssSettings + + RSS Reader Settings + RSS Reader Settings + + + RSS feeds refresh interval: + RSS feeds refresh interval: + + + minutes + دقائق + + + Maximum number of articles per feed: + اكبر كمية من المقالات الممكنة: + + + + RssSettingsDlg + + + RSS Reader Settings + خيارات قارئ RSS + + + + RSS feeds refresh interval: + المدة بين اعادة تحديث المقالات: + + + + minutes + دقائق + + + + Maximum number of articles per feed: + اكبر كمية من المقالات الممكنة: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + تحميل %1 تلقائيا من هذا الرابط %2... + + + + ScanFoldersModel + + + Watched Folder + المجلد المراقب + + + + Download here + حمل هنا + + + + SearchCategories + + + All categories + الكل + + + + Movies + افلام + + + + TV shows + مسلسلات تلفزيونية + + + + Music + موسيقى + + + + Games + العاب + + + + Anime + أنمي + + + + Software + برامج + + + + Pictures + صور + + + + Books + كتب + + + + SearchEngine + + + Cut + قص + + + + Copy + نسخ + + + + Paste + لصق + + + + Clear field + تفريغ الخانة + + + + Clear completion history + تفريق تاريخ الإنتهاء + + + + Confirmation + التأكيد + + + + Are you sure you want to clear the history? + هل انت متأكد من رغبتك في حذف النصوص السابقة؟ + + + + + + Search + البحث + + + + Missing Python Interpreter + موجه Python مفقود + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x مطلوب من اجل إستخدام محرك البحث لاكن لا يبدو انه منصب +هل تريد تنصيبه الآن ؟ + + + + Empty search pattern + تفريغ نمط البحث + + + + Please type a search pattern first + الرجاء كتابة نمط البحث اولا + + + + + Results + النتائج + + + + Searching... + جاري البحث... + + + + Search Engine + محرك البحث + + + + + Search has finished + انتهى البحث + + + + An error occured during search... + حدث خطأ في البحث... + + + + + Search aborted + إيقاف البحث + + + + Download error + خطأ تحميل + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + منصب برنامج Python لم يستطيع التحميل, السبب: %1 +الرجاء التنصيب يدويا. + + + + Search returned no results + لم يجد البحث أية نتيجة + + + + Results + i.e: Search results + النتائج + + + + + Unknown + غير معروف + + + + SearchTab + + + Name + i.e: file name + اسم الملف + + + + Size + i.e: file size + حجم الملف + + + + Seeders + i.e: Number of full sources + رافع + + + + Leechers + i.e: Number of partial sources + محمل + + + + Search engine + محرك البحث + + + + ShutdownConfirmDlg + + + Shutdown confirmation + تأكيد الإيقاف + + + + SpeedLimitDialog + + + KiB/s + KiB/s + + + + StatusBar + + + + Connection status: + حالة الإتصال: + + + + + No direct connections. This may indicate network configuration problems. + لا يوجد اتصال و قد يعود السبب الى اعدادات الشبكة. + + + + + DHT: %1 nodes + DHT: %1 nodes + + + + qBittorrent needs to be restarted + البرنامج يحتاج الى اعادة تشغيل + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + تم تحديث البرنامج ,الرجاء اعادة التشغيل. + + + + + Connection Status: + حالة الإتصال: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + غير متصل. قد تعود المشكلة الى عدم قدرة البرنامج على الاستماع على المنفذ المختار. + + + + Online + متصل + + + + + %1/s + Per second + %1/s + + + + Click to switch to alternative speed limits + اضغط هنا لتفعيل السرعة البديلة + + + + Click to switch to regular speed limits + اضغط هنا لتفعيل السرعة المعتادة + + + Click to disable alternative speed limits + اضغط هنا لتعطيل حد السرعة البديل + + + Click to enable alternative speed limits + اضغط هنا لتشغيل حد السرعة البديل + + + + Global Download Speed Limit + حد سرعة التحميل العامة + + + + Global Upload Speed Limit + حد سرعة الرفع العامة + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + اختر مجلد لإضافة التورنت + + + + Select a file to add to the torrent + إختر ملف لإضافة التورنت + + + Please type an announce URL + الرجاء ادخل رابط التراكر + + + Announce URL: + Tracker URL + موقع التراكر: + + + Please type a web seed url + الرجاء ادخل موقع السيد + + + Web seed URL: + موقع السيد: + + + + No input path set + مكان الحفظ غير مدخل + + + + Please type an input path first + الرجاء ادخال مكان الحفظ اولا + + + + Select destination torrent file + إختر ملف التورنت المستهدف + + + + Torrent Files + ملفات التورنت + + + + + + Torrent creation + انشاء تورنت + + + + Torrent creation was unsuccessful, reason: %1 + فشل انشاء التورنت, السبب:%1 + + + + Created torrent file is invalid. It won't be added to download list. + خطأ في إنشاء ملف التورنت, لن يضاف الى قائمة التنزيل. + + + + Torrent was created successfully: + تم انشاء التورنت بنجاح: + + + + TorrentFilesModel + + + Name + الاسم + + + + Size + الحجم + + + + Progress + الحالة + + + + Priority + الاهمية + + + + TorrentImportDlg + + + Torrent Import + استيراد ملف التورنت + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + هذه الاداة سوف تساعدك في مشاركة ملف سبق و أن حملته. + + + + Torrent file to import: + ملف تورنت للاستيراد: + + + + + ... + ... + + + + Content location: + مكان المحتوى: + + + + Skip the data checking stage and start seeding immediately + ترك الفحص و بدء الرفع مباشرة + + + + Import + إستيراد + + + + Torrent file to import + اختر ملف تورنت للاستيراد + + + + Torrent files (*.torrent) + ملفات التورنت (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + ملفات %1 + + + + Please provide the location of %1 + %1 is a file name + الرجاء إعطاء مكان ملف التورنت %1 + + + + Please point to the location of the torrent: %1 + الرجاء إختيار مكان ملف التورنت %1 + + + + Invalid torrent file + ملف تورنت خاطئ + + + + This is not a valid torrent file. + ملف تورنت خاطئ. + + + + TorrentModel + + + Name + i.e: torrent name + اسم الملف + + + + Size + i.e: torrent size + حجم الملف + + + + Done + % Done + تم تحميل + + + + Status + Torrent status (e.g. downloading, seeding, paused) + الحالة + + + + Seeds + i.e. full sources (often untranslated) + المصادر + + + + Peers + i.e. partial sources (often untranslated) + القرناء + + + + Down Speed + i.e: Download speed + سرعة التحميل + + + + Up Speed + i.e: Upload speed + سرعة الرفع + + + + Ratio + Share ratio + معدل الرفع + + + + ETA + i.e: Estimated Time of Arrival / Time left + الوقت المتبقي + + + + Label + الملصق + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + تاريخ الإضافة + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + تاريخ الإنتهاء + + + + Tracker + موقع التتبع + + + + Down Limit + i.e: Download limit + حد التحميل + + + + Up Limit + i.e: Upload limit + حد الرفع + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + كمية التحميل + + + + Amount left + Amount of data left to download (e.g. in MB) + باقي + + + + Time Active + Time (duration) the torrent is active (not paused) + مدة النشاط + + + + TrackerList + + + URL + الرابط + + + + Status + الحالة + + + + Peers + القرناء + + + + Message + الرسائل + + + + [DHT] + [DHT] + + + + [PeX] + [PeX] + + + + [LSD] + [LSD] + + + + + + + + Working + يعمل + + + + + + Disabled + تعطيل + + + + This torrent is private + هذا التورنت خاص + + + + Updating... + تحديث... + + + + + Not working + لا تعمل + + + + + Not contacted yet + لم يتصل بعد + + + + Add a new tracker... + إضافة تراكر جديد... + + + + Remove tracker + إزالة التراكر + + + + Force reannounce + Force reannounce + + + + TrackersAdditionDlg + + + Trackers addition dialog + نافذة إضافة التراكرز + + + + List of trackers to add (one per line): + لئحة التراكرز للإضافة ) واحدة في كل سطر ): + + + + µTorrent compatible list URL: + لائحة الروابط المتوافقة مع µTorrent: + + + + I/O Error + I/O خطأ + + + + Error while trying to open the downloaded file. + خطأ في فتح الملف المحمل. + + + + No change + لا تغير + + + + No additional trackers were found. + لم يوجد تراكر جديد. + + + + Download error + خطأ تحميل + + + + The trackers list could not be downloaded, reason: %1 + قائمة التراكرز لم تحمل, السبب: %1 + + + + TransferListDelegate + + + Downloading + التحميل + + + + Paused + إيقاف مؤقت + + + + Queued + i.e. torrent is queued + في القائمة + + + + Seeding + Torrent is complete and in upload-only mode + يرفع + + + + Stalled + Torrent is waiting for download to begin + عالق + + + + Checking + Torrent local data is being checked + جاري الفحص + + + + /s + /second (.i.e per second) + /s + + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + + Seeded for %1 + e.g. Seeded for 3m10s + تم رفعه %1 + + + + TransferListFiltersWidget + + + + All + الكل + + + + + Downloading + التحميل + + + + + Completed + انتهى + + + + + Paused + إيقاف مؤقت + + + + + Active + فعال + + + + + Inactive + غير فعال + + + + + All labels + كل الملصقات + + + + + Unlabeled + من غير ملصق + + + + Remove label + إزالة ملصق + + + + Add label... + إضافة ملصق... + + + + Resume torrents + استكمال التورنت + + + + Pause torrents + ايقاف التورنت + + + + Delete torrents + حذف التورنت + + + + New Label + ملصق جديد + + + + Label: + الملصق: + + + + Invalid label name + اسم ملصق خطأ + + + + Please don't use any special characters in the label name. + الرجاء عدم ذكر اسماء تحتوي علي رموز غريبة في اسم الملصق. + + + + TransferListWidget + + Down Speed + i.e: Download speed + سرعة التحميل + + + Up Speed + i.e: Upload speed + سرعة الرفع + + + ETA + i.e: Estimated Time of Arrival / Time left + الوقت المتبقي + + + + Column visibility + وضوح الصفوف + + + Name + i.e: torrent name + الاسم + + + Size + i.e: torrent size + الحجم + + + Done + % Done + انتها + + + Status + Torrent status (e.g. downloading, seeding, paused) + الحالة + + + Seeds + i.e. full sources (often untranslated) + المصادر + + + Peers + i.e. partial sources (often untranslated) + المشاركين + + + Ratio + Share ratio + معدل الرفع + + + + Label + الملصق + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + تاريخ الإضافة + + + Completed On + Torrent was completed on 01/01/2010 08:00 + تاريخ الإنتهاء + + + Tracker + موقع التتبع + + + Down Limit + i.e: Download limit + حد التحميل + + + Up Limit + i.e: Upload limit + حد الرفع + + + + Choose save path + اختر مكان الحفظ + + + Save path creation error + خطأ في اختيار مكان الحفظ + + + Could not create the save path + خطأ في انشاء مكان الحفظ + + + + Torrent Download Speed Limiting + حد التحميل للتورنت + + + + Torrent Upload Speed Limiting + حد الرفع للتورنت + + + + New Label + ملصق جديد + + + + Label: + الملصق: + + + + Invalid label name + اسم خطأ للملصق + + + + Please don't use any special characters in the label name. + الرجاء عدم ذكر اسماء تحتوي علي رموز غريبة في اسم الملصق. + + + + Rename + إعادة تسمية + + + + New name: + اسم جديد: + + + + Resume + Resume/start the torrent + الاكمال + + + + Pause + Pause the torrent + ايقاف مؤقت + + + + Delete + Delete the torrent + حذف + + + + Preview file... + استعراض الملف... + + + + Limit share ratio... + نسبة المشاركة... + + + + Limit upload rate... + وضع حد الرفع... + + + + Limit download rate... + وضع حد التحميل... + + + + Priority + الأفضلية + + + + Open destination folder + فتح المجلد المستهدف + + + + Move up + i.e. move up in the queue + رفع الاهمية + + + + Move down + i.e. Move down in the queue + خفض الأهمية + + + + Move to top + i.e. Move to top of the queue + الرفع للاعلى + + + + Move to bottom + i.e. Move to bottom of the queue + الخفض لاسفل + + + + Set location... + تغيير المكان... + + + + Force recheck + اعادة الفحص + + + + Copy magnet link + نسخ الرابط الممغنط + + + + Super seeding mode + حالة الرافع القوي + + + + Rename... + إعادة تسمية... + + + + Download in sequential order + التحميل بتسلسل + + + + Download first and last piece first + تحميل اول واخر قطعة + + + + New... + New label... + ملصق جديد... + + + + Reset + Reset label + إعادة الملصق + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + حد نسبة التحميل و الرفع + + + + Use global ratio limit + استخدام نسبة المشاركة العامة + + + + + + buttonGroup + buttonGroup + + + + Set no ratio limit + عدم استخدام نسبة المشاركة + + + + Set ratio limit to + نسبة المشاركة + + + + UsageDisplay + + + Usage: + الإستخدام: + + + + displays program version + عرض نسخة البرنامج + + + + disable splash screen + تعطيل شاشة السبلاش + + + + displays this help message + عرض قائمة المساعدة + + + + changes the webui port (current: %1) + تغيير منفذ صفحة الويب ) الحالي:1 (%1 + + + + [files or urls]: downloads the torrents passed by the user (optional) + [ ملفات او روابط [ : يحمل الملفات المارة من المستخدم ) إختياري ) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + اريد شكر المتطوعون في ترجمة هذا البرنامج: + + + + Please contact me if you would like to translate qBittorrent into your own language. + الرجاء الاتصال بي اذا اردت ترجمة البرنامج الى لغتك. + + + + addPeerDialog + + + Peer addition + إضافة قرين + + + + IP + اي بي + + + + Port + منفذ + + + + addTorrentDialog + + + Torrent addition dialog + نافذة اضافة التورنت + + + + Save path: + مكان الحفظ: + + + + ... + ... + + + + Torrent size: + حجم التورنت: + + + + + Unknown + غير معروف + + + + Free disk space: + المساحة المتوفرة في القرص: + + + + Label: + الملصق: + + + + Torrent content: + محتوى التورنت: + + + + Select All + اختيار الكل + + + + Select None + عدم اختيار شيئ + + + + Download in sequential order (slower but good for previewing) + التنزيل المتسلسل ( افضل للإستعراض لكن ابطأ) + + + + Skip file checking and start seeding immediately + ترك الفحص و بدء الرفع مباشرة + + + + Add to download list in paused state + إضافة الى قائمة التنزيل في حالة وقوف مؤقت + + + + Add + اضافة + + + + Cancel + الغاء + + + + Normal + متوسط + + + + High + مهم + + + + Maximum + مهم جدا + + + + + Do not download + لا تحمل + + + + authentication + + + + Tracker authentication + إثبات التراكر + + + + Tracker: + التراكر: + + + + Login + الدخول + + + + Username: + اسم المستخدم: + + + + Password: + كلمة المرور: + + + + Log in + الدخول + + + + Cancel + الغاء + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + تأكيد الحذف للبرنامج + + + + Are you sure you want to delete the selected torrents from the transfer list? + هل انت متأكد من حذف ملفات التورنت من قائمة النقل ؟ + + + + Remember choice + حفظ الاختيار + + + + Also delete the files on the hard disk + حذف الملفات في القرص الصلب ايضا + + + + createTorrentDialog + + + Cancel + إلغاء + + + + Torrent Creation Tool + أدوات إنشاء التورنت + + + + Torrent file creation + انشاء ملفات التورنت + + + + Add file + إضافة ملف + + + + Add folder + إضافة ملف + + + Announce urls (trackers): + التراكر: + + + Comment (optional): + التعليق ) إختياري ): + + + Web seeds urls (optional): + رابط السيد ) إختياري): + + + + File or folder to add to the torrent: + ملف ام مجلد للإضافة للتورنت: + + + + Tracker URLs: + Tracker URLs: + + + + Web seeds urls: + Web seeds urls: + + + + Comment: + تعليق: + + + + Piece size: + حجم القطعة: + + + + 32 KiB + 32 KiB + + + + 64 KiB + 64 KiB + + + + 128 KiB + 128 KiB + + + + 256 KiB + 256 KiB + + + + 512 KiB + 512 KiB + + + + 1 MiB + 1 MiB + + + + 2 MiB + 2 MiB + + + + 4 MiB + 4 MiB + + + + Auto + آلي + + + + Private (won't be distributed on DHT network if enabled) + خاص ) لن تتوزع في شبكة DHTال اذا تفعل الخيار ) + + + + Start seeding after creation + بدء الرفع بعد الإنشاء + + + + Create and save... + إنشاء و حفظ... + + + + Progress: + الحالة: + + + + createtorrent + + Select destination torrent file + إختر ملف التورنت المستهدف + + + Torrent Files + ملفات تورنت + + + No input path set + مكان الحفظ غير مدخل + + + Please type an input path first + الرجاء ادخال مكان الحفظ اولا + + + Torrent creation + انشاء تورنت + + + Torrent was created successfully: + تم النشاء بنجاح: + + + Select a folder to add to the torrent + اختر مجلد لإضافة التورنت + + + Please type an announce URL + الرجاء ادخل رابط التراكر + + + Torrent creation was unsuccessful, reason: %1 + فشل انشاء التورنت, السبب:%1 + + + Announce URL: + Tracker URL + موقع التراكر: + + + Please type a web seed url + الرجاء ادخل موقع السيد + + + Web seed URL: + موقع السيد: + + + Select a file to add to the torrent + إختر ملف لإضافة التورنت + + + Created torrent file is invalid. It won't be added to download list. + خطأ في إنشاء ملف التورنت, لن يضاف الى قائمة التنزيل. + + + + downloadFromURL + + Download Torrents from URLs + تحميل ملفات التورنت من الرابط + + + Only one URL per line + رابط واحد في السطر فقط + + + + Add torrent links + فتح روابط تورنت + + + + Both HTTP and Magnet links are supported + Both HTTP and Magnet links are supported + + + + Download + تحميل + + + + Cancel + الغاء + + + + Download from urls + التحميل من الروابط + + + + No URL entered + الرابط غير موجود + + + + Please type at least one URL. + الرجاء إدخال رابط واحد على الأقل. + + + + downloadThread + + I/O Error + I/O خطأ + + + The remote host name was not found (invalid hostname) + اسم المسخدم غير موجود ) اسم مستخدم خطأ ) + + + The operation was canceled + العملية الغيت + + + The remote server closed the connection prematurely, before the entire reply was received and processed + السرفر اغلق الإتصال نهائيا, قبل انهاء ومعالجة الطلب + + + The connection to the remote server timed out + إنقطع الإتصال مع السرفر + + + SSL/TLS handshake failed + SSL/TLS فشلة المصافحة + + + The remote server refused the connection + السرفر رفض الإتصال + + + The connection to the proxy server was refused + رفض الإتصال مع سرفر البروكسي + + + The proxy server closed the connection prematurely + الإتصال مع سرفر البروكسي اغلق تماما + + + The proxy host name was not found + لا يوجد اسم المستحدم للبروكسي + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + الإتصال مع البروكسي انقطع ام لم يرد في الفترة المطلوبة + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + البروكسي يتطلب اثبات + + + The access to the remote content was denied (401) + الدخول ممنوع. ) 401 ) + + + The operation requested on the remote content is not permitted + العملية مرفوضة + + + The remote content was not found at the server (404) + المعلومات غير موجودة في السرفر + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + السرفر يتطلب اثبات لعرض البيانات لاكن رفض اثباتك + + + The Network Access API cannot honor the request because the protocol is not known + لا يمكن الدخول للشبكة عن طريق APIال لان البروتوكول غير معروف + + + The requested operation is invalid for this protocol + العملية للبروتوكول خطأ + + + An unknown network-related error was detected + خطأ شبكة غير معروف + + + An unknown proxy-related error was detected + خطأ غي معرول للبركسي + + + An unknown error related to the remote content was detected + خطأ سرفر متعلق بالمعلومات + + + A breakdown in protocol was detected + يوجد خطأ في البروتوكول + + + Unknown error + خطأ غير معروف + + + + engineSelect + + + Search plugins + بحث pluginsال + + + + Installed search engines: + تنصيب محراكات البحث: + + + + Name + الإسم + + + + Url + الرابط + + + + + Enabled + تشغيل + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + تستطيع الحصول على محركات البحث pluginsال هنا:<a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + تنصيب واحدة جديدة + + + + Check for updates + البحث عن التحديثات + + + + Close + اغلق + + + Enable + تشغيل + + + Disable + تعطيل + + + + Uninstall + إزالة + + + + engineSelectDlg + + + Uninstall warning + تحذير الإزالة + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + يمكنك فقط مسح Plugins خاصة بك. و لكن تم تعطيل جميع Plugins التي اخترتها انت. + + + + Uninstall success + نجاح الإزالة + + + + Select search plugins + إختر مساعدات البحث + + + + qBittorrent search plugins + مساعدات بحث البرنامج + + + + + + + + Search plugin install + تنصيب مساعدات البحث + + + + + + Yes + نعم + + + + + + + No + لا + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + يوجد نسخة أحدث ل %1 محرك البحث منصبة. + + + + + + + Search plugin update + بحث تحديث لمساعدات البحث + + + + + Sorry, update server is temporarily unavailable. + عذرا خادم التحديث غير متوفر مؤقتا. + + + + All your plugins are already up to date. + كل مساعدات البحث لديك حديثة. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + لا يمكن تحديث %1,تم الرجوع الى النسخة القديمة. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + لا يمكن تنصيب %1. + + + + All selected plugins were uninstalled successfully + تمت ازالة الخيارات + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + تم تحديث %1. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1 search engine plugin was successfully installed. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Sorry, %1 search plugin install failed. + + + + New search engine plugin URL + رابط محرك بحث جديد + + + + URL: + الرابط: + + + + misc + + + B + bytes + بايت + B + + + + KiB + kibibytes (1024 bytes) + كيلوبايت + KiB + + + + MiB + mebibytes (1024 kibibytes) + ميجا بايت + MiB + + + + GiB + gibibytes (1024 mibibytes) + جيجا بايت + GiB + + + + TiB + tebibytes (1024 gibibytes) + تيرا بايت + TiB + + + + %1h %2m + e.g: 3hours 5minutes + %1h %2m + + + + %1d %2h + e.g: 2days 10hours + %1d %2h + + + + Unknown + Unknown (size) + غير معروف ) الحجم ) + غير معروف + + + + qBittorrent will shutdown the computer now because all downloads are complete. + سيتم اطفاء التشغيل الآن. + + + + + + + + + Unknown + غير معروف + + + + < 1m + < 1 minute + < 1 دقيقة + < 1m + + + + %1m + e.g: 10minutes + %1m + + + + options_imp + + + + Choose export directory + إختر مكان للتصدير + + + + + + + Choose a save directory + إختر مكان للحفظ + + + + + Choose an ip filter file + إختر ملف لمنقي الاي بي + + + + Add directory to scan + اضافة مكان الملفات المراد فحصها + + + + Folder is already being watched. + المجلد يستعرض الآن. + + + + Folder does not exist. + المجلد غير موجود. + + + + Folder is not readable. + المجلد غير قابل للقراءة. + + + + Failure + فشل + + + + Failed to add Scan Folder '%1': %2 + فشل اضافة المجلد للفحص '%1: %2 + + + + + Filters + منقيات + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + Parsing error + + + + Failed to parse the provided IP filter + Failed to parse the provided IP filter + + + + Successfully refreshed + التحديث ناجح + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + Succesfully refreshed + التحديث ناجح + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Successfuly parsed the provided IP filter: %1 rules were applied. + + + + pluginSourceDlg + + + Plugin source + موقع مساعد البحث + + + + Search plugin source: + موقع محرك البحث: + + + + Local file + ملف محلي + + + + Web link + رابط موقع + + + + preview + + + Preview selection + معاينة الاختيار + + + + File preview + إستعراض الملف + + + + The following files support previewing, <br>please select one of them: + الملفات التالية تدعم الإستعراض, <br>الرجاء اختيار واحدا منها: + + + + Preview + الإستعراض + + + + Cancel + إلغاء + + + + previewSelect + + Preview impossible + لايمكن الاستعراض + + + Sorry, we can't preview this file + نأسف لاكن لا يمكن اسعراض الملف + + + Name + الاسم + + + Size + الحجم + + + Progress + الحالة + + + + search_engine + + + + Search + البحث + + + + Status: + الحالة: + + + + Stopped + متوقفة + + + + Download + تنزيل + + + + Go to description page + الذهاب الى صفحة الوصف + + + + Search engines... + محركات البحث... + + + + torrentAdditionDialog + + + Unable to decode magnet link: + غير ممكن فك التشفير للرابط الممغنط: + + + + Magnet Link + الرابط الممغنط + + + + + Unable to decode torrent file: + غير ممكن فك التشفير لملف التورنت: + + + + Rename... + إعادة تسمية... + + + + Priority + الاهمية + + + + Rename the file + تغيير اسم الملف + + + + New name: + اسم جديد: + + + + + The file could not be renamed + لا يمكن اعادة تسمية الملف + + + + This file name contains forbidden characters, please choose a different one. + اسم الملف يحتوي على رموز ممنوعة, الرجاء إختيار اسم آخر للملف. + + + + + This name is already in use in this folder. Please use a different name. + هذا الاسم يستعمل في ملف آخر , الرجاء إختيار اسم جديد. + + + + The folder could not be renamed + لا يمكن اعادة تسمية الملف + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1متبقي على تنزيل ملف التورنت) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 أيضاً متبقية على (التنزيل + + + + + + Choose save path + اختر مكان الحفظ + + + + Empty save path + مكان الحفظ فارغ + + + + Please enter a save path + فضلا ادخل مكان الحفظ + + + + Save path creation error + خطأ في مكان الحفظ + + + + Could not create the save path + غير ممكن انشاء مكان الحفظ + + + + Invalid label name + اسم غير صالح للملصق + + + + Please don't use any special characters in the label name. + الرجاء عدم إستخدام رموز خاصة على اسم الملصق. + + + + Seeding mode error + خطأ في وضع الرفع + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + انت اخترت ان تتفادى فحص الملف, لكن الملفات غير موجودة في مكان الحفظ, الرجاء تعطيل هذه الميزة او تعديل مكان حفظ الملف. + + + + Invalid file selection + إختيار ملف خطأ + + + + You must select at least one file in the torrent + يجب عليك اختيار ملف تورنت واحد على الاقل + + + diff --git a/src/lang/qbittorrent_bg.qm b/src/lang/qbittorrent_bg.qm new file mode 100644 index 0000000000000000000000000000000000000000..9502dcc1f238f9dd2e0f761d96a2053017af40da GIT binary patch literal 118498 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 S@3Kj{hzq}mB=P=x@BLq%FA{+O literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_bg.ts b/src/lang/qbittorrent_bg.ts new file mode 100644 index 000000000..5830c510c --- /dev/null +++ b/src/lang/qbittorrent_bg.ts @@ -0,0 +1,6715 @@ + + + + + AboutDlg + + + About qBittorrent + Относно qBittorrent + + + + About + Относно + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Битторент клиент базиран на C++, базиран на Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">и libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Начало:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Форум:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + Author + Автор + + + + Name: + Име: + + + + Country: + Страна: + + + + E-mail: + E-mail: + + + + Christophe Dumez + Christophe Dumez + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Една развита BitTorrent програма-клиент, програмирана на C++, базирана на Qt4 инструменти и libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Главна:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Запис на бъгове:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Форум:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + France + Франция + + + + Translation + Превод + + + + License + Лиценз + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + + chris@qbittorrent.org + chris@qbittorrent.org + + + + Thanks to + Благодарим на + + + + AdvancedSettings + + Property + Характеристика + + + Value + Стойност + + + + Disk write cache size + Размер на записан дисков кеш + + + + MiB + МБ + + + + Outgoing ports (Min) [0: Disabled] + Изходен порт (Мин) [0: Изключен] + + + + Outgoing ports (Max) [0: Disabled] + Изходен порт (Макс) [0: Изключен] + + + + Recheck torrents on completion + Провери торентите при завършване + + + + Transfer list refresh interval + Интервал на обновяване на списъка за трансфер + + + + ms + milliseconds + ms + + + + Setting + Настройка + + + + Value + Value set for this setting + Стойност + + + + Resolve peer countries (GeoIP) + Намери държавата на двойката (GeoIP) + + + + Resolve peer host names + Намери имената на получаващата двойка + + + + Maximum number of half-open connections [0: Disabled] + Максимален брой полу-отворени връзки [0: Изключен] + + + + Strict super seeding + Стриктен режим на супер-даване + + + + Network Interface (requires restart) + Интерфейс на Мрежата (изисква рестарт) + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + Произволен интерфейс + + + + IP Address to report to trackers (requires restart) + IP адрес за информиране на тракери (изисква рестарт) + + + + Display program on-screen notifications + Покажи уведомленията на програмата на екрана + + + Display program notification balloons + Покажи уведомителните балони на програмата + + + + Enable embedded tracker + Включи вградения тракер + + + + Embedded tracker port + Вграден порт на тракер + + + + Check for software updates + Провери за обновяване на програмата + + + + Use system icon theme + Ползвай темата на системната икона + + + + Confirm torrent deletion + Потвърди изтриването на торента + + + + Ignore transfer limits on local network + Игнорирай ограниченията за сваляне на локалната мрежа + + + Include TCP/IP overhead in transfer limits + Включи в ограниченията за сваляне пиковете на TCP/IP + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Автоматичен RSS сваляч + + + + Enable the automated RSS downloader + Включи автоматичния RSS сваляч + + + + Download rules + Правила за сваляне + + + + Rule definition + Дефиниция на правилото + + + + Must contain: + Да съдържа: + + + + Must not contain: + Да не съдържа: + + + + Use regular expressions + Ползвайте стандартни изрази + + + + Import... + Внос... + + + + Export... + Износ... + + + + ... + ... + + + + Assign label: + Прикачи етикет: + + + + Save to a different directory + Съхрани в друга директория + + + + Save to: + Съхрани в: + + + + Apply rule to feeds: + Приложи правилото към канали: + + + + Matching RSS articles + Съответстващи RSS статии + + + + New rule name + Име на ново правила + + + + Please type the name of the new download rule. + Моля напишете името на файла с ново правило за сваляне. + + + + + Rule name conflict + Конфликт в имената на правилата + + + + + A rule with this name already exists, please choose another name. + Правило с това име вече съществува, моля изберете друго име. + + + + Are you sure you want to remove the download rule named %1? + Сигурни ли сте че искате да изтриете правилото с име %1? + + + + Are you sure you want to remove the selected download rules? + Сигурни ли сте че искате да изтриете избраните правила? + + + + Rule deletion confirmation + Потвърждение за изтриване на правилото + + + + Destination directory + Директория цел + + + + Invalid action + Невалидно действие + + + + The list is empty, there is nothing to export. + Списъка е празен, няма какво да се експортира. + + + + Where would you like to save the list? + Къде искате да се съхрани списъка? + + + + Rules list (*.rssrules) + Листа с правила (*.rssrules) + + + + I/O Error + В/И Грешка + + + + Failed to create the destination file + Неуспешно създавене на файла-получател + + + + Please point to the RSS download rules file + Моля посочете файла с правила за сваляне на RSS + + + + Rules list (*.rssrules *.filters) + Листа с правила (*.rssrules *.filters) + + + + Import Error + Грешка при внос + + + + Failed to import the selected rules file + Неуспешно внасяне на избрания файл с правила + + + + Add new rule... + Добави ново правило... + + + + Delete rule + Изтрий правилото + + + + Rename rule... + Преименувай правилото... + + + + Delete selected rules + Изтрий избраните правила + + + + Rule renaming + Преименуване на правилото + + + + Please type the new rule name + Моля напишете името на новото правило + + + + Regex mode: use Perl-like regular expressions + Режим регулярни изрази: ползвайте подобни на Perl регулярни изрази + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Режим Жокер: можете да ползвате<ul><li>? за заместване на всеки единичен знак</li><li>* за заместване от нула до много различни знаци</li><li>Паузите се броят като оператор AND</li></ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Режим Жокер: можете да ползвате<ul><li>? за заместване на всеки отделен знак</li><li>* за заместване на нула или много знаци</li><li>| се ползва като OR оператор</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 използва максималното разрешено от вас отношение. + + + Removing torrent %1... + Премахване торент %1... + + + Pausing torrent %1... + Пауза на торент %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent се прехвърля на порт: TCP/%1 + + + UPnP support [ON] + UPnP поддръжка [ВКЛ] + + + UPnP support [OFF] + UPnP поддръжка [ИЗКЛ] + + + NAT-PMP support [ON] + NAT-PMP поддръжка [ВКЛ] + + + NAT-PMP support [OFF] + NAT-PMP поддръжка [ИЗКЛ] + + + HTTP user agent is %1 + HTTP агент на клиета е %1 + + + Using a disk cache size of %1 MiB + Ползване на дисков кеш размер от %1 ΜιΒ + + + DHT support [ON], port: UDP/%1 + DHT поддръжка [ВКЛ], порт: UDP/%1 + + + DHT support [OFF] + DHT поддръжка [ИЗКЛ] + + + PeX support [ON] + PeX поддръжка [ВКЛ] + + + PeX support [OFF] + PeX поддръжка [ИЗКЛ] + + + Restart is required to toggle PeX support + Рестарта изисква превключване на PeX поддръжката + + + Local Peer Discovery [ON] + Търсене на локални връзки [ВКЛ] + + + Local Peer Discovery support [OFF] + Търсене на локални връзки [ИЗКЛ] + + + Encryption support [ON] + Поддръжка кодиране [ВКЛ] + + + Encryption support [FORCED] + Поддръжка кодиране [ФОРСИРАНА] + + + Encryption support [OFF] + Поддръжка кодиране [ИЗКЛ] + + + The Web UI is listening on port %1 + Интерфейс на Web Потребител прослушване на порт: %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Грешка в Интерфейс на Web Потребител - Невъзможно прехърляне на интерфейса на порт %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' бе премахнат от списъка за прехвърляне и от твърдия диск. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' бе премахнат от списъка за прехвърляне. + + + '%1' is not a valid magnet URI. + '%1' е невалиден magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' вече е в листа за сваляне. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' бе възстановен. (бързо възстановяване) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' добавен в листа за сваляне. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Не мога да декодирам торент-файла: '%1' + + + This file is either corrupted or this isn't a torrent. + Този файла или е разрушен или не е торент. + + + Note: new trackers were added to the existing torrent. + Внимание: нови тракери бяха добавени към съществуващия торент. + + + Note: new URL seeds were added to the existing torrent. + Внимание: нови даващи URL бяха добавени към съществуващия торент. + + + Error: The torrent %1 does not contain any file. + Грешка: Торент %1 не съдържа никакъв файл. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>бе блокиран от вашия IP филтър</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>бе прекъснат поради разрушени части</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Програмирано сваляне на файл %1 вмъкнато в торент %2 + + + Unable to decode %1 torrent file. + Не мога да декодирам %1 торент-файла. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Грешка при следене на порт, съобщение: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Следене на порт успешно, съобщение: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Бърза пауза бе отхвърлена за торент %1, нова проверка... + + + Reason: %1 + Причина: %1 + + + An I/O error occured, '%1' paused. + Намерена грешка В/И, '%1' е в пауза. + + + File sizes mismatch for torrent %1, pausing it. + Размера на файла не съвпада за торент %1, в пауза. + + + Url seed lookup failed for url: %1, message: %2 + Url споделяне провалено за url: %1, съобщение: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Сваляне на '%1', моля изчакайте... + + + + ConsoleDlg + + qBittorrent log viewer + qBittorrent разглеждане на данните + + + General + Общи + + + Blocked IPs + Блокирани IP + + + + CookiesDlg + + + Cookies management + Управление на бисквитки + + + + Key + As in Key/Value pair + Клавиш + + + + Value + As in Key/Value pair + Стойност + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Обичайните клавиши за бисквитки са : '%1', '%2' . +Трябва да вземете тази информация от настройките на вашата търсеща програма. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + Вашата динамична DNS бе успешно обновена. + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Динамична DNS грешка: Услугата временно е недостъпна, повторен опит след 30 минути. + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Динамична DNS грешка: името на хоста не съществува в определената сметка. + + + + Dynamic DNS error: Invalid username/password. + Динамична DNS грешка: Невалидно потребителско име/парола. + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Динамична DNS грешка: qBittorrent е в черния списък на услугата, моля уведомете за грешка в http://bugs.qbittorrent.org. + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Динамична DNS грешка: %1 бе отговорено от услугата, моля уведомете за грешка в http://bugs.qbittorrent.org. + + + + Dynamic DNS error: Your username was blocked due to abuse. + Динамична DNS грешка: Вашето потребителско име е блокирано поради злоупотреба. + + + + Dynamic DNS error: supplied domain name is invalid. + Динамична DNS грешка: Името на домейна е невалидно. + + + + Dynamic DNS error: supplied username is too short. + Динамична DNS грешка: потребителското име е много кратко. + + + + Dynamic DNS error: supplied password is too short. + Динамична DNS грешка: паролата е много кратка. + + + + DownloadThread + + + + I/O Error + Грешка на Вход/Изход + + + + The remote host name was not found (invalid hostname) + Името на приемащия не бе намерено (невалидно име) + + + + The operation was canceled + Действието бе прекъснато + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Приемащия сървър затвори едностранно връзката, преди отговора да бъде получен и изпълнен + + + + The connection to the remote server timed out + Връзката с приемащия сървър затвори поради изтичане на времето + + + + SSL/TLS handshake failed + Прекъсване на скачването SSL/TLS + + + + The remote server refused the connection + Приемащия сървър отхвърли връзката + + + + The connection to the proxy server was refused + Връзката с прокси сървъра бе отхвърлена + + + + The proxy server closed the connection prematurely + Прокси сървъра затвори връзката едностранно + + + + The proxy host name was not found + Името на приемащия прокси не бе намерено + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Връзката с прокси изтече или проксито не отговаря когато запитването бе изпратено + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Проксито изисква удостоверяване за да изпълни запитването но не приема предложените данни + + + + The access to the remote content was denied (401) + Достъпа бе отхвърлен (401) + + + + The operation requested on the remote content is not permitted + Поисканото действие не е разрешено + + + + The remote content was not found at the server (404) + Поисканото не бе намерено на сървъра (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Сървъра изисква удостоверяване за да изпълни запитването но не приема предложените данни + + + + The Network Access API cannot honor the request because the protocol is not known + Приложението за Мрежов Достъп не може да изпълни заявката поради неизвестен протокол + + + + The requested operation is invalid for this protocol + Поисканото действие е невалидно за този протокол + + + + An unknown network-related error was detected + Установена е неизвестна грешка свързана с мрежата + + + + An unknown proxy-related error was detected + Установена е неизвестна грешка свързана с проксито + + + + An unknown error related to the remote content was detected + Установена е неизвестна грешка свързана със съдържанието + + + + A breakdown in protocol was detected + Установено е прекъсване в протокола + + + + Unknown error + Неизвестна грешка + + + + EventManager + + + + Working + Работи + + + + Updating... + Обновяване... + + + + + Not working + Не работи + + + + + Not contacted yet + Още не е свързан + + + + + this session + тази сесия + + + + + /s + /second (i.e. per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + Даващ на %1 + + + + %1 max + e.g. 10 max + %1 макс + + + + + %1/s + e.g. 120 KiB/s + %1/с + + + + ExecutionLog + + Form + Форма + + + + General + Общи + + + + Blocked IPs + Блокирани IP + + + + FeedDownloader + + RSS Feed downloader + RSS Feed сваляч + + + RSS feed: + RSS Feed: + + + Feed name + Feed име + + + Automatically download torrents from this feed + Автоматично сваляне на торентите от този feed + + + Download filters + Филтри за сваляне + + + Filters: + Филтри: + + + Filter settings + Настройки на филтъра + + + Matches: + Съответстващи: + + + Does not match: + Несъответстващи: + + + Destination folder: + Папка получател: + + + ... + ... + + + Filter testing + Тест на филтъра + + + Torrent title: + Име но торента: + + + Result: + Резултат: + + + Test + Тест + + + Import... + Внос... + + + Export... + Износ... + + + Rename filter + Преименувай филтъра + + + Remove filter + Премахни филтъра + + + Add filter + Добави филтър + + + + FeedDownloaderDlg + + New filter + Нов филтър + + + Please choose a name for this filter + Моля изберете име за този филтър + + + Filter name: + Име на филтър: + + + Invalid filter name + Невалидно име на филтър + + + The filter name cannot be left empty. + Името на филтър не може да е празно. + + + This filter name is already in use. + Това име на филтър вече се ползва. + + + Choose save path + Избери път за съхранение + + + Filter testing error + Грешка при тест на филтъра + + + Please specify a test torrent name. + Моля определете име на тест торент. + + + matches + съответства + + + does not match + несъответства + + + Select file to import + Изберете файл за внос + + + Filters Files + Файлове Филтри + + + Import successful + Внос успешен + + + Filters import was successful. + Внос на филтри успешен. + + + Import failure + Грешка при внос + + + Filters could not be imported due to an I/O error. + Филтрите не могат да бъдат внесени поради В/И грешка. + + + Select destination file + Изберете файл-получател + + + Export successful + Износ успешен + + + Filters export was successful. + Износ на филтри успешен. + + + Export failure + Грешка при износ + + + Filters could not be exported due to an I/O error. + Филтрите не могат да бъдат изнесени поради В/И грешка. + + + + FeedList + + Unread + Непрочетен + + + + FeedListWidget + + + RSS feeds + RSS канали + + + + Unread + Непрочетен + + + + GUI + + Open Torrent Files + Отвори Торент Файлове + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Допълнителна информация за сваляне + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Торента %1 съдържа файлове торент, искате ли да ги свалите? + + + Yes + Да + + + No + Не + + + Never + Никога + + + Global Upload Speed Limit + Общ лимит Скорост на качване + + + Global Download Speed Limit + Общ лимит Скорост на сваляне + + + A newer version is available + Има нова версия + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Има нова версия на qBittorrent в Sourceforge. +Искате ли да обновите qBittorrent с версия %1? + + + Impossible to update qBittorrent + Невъзможно обновяването на qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent не можа да се обнови, причина: %1 + + + Exiting qBittorrent + Напускам qBittorrent + + + Always + Винаги + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Сваля: %2/s, Качва: %3/s) + + + Torrent Files + Торент Файлове + + + qBittorrent + qBittorrent + + + Transfers + Трансфери + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + DL Скорост %1 KB/с + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + UL Скорост %1 KB/с + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + '%1' завърши свалянето. + + + I/O Error + i.e: Input/Output Error + В/И Грешка + + + Search + Търси + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent не е вашето приложение по подразбиране за отваряне на файлове торент или Магнитни връзки. +Искате ли да свържете qBittorrent към файлове торент и Магнитни връзки? + + + RSS + RSS + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Download completion + Завършва свалянето + + + Torrent file association + Свързване на торент файла + + + Transfers (%1) + Трансфери (%1) + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Намерена грешка за торент %1. + Причина:%2 + + + Url download error + Грешка при сваляне от Url + + + Couldn't download file at url: %1, reason: %2. + Невъзможно сваляне на файл от url: %1, причина: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Някои файлове се прехвърлят. Сигурни ли сте че искате да напуснете qBittorrent? + + + Options were saved successfully. + Опциите бяха съхранени успешно. + + + + GeoIP + + Australia + Австралия + + + Argentina + Аржентина + + + Austria + Австрия + + + United Arab Emirates + Обединени Арабски Емиратства + + + Brazil + Бразилия + + + Bulgaria + България + + + Belarus + Беларус + + + Belgium + Белгия + + + Bosnia + Босна + + + Canada + Канада + + + Czech Republic + Република Чехия + + + China + Китай + + + Costa Rica + Коста Рика + + + Switzerland + Швейцария + + + Germany + Германия + + + Denmark + Дания + + + Algeria + Алжир + + + Spain + Испания + + + Egypt + Египет + + + Finland + Финландия + + + France + Франция + + + United Kingdom + Великобритания + + + Greece + Гърция + + + Georgia + Грузия + + + Hungary + Унгария + + + Croatia + Хърватска + + + Italy + Италия + + + India + Индия + + + Israel + Израел + + + Ireland + Ирландия + + + Iceland + Исландия + + + Indonesia + Индонезия + + + Japan + Япония + + + South Korea + Южна Корея + + + Luxembourg + Люксембург + + + Malaysia + Малайзия + + + Mexico + Мексико + + + Serbia + Сърбия + + + Morocco + Мароко + + + Netherlands + Холандия + + + Norway + Норвегия + + + New Zealand + Нова Зеландия + + + Portugal + Португалия + + + Poland + Полша + + + Pakistan + Пакистан + + + Philippines + Филипини + + + Russia + Русия + + + Romania + Румъния + + + France (Reunion Island) + Франция (Остров Реюнион) + + + Saudi Arabia + Саудитска Арабия + + + Sweden + Швеция + + + Slovakia + Словакия + + + Singapore + Сингапур + + + Slovenia + Словения + + + Taiwan + Тайван + + + Turkey + Турция + + + Thailand + Тайланд + + + USA + САЩ + + + Ukraine + Украйна + + + South Africa + Южна Африка + + + + HeadlessLoader + + + Information + Информация + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + За контрол на qBittorrent влезте в Web на адрес http://localhost:%1 + + + + The Web UI administrator user name is: %1 + Потребителското име на Администратор на Web UI е: %1 + + + + The Web UI administrator password is still the default one: %1 + Паролата на Администратор на Web UI все още е по подразбиране: %1 + + + + This is a security risk, please consider changing your password from program preferences. + Има риск за сигурността, моля сменете паролата в програмните параметри. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + Вашия IP адрес беше забранен след многократни неуспешни опити за удостоверяване. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Св: %1/с - Пр: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Ка: %1/с - Пр: %2 + + + + HttpServer + + + File + Файл + + + + Edit + Редактирай + + + + Help + Помощ + + + Delete from HD + Изтрий от твърдия диск + + + + Download Torrents from their URL or Magnet link + Сваляне на Торенти от техния URL или Magnet link + + + + Only one link per line + Само един линк на реда + + + + Download local torrent + Сваляне на местен торент + + + + Torrent files were correctly added to download list. + Торент файловете бяха правилно добавени в листа за сваляне. + + + + Point to torrent file + Посочи торент файл + + + + Download + Свали + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Сигурни ли сте че искате да изтриете избраните торенти от списъка за сваляне и от твърдия диск? + + + + Download rate limit must be greater than 0 or disabled. + Ограничението за скорост на сваляне трябва да е по-голямо от 0 или изключено. + + + + Upload rate limit must be greater than 0 or disabled. + Ограничението за скорост на качване трябва да е по-голямо от 0 или изключено. + + + + Maximum number of connections limit must be greater than 0 or disabled. + Ограничението за максимален брой връзки трябва да е по-голямо от 0 или изключено. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Ограничението за максимален брой връзки на торент трябва да е по-голямо от 0 или изключено. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Ограничението за максимален брой слотове на торент трябва да е по-голямо от 0 или изключено. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Не мога да съхраня предпочитанията за програмата, qBittorrent е вероятно недостъпен. + + + + Language + Език + + + + Downloaded + Is the file downloaded or not? + Свалени + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Порта ползван за входни връзки трябва да е по-голям от 1024 и по-малък от 65535. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Порта ползван за Web UI трябва да е по-голям от 1024 и по-малък от 65535. + + + + The Web UI username must be at least 3 characters long. + Потребителското име на Web UI трябва да е поне от три букви. + + + + The Web UI password must be at least 3 characters long. + Паролата на Web UI трябва да е поне от три букви. + + + + Save + Съхрани + + + + qBittorrent client is not reachable + qBittorrent клиента е недостъпен + + + + HTTP Server + Сървър HTTP + + + + The following parameters are supported: + Поддържат се следните параметри: + + + + Torrent path + Торент път + + + + Torrent name + Торент име + + + + LegalNotice + + + Legal Notice + Юридическа бележка + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent е програма за обмяна на файлове. Когато пускате един торент, данните му ще са достъпни за останалите по подразбиране. Всякакво съдържание което споделяте е за ваша отговорност. + +Други съобщения няма да се правят. + + + + Press %1 key to accept and continue... + Натисни %1 клавиш за потвърждение и продължение... + + + + Legal notice + Юридическа бележка + + + + Cancel + Прекъсни + + + + I Agree + Съгласен съм + + + + LineEdit + + + Clear the text + Изтрий текста + + + + MainWindow + + + &Edit + &Редактирай + + + + &Tools + &Инструменти + + + + &File + &Файл + + + + &Help + &Помощ + + + + &View + &Оглед + + + &Add File... + &Добави файл... + + + E&xit + И&зход + + + + &Options... + &Опции... + + + Add &URL... + Добави &URL... + + + + Torrent &creator + Торент &създател + + + + Set upload limit... + Определи лимит качване... + + + + Set download limit... + Определи лимит сваляне... + + + + &About + &Относно + + + + &Pause + &Пауза + + + + &Delete + &Изтрий + + + + P&ause All + П&ауза Всички + + + + &Resume + &Пауза + + + + &Add torrent file... + &Добави торент файл... + + + + + Exit + Изход + + + + R&esume All + П&ауза Всички + + + + Visit &Website + Посетете &уебсайт + + + + Auto-Shutdown on downloads completion + Автоматично гасене на компютъра при завършено сваляне + + + + Add &link to torrent... + Добави &линк към торент... + + + + Report a &bug + Уведомете за &грешка + + + + &Documentation + &Документация + + + + Set global download limit... + Определи общ лимит сваляне... + + + + Set global upload limit... + Определи общ лимит качване... + + + + Exit qBittorrent + Напусни qBittorrent + + + + Suspend system + Приспи системата + + + + Shutdown system + Угаси системата + + + + Disabled + Изключено + + + &Log viewer... + &Разглеждане на данни... + + + Log viewer + Разглеждане на данни + + + Shutdown computer when downloads complete + Угаси компютъра след завършване на свалянето + + + + + Lock qBittorrent + Заключи qBittorrent + + + + Ctrl+L + Ctrl+L + + + Shutdown qBittorrent when downloads complete + Затвори qBittorrent след завършване на свалянето + + + + Import existing torrent... + Внос на съществуващ торент... + + + + Import torrent... + Внос на торент... + + + + Donate money + Дарете пари + + + + If you like qBittorrent, please donate! + Ако ви харесва qBittorrent, моля дарете! + + + + Execution &Log + Изпълнение на &Запис + + + + + Execution Log + Изпълнение на Запис + + + + + Alternative speed limits + Други ограничения за скорост + + + + &RSS reader + &RSS четец + + + + Search &engine + Програма за &търсене + + + + Top &tool bar + Горна лента с &инструменти + + + + Display top tool bar + Покажи горна лента с инструменти + + + + &Speed in title bar + &Скорост в заглавната лента + + + + Show transfer speed in title bar + Покажи скорост в заглавната лента + + + Preview file + Огледай файла + + + Clear log + Изтрий лога + + + + Decrease priority + Намали предимството + + + + Increase priority + Увеличи предимството + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + Определи паролата... + + + + Transfers + Трансфери + + + + Torrent file association + Свързване на торент файла + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent не е вашето приложение по подразбиране за отваряне на файлове торент или Магнитни връзки. +Искате ли да свържете qBittorrent към файлове торент и Магнитни връзки? + + + + + + UI lock password + Парола за потребителски интерфейс + + + + + + Please type the UI lock password: + Моля въведете парола за заключване на потребителския интерфейс: + + + + The password should contain at least 3 characters + Паролата трябва да съдържа поне 3 символа + + + + Password update + Обновяване на парола + + + + The UI lock password has been successfully updated + Паролата за заключване на потребителския интерфейс бе успешно обновена + + + + RSS + RSS + + + + Search + Търси + + + + Transfers (%1) + Трансфери (%1) + + + + Download completion + Завършва свалянето + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + '%1' завърши свалянето. + + + + I/O Error + i.e: Input/Output Error + В/И Грешка + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Намерена грешка за торент %1. + Причина:%2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Допълнително потвърждение за сваляне + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Торента %1 съдържа файлове торент, искате ли да ги свалите? + + + + + Yes + Да + + + + + No + Не + + + + Never + Никога + + + + Url download error + Грешка при сваляне от Url + + + + Couldn't download file at url: %1, reason: %2. + Невъзможно сваляне на файл от url: %1, причина: %2. + + + + Global Upload Speed Limit + Общ лимит Скорост на качване + + + + Global Download Speed Limit + Общ лимит Скорост на сваляне + + + + + Invalid password + Невалидна парола + + + + The password is invalid + Невалидна парола + + + + Exiting qBittorrent + Напускам qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Някои файлове се прехвърлят. Сигурни ли сте че искате да напуснете qBittorrent? + + + + Always + Винаги + + + + Open Torrent Files + Отвори Торент Файлове + + + + Torrent Files + Торент Файлове + + + + Options were saved successfully. + Опциите бяха съхранени успешно. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + DL Скорост %1 KB/с + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + UP Скорост %1 KB/с + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Сваля: %2/s, Качва: %3/s) + + + + A newer version is available + Има нова версия + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Има нова версия на qBittorrent в Sourceforge. +Искате ли да обновите qBittorrent с версия %1? + + + + Impossible to update qBittorrent + Невъзможно обновяването на qBittorrent + + + + qBittorrent failed to update, reason: %1 + qBittorrent не можа да се обнови, причина: %1 + + + + PeerAdditionDlg + + + Invalid IP + Невалиден IP + + + + The IP you provided is invalid. + Този IP е невалиден. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + + + + + PeerListWidget + + + IP + IP + + + + Connection + Връзка + + + + Client + i.e.: Client application + Клиент + + + + Progress + i.e: % downloaded + Изпълнение + + + + Down Speed + i.e: Download speed + Скорост Сваляне + + + + Up Speed + i.e: Upload speed + Скорост на качване + + + + Downloaded + i.e: total data downloaded + Свалени + + + + Uploaded + i.e: total data uploaded + Качени + + + + Add a new peer... + Добави нова двойка... + + + + Copy IP + Копирай IP + + + + Limit download rate... + Ограничи процент сваляне... + + + + Limit upload rate... + Ограничи процент качване... + + + + Ban peer permanently + Спри двойката завинаги + + + + + Peer addition + Добавяне на двойка + + + + The peer was added to this torrent. + Двойката бе добавена към този торент. + + + + The peer could not be added to this torrent. + Двойката не може да бъде добавена към този торент. + + + + Are you sure? -- qBittorrent + Сигурни ли сте? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Сигурни ли сте че искате да спрете завинаги избраните двойки? + + + + &Yes + &Да + + + + &No + &Не + + + + Manually banning peer %1... + Ръчно спиране на двойка %1... + + + + Upload rate limiting + Ограничаване процента на качване + + + + Download rate limiting + Ограничаване процента на сваляне + + + + Preferences + + UI + User Interface + Вид към потребителя + + + + Downloads + Сваляне + + + + Connection + Връзка + + + + Speed + Скорост + + + Bittorrent + Bittorrent + + + Proxy + Прокси + + + + Web UI + Web UI + + + + Advanced + Разширено + + + Language: + Език: + + + + (Requires restart) + (Изисква рестартиране) + + + Visual style: + Визуален стил: + + + Transfer list + Листа за обмен + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Ползвай различно оцветени редове + + + + + Start / Stop Torrent + Пусни / Спри Торент + + + + + No action + Без действие + + + File system + Файлова система + + + + Copy .torrent files to: + Копирай .торент файловете в: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Поддържат се следните параметри: +<ul> +<li>%f: Торент път</li> +<li>%n: Торент име</li> +</ul> + + + Torrent queueing + Серия торенти + + + + Maximum active downloads: + Максимум активни сваляния: + + + + Maximum active uploads: + Максимум активни качвания: + + + + Maximum active torrents: + Максимум активни торенти: + + + + When adding a torrent + При добавяне на торент + + + + + Options + Опции + + + Visual Appearance + Визуален стил + + + + Action on double-click + Действие при двойно щракване + + + + Downloading torrents: + Сваляне на торенти: + + + Start / Stop + Старт/Стоп + + + + + Open destination folder + Отвори папка получател + + + + Completed torrents: + Завършени торенти: + + + + Desktop + Десктоп + + + + Show splash screen on start up + Покажи начален екран при стартиране + + + + Start qBittorrent minimized + Стартирай qBittorrent минимизиран + + + Show qBittorrent icon in notification area + Покажи иконата на qBittorrent в зоната за уведомяване + + + Use monochrome system tray icon (requires restart) + Ползвай едноцветна системна икона (изисква рестарт) + + + + Minimize qBittorrent to notification area + Минимизирай qBittorrent в зоната за уведомяване + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Затвори qBittorrent в зоната за уведомяване + + + + Tray icon style: + Стил на иконата в лентата: + + + + Normal + Нормален + + + + Monochrome (Dark theme) + Едноцветно (Тъмна тема) + + + + Monochrome (Light theme) + Едноцветно (Светла тема) + + + + Ask for program exit confirmation + Искай потвърждение за изход от програмата + + + + User Interface Language: + Език на Потребителския Интерфейс: + + + + Transfer List + Листа за обмен + + + + Show qBittorrent in notification area + Покажи qBittorrent в зоната за уведомяване + + + + Power Management + Управление на Енергията + + + + Inhibit system sleep when torrents are active + Попречи на системата да заспи когато има активни торенти + + + + Display torrent content and some options + Показване съдържание на торента и някои опции + + + + Do not start the download automatically + The torrent will be added to download list in pause state + Не стартирай свалянето автоматично + + + + Hard Disk + Твърд диск + + + + Save files to location: + Съхрани файловете в: + + + + Append the label of the torrent to the save path + Добави етикета на торента в пътя за съхранение + + + + Pre-allocate disk space for all files + Преразпредели дисково пространство за всички файлове + + + + Keep incomplete torrents in: + Дръж незавършени торенти в: + + + Append .!qB extension to incomplete files' names + Добави .!qB разширение към незавършените файлове + + + + Automatically add torrents from: + Автоматично добави торенти от: + + + + Add folder... + Добави папка... + + + + Email notification upon download completion + Уведомяване с е-мейл при завършване на свалянето + + + + Destination email: + Е-мейл получател: + + + + SMTP server: + SMTP сървър: + + + + This server requires a secure connection (SSL) + Този сървър изисква защитена връзка (SSL) + + + + Run an external program on torrent completion + Пусни друга програма при завършване на торента + + + + Otherwise, the proxy server is only used for tracker connections + В противен случай, прокси сървъра се използва само за връзки на тракера + + + + Use proxy for peer connections + Използвайте прокси за взаимно свързване + + + + Global Rate Limits + Ограничения на Общо Ниво + + + + Apply rate limit to uTP connections + Прилагане на пределна скорост за uTP-връзки + + + + Apply rate limit to transport overhead + Прилагане на пределна скорост за превишено пренасяне + + + + Alternative Global Rate Limits + Алтернативни Ограничения на Общо Ниво + + + + Schedule the use of alternative rate limits + График на използване на Алтернативни Ограничения + + + + Use HTTPS instead of HTTP + Ползвай HTTPS вместо HTTP + + + + Import SSL Certificate + Вмъкни SSL Сертификат + + + + Import SSL Key + Вмъкни SSL Ключ + + + + Certificate: + Сертификат: + + + + Key: + Ключ: + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Информация за сертификати</a> + + + + Update my dynamic domain name + Обнови моето динамично име на домейн + + + + Service: + Услуга: + + + + Register + Регистър + + + + Domain name: + Име на домейн: + + + Use %f to pass the torrent path in parameters + Ползвай %f за вмъкване пътя на торента в параметрите + + + + Use UPnP / NAT-PMP port forwarding from my router + Ползвай UPnP / NAT-PMP порт прехвърляне от моя рутер + + + Proxy server + Прокси сървър + + + + Reload the filter + Зареди повторно филтъра + + + + Enable bandwidth management (uTP) + Включи управление на трафика (uTP) + + + + Privacy + Лично + + + + Enable DHT (decentralized network) to find more peers + Включи мрежа DHT (децентрализирана) за намиране на повече връзки + + + + Use a different port for DHT and BitTorrent + Ползвай различен порт за DHT и Битторент + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Обмени двойки със съвместими Битторент клиенти (µTorrent, Vuze, ...) + + + + Enable Peer Exchange (PeX) to find more peers + Включи Peer Exchange (PeX) за намиране на повече връзки + + + + Enable Local Peer Discovery to find more peers + Включи Откриване на локална връзка за намиране на повече връзки + + + + Encryption mode: + Режим на кодиране: + + + + Prefer encryption + Предпочитано кодиране + + + + Require encryption + Изисква кодиране + + + + Disable encryption + Изключи кодиране + + + Share ratio limiting + Ограничаване съотношението на споделяне + + + + Seed torrents until their ratio reaches + Давай торентите докато съотношението се увеличи + + + + then + тогава + + + + Pause them + Сложи ги в пауза + + + + Remove them + Премахни ги + + + + Enable Web User Interface (Remote control) + Включи Интерфейс на Web Потребител (Отдалечен контрол) + + + + Use UPnP / NAT-PMP to forward the port from my router + Ползвай UPnP / NAT-PMP за препращане порта на моя рутер + + + + Bypass authentication for localhost + Заобиколи удостоверяването за локален хост + + + Listening port + Порт за прослушване + + + + Port used for incoming connections: + Порт ползван за входящи връзки: + + + + Random + Приблизително + + + Enable UPnP port mapping + Включено UPnP порт следене + + + Enable NAT-PMP port mapping + Включено NAT-PMP порт следене + + + Connections limit + Ограничение на връзката + + + + Global maximum number of connections: + Общ максимален брой на връзки: + + + + Maximum number of connections per torrent: + Максимален брой връзки на торент: + + + + Maximum number of upload slots per torrent: + Максимален брой слотове за качване на торент: + + + + + Upload: + Качване: + + + + + Download: + Сваляне: + + + + + + + KiB/s + KiB/с + + + User Interface + Потребителски Интерфейс + + + + BitTorrent + BitTorrent + + + Global speed limits + Общи ограничения за скоост + + + Alternative global speed limits + Разширени ограничения за скорост + + + + to + time1 to time2 + към + + + + Every day + Всеки ден + + + + Week days + Работни дни + + + + Week ends + Почивни дни + + + Bittorrent features + Възможности на Битторент + + + Enable DHT network (decentralized) + Включена мрежа DHT (децентрализирана) + + + Use a different port for DHT and Bittorrent + Ползвай различен порт за DHT и Битторент + + + + DHT port: + DHT порт: + + + Enable Peer Exchange / PeX (requires restart) + Включен Peer Exchange / PeX (изисква рестартиране) + + + Enable Local Peer Discovery + Включено Откриване на локална връзка + + + Enabled + Включено + + + Forced + Форсирано + + + Disabled + Изключено + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP комуникации (тракери, Уеб даващи, търсачки) + + + + Host: + Хост: + + + Peer Communications + Комуникации Връзки + + + + SOCKS4 + SOCKS4 + + + + Type: + Вид: + + + + + Behavior + Режим на работа + + + + Language + Език + + + + Append .!qB extension to incomplete files + Добави .!qB разширение към незавършени файлове + + + + Remove folder + Премахни папка + + + + Listening Port + Порт за прослушване + + + + Connections Limits + Ограничения на Връзката + + + + Proxy Server + Прокси сървър + + + + IP Filtering + IP филтриране + + + Schedule the use of alternative speed limits + График на ползването на други ограничения на скоростта + + + + from + from (time1 to time2) + от + + + + When: + Когато: + + + + Look for peers on your local network + Търси връзки на твоята локална мрежа + + + Protocol encryption: + Протокол на кодиране: + + + + (None) + (без) + + + + HTTP + HTTP + + + + + Port: + Порт: + + + + + + Authentication + Удостоверяване + + + + + + + Username: + Име на потребителя: + + + + + + + Password: + Парола: + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + Филтър път (.dat, .p2p, .p2b): + + + + Torrent Queueing + Серия Торенти + + + + Share Ratio Limiting + Ограничаване Съотношението на Споделяне + + + HTTP Server + Сървър HTTP + + + + PreviewSelect + + + Name + Име + + + + Size + Размер + + + + Progress + Изпълнение + + + + + + Preview impossible + Оглед невъзможен + + + + + + Sorry, we can't preview this file + Съжалявам, не можем да огледаме този файл + + + + ProgramUpdater + + Could not create the file %1 + Не мога да създам файла %1 + + + Failed to download the update at %1 + %1 is an URL + Неуспешно сваляне на обновяването от %1 + + + + PropListDelegate + + + Not downloaded + Не свалени + + + + + Normal + Normal (priority) + Нормален + + + + + High + High (priority) + Висок + + + + Mixed + Mixed (priorities + Смесени + + + + + Maximum + Maximum (priority) + Максимален + + + + PropTabBar + + + General + Общи + + + + Trackers + Тракери + + + + Peers + Двойки + + + + HTTP Sources + HTTP Източници + + + + Content + Съдържание + + + URL Seeds + URL даващи + + + Files + Файлове + + + + PropertiesWidget + + + Save path: + Съхрани път: + + + + Torrent hash: + Торент раздробяване: + + + + Comment: + Коментар: + + + + Share ratio: + Процент на споделяне: + + + + + Downloaded: + Свалени: + + + + Availability: + Наличност: + + + + Transfer + Трансфер + + + + Uploaded: + Качени: + + + + Wasted: + Изгубени: + + + + Time active: + Time (duration) the torrent is active (not paused) + Време активен: + + + + Pieces size: + Размери на частите: + + + + Torrent content: + Съдържание на Торента: + + + + Select All + Избери всички + + + + Select None + Не избирай + + + + + Do not download + Не сваляй + + + + UP limit: + Лимит качване: + + + + DL limit: + Лимит сваляне: + + + Time elapsed: + Оставащо време: + + + + Connections: + Връзки: + + + + Reannounce in: + Предложи отново в: + + + + Information + Информация + + + + Created on: + Създаден на: + + + General + Общи + + + Trackers + Тракери + + + Peers + Двойки + + + URL seeds + URL даващи + + + Files + Файлове + + + + Priority + Предимство + + + + Normal + Нормален + + + + Maximum + Максимален + + + + High + Висок + + + + + this session + тази сесия + + + + + /s + /second (i.e. per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + Даващ на %1 + + + + %1 max + e.g. 10 max + %1 макс + + + + + I/O Error + Грешка на Вход/Изход + + + + This file does not exist yet. + Този файл още не съществува. + + + + This folder does not exist yet. + Тази папка още не съществува. + + + + Rename... + Преименувай... + + + + Rename the file + Преименувай файла + + + + New name: + Ново име: + + + + + The file could not be renamed + Файла не може да се преименува + + + + This file name contains forbidden characters, please choose a different one. + Името на файла съдържа забранени символи, моля изберете различно име. + + + + + This name is already in use in this folder. Please use a different name. + Това име вече съществува в тази папка. Моля, ползвайте различно име. + + + + The folder could not be renamed + Папката не може да се преименува + + + + New url seed + New HTTP source + Нов url на даващ + + + + New url seed: + Нов url на даващ: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Този url на даващ е вече в списъка. + + + + + Choose save path + Избери път за съхранение + + + Save path creation error + Грешка при създаване на път за съхранение + + + Could not create the save path + Не мога да създам път за съхранение + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 използва максималното разрешено от вас отношение. + + + + Removing torrent %1... + Премахване торент %1... + + + + Pausing torrent %1... + Пауза на торент %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent се прехвърля на порт: TCP/%1 + + + UPnP support [ON] + UPnP поддръжка [ВКЛ] + + + UPnP support [OFF] + UPnP поддръжка [ИЗКЛ] + + + NAT-PMP support [ON] + NAT-PMP поддръжка [ВКЛ] + + + NAT-PMP support [OFF] + NAT-PMP поддръжка [ИЗКЛ] + + + + HTTP user agent is %1 + HTTP агент на клиента е %1 + + + Using a disk cache size of %1 MiB + Ползване на дисков кеш размер от %1 ΜιΒ + + + + DHT support [ON], port: UDP/%1 + DHT поддръжка [ВКЛ], порт: UDP/%1 + + + + + DHT support [OFF] + DHT поддръжка [ИЗКЛ] + + + + PeX support [ON] + PeX поддръжка [ВКЛ] + + + + PeX support [OFF] + PeX поддръжка [ИЗКЛ] + + + + Restart is required to toggle PeX support + Рестарта изисква превключване на PeX поддръжката + + + Local Peer Discovery [ON] + Търсене на локални връзки [ВКЛ] + + + + Local Peer Discovery support [OFF] + Търсене на локални връзки [ИЗКЛ] + + + + Encryption support [ON] + Поддръжка кодиране [ВКЛ] + + + + Encryption support [FORCED] + Поддръжка кодиране [ФОРСИРАНА] + + + + Encryption support [OFF] + Поддръжка кодиране [ИЗКЛ] + + + + Embedded Tracker [ON] + Вграден Тракер [ВКЛ] + + + + Failed to start the embedded tracker! + Неуспешен старт на вграден тракер! + + + + Embedded Tracker [OFF] + Вграден Тракер [ИЗКЛ] + + + + The Web UI is listening on port %1 + Интерфейс на Web Потребител прослушва порт %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Грешка в Интерфейс на Web Потребител - Невъзможно прехърляне на интерфейса на порт %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' бе премахнат от списъка за прехвърляне и от твърдия диск. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' бе премахнат от списъка за прехвърляне. + + + + '%1' is not a valid magnet URI. + '%1' е невалиден magnet URI. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' вече е в листа за сваляне. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' бе възстановен. (бързо възстановяване) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' добавен в листа за сваляне. + + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP поддръжка [ВКЛ] + + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP поддръжка [ИЗКЛ] + + + + Reporting IP address %1 to trackers... + Съобщаване на IP адрес %1 на тракери... + + + + Local Peer Discovery support [ON] + Търсене на локални връзки [ВКЛ] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Не мога да декодирам торент-файла: '%1' + + + + This file is either corrupted or this isn't a torrent. + Този файла или е разрушен или не е торент. + + + + Error: The torrent %1 does not contain any file. + Грешка: Торент %1 не съдържа никакъв файл. + + + + Note: new trackers were added to the existing torrent. + Внимание: нови тракери бяха добавени към съществуващия торент. + + + + Note: new URL seeds were added to the existing torrent. + Внимание: нови даващи URL бяха добавени към съществуващия торент. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>бе блокиран от вашия IP филтър</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>бе прекъснат поради разрушени части</i> + + + + The network interface defined is invalid: %1 + Определения мрежов интерфейс е невалиден: %1 + + + + Trying any other network interface available instead. + Опитвам всеки друг мрежов интерфейс достъпен в замяна. + + + + Listening on IP address %1 on network interface %2... + Прослушвам IP адрес %1 на мрежов интерфейс %2... + + + + Failed to listen on network interface %1 + Неуспешно прослушване на мрежов интерфейс %1 + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Програмирано сваляне на файл %1 вмъкнато в торент %2 + + + + + Unable to decode %1 torrent file. + Не мога да декодирам %1 торент-файла. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Компютъра ще влезе сега в режим сън освен ако прекратите операцията в следващите 15 секунди... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Компютъра ще се загаси сега освен ако прекратите операцията в следващите 15 секунди... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent ще се затвори освен ако прекратите операцията в следващите 15 секунди... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Успешно вмъкване на дадения IP филтър: %1 правило бе добавено. + + + + Error: Failed to parse the provided IP filter. + Грешка: Неуспешно вмъкване на дадения IP филтър. + + + + Torrent name: %1 + Име но торента: %1 + + + + Torrent size: %1 + Торент размер: %1 + + + + Save path: %1 + Съхрани път: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Торента бе свален за %1. + + + + Thank you for using qBittorrent. + Благодарим Ви за ползването на qBittorrent. + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 завърши свалянето + + + + An I/O error occured, '%1' paused. + Намерена В/И грешка, '%1' е в пауза. + + + + + Reason: %1 + Причина: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Грешка при следене на порт, съобщение: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Следене на порт успешно, съобщение: %1 + + + + File sizes mismatch for torrent %1, pausing it. + Размера на файла не съвпада за торент %1, в пауза. + + + + Fast resume data was rejected for torrent %1, checking again... + Бърза пауза бе отхвърлена за торент %1, нова проверка... + + + + Url seed lookup failed for url: %1, message: %2 + Url споделяне провалено за url: %1, съобщение: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Сваляне на '%1', моля изчакайте... + + + + RSS + + + Search + Търси + + + + New subscription + Нов абонамент + + + + + + Mark items read + Четене на маркираните + + + + Update all + Обнови всички + + + + RSS Downloader... + RSS сваляч... + + + + Settings... + Настройки... + + + RSS feed downloader... + RSS Feed сваляч... + + + + New folder... + Нова папка... + + + + Manage cookies... + Управление на бисквитки... + + + Feed URL + URL на канал + + + + Rename... + Преименувай... + + + + + Update + Обновяване + + + RSS feeds + RSS канали + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Торенти:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + + + Article title + Заглавие на статията + + + + New subscription... + Нов абонамент... + + + + + Update all feeds + Обнови всички канали + + + + + Delete + Изтрий + + + + Rename + Преименувай + + + + Download torrent + Торент сваляне + + + + Open news URL + Отваря URL за новини + + + + Copy feed URL + Копира URL на канал + + + + Refresh RSS streams + Обнови потоците RSS + + + + RSSImp + + + Please type a rss stream url + Моля въведете url на поток rss + + + + Stream URL: + Поток URL: + + + + + Are you sure? -- qBittorrent + Сигурни ли сте? -- qBittorrent + + + + + &Yes + &Да + + + + + &No + &Не + + + + Please choose a folder name + Моля изберете име на папка + + + + Folder name: + Име на папка: + + + + New folder + Нова папка + + + + Overwrite attempt + Опит за презаписване + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Не можете да презапишете %1. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Този rss канал е вече в списъка. + + + + Are you sure you want to delete these elements from the list? + Сигурни ли сте че искате да изтриете тези елементи от списъка? + + + + Are you sure you want to delete this element from the list? + Сигурни ли сте че искате да изтриете този елемент от списъка? + + + + Please choose a new name for this RSS feed + Моля изберете ново име за този RSS канал + + + + New feed name: + Име на нов канал: + + + + Name already in use + Името вече се ползва + + + + This name is already used by another item, please choose another one. + Това име се ползва от друг елемент, моля изберете друго. + + + + Date: + Дата: + + + + Author: + Автор: + + + + Unread + Непрочетен + + + + RssArticle + + No description available + Няма налично описание + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Автоматично сваляне на %1 торент от %2 RSS канал... + + + + RssItem + + No description available + Няма налично описание + + + + RssSettings + + RSS Reader Settings + RSS четец настройки + + + RSS feeds refresh interval: + Интервал на обновяване на RSS feeds: + + + minutes + минути + + + Maximum number of articles per feed: + Максимум статии на feed: + + + + RssSettingsDlg + + + RSS Reader Settings + RSS четец настройки + + + + RSS feeds refresh interval: + Интервал на обновяване на RSS feeds: + + + + minutes + минути + + + + Maximum number of articles per feed: + Максимум статии на feed: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Автоматично сваляне на %1 торент от %2 RSS канал... + + + + ScanFoldersModel + + + Watched Folder + Наблюдавана Папка + + + + Download here + Свали тук + + + + SearchCategories + + + All categories + Всички категории + + + + Movies + Филми + + + + TV shows + TV шоу + + + + Music + Музика + + + + Games + Игри + + + + Anime + Анимация + + + + Software + Софтуер + + + + Pictures + Снимки + + + + Books + Книги + + + + SearchEngine + + + Empty search pattern + Празен образец за търсене + + + + Please type a search pattern first + Моля първо въведете образец за търсене + + + + + Results + Резултати + + + + Searching... + Търсене... + + + + Cut + Отрежи + + + + Copy + Копирай + + + + Paste + Залепи + + + + Clear field + Изчисти полето + + + + Clear completion history + Изчисти листа на завършените + + + + Confirmation + Потвърждение + + + + Are you sure you want to clear the history? + Сигурни ли сте че искате да изтриете историята? + + + + + + Search + Търси + + + + Missing Python Interpreter + Липсва Интерпретатор за Python + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x се изисква за ползване от търсачката но той изглежда не е инсталиран. +Искате ли да го инсталирате сега? + + + + Search Engine + Търсачка + + + + + Search has finished + Търсенето завърши + + + + An error occured during search... + Намерена грешка при търсенето... + + + + + Search aborted + Търсенето е прекъснато + + + + Download error + Грешка при сваляне + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Инсталирането на Python не може да бъде свален, причина: %1. +Моля инсталирайте го ръчно. + + + + Search returned no results + Търсене завършено без резултат + + + + Results + i.e: Search results + Резултати + + + + + Unknown + Неизвестен + + + + SearchTab + + + Name + i.e: file name + Име + + + + Size + i.e: file size + Размер + + + + Seeders + i.e: Number of full sources + Даващи + + + + Leechers + i.e: Number of partial sources + Вземащи + + + + Search engine + Програма за търсене + + + + ShutdownConfirmDlg + + + Shutdown confirmation + Потвърждение за загасяване + + + + SpeedLimitDialog + + + KiB/s + KiB/с + + + + StatusBar + + + + Connection status: + Състояние на връзката: + + + + + No direct connections. This may indicate network configuration problems. + Няма директни връзки. Това може да е от проблеми в мрежовата настройка. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + Св: %1 б/с - Пр: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + Ка: %1 б/с - Пр: %2 + + + + + DHT: %1 nodes + DHT: %1 възли + + + + qBittorrent needs to be restarted + qBittorrent се нуждае от рестарт + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent току-що бе обновен и има нужда от рестарт за да работят промените. + + + + + Connection Status: + Състояние на връзката: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Извън мрежа. Това обикновено означава, че qBittorrent не е успял да прослуша избрания порт за входни връзки. + + + + Online + Свързан + + + + + %1/s + Per second + %1/с + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Св: %1/с - Пр: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Ка: %1/с - Пр: %2 + + + + Click to switch to alternative speed limits + Натисни за смяна към други ограничения за скорост + + + + Click to switch to regular speed limits + Натисни за смяна към стандартни ограничения за скорост + + + Click to disable alternative speed limits + Щракни за изключване на други ограничения за скорост + + + Click to enable alternative speed limits + Щракни за включване на други ограничения за скорост + + + + Global Download Speed Limit + Общ лимит Скорост на сваляне + + + + Global Upload Speed Limit + Общ лимит Скорост на качване + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Изберете папка за добавяне към торента + + + + Select a file to add to the torrent + Изберете файл за добавяне към торента + + + Please type an announce URL + Моля въведете даващ URL + + + Announce URL: + Tracker URL + Предлагащ URL: + + + Please type a web seed url + Моля въведете web даващ url + + + Web seed URL: + Web даващ URL: + + + + No input path set + Не е избран входящ път + + + + Please type an input path first + Моля първо напишете входящ път + + + + Select destination torrent file + Избери торент файл получател + + + + Torrent Files + Торент Файлове + + + + + + Torrent creation + Създаване на Торент + + + + Torrent creation was unsuccessful, reason: %1 + Създаване на торент неуспешно, причина: %1 + + + + Created torrent file is invalid. It won't be added to download list. + Създаденият торент файл е невалиден. Няма да бъде добавен в листа за сваляне. + + + + Torrent was created successfully: + Торента бе създаден успешно: + + + + TorrentFilesModel + + + Name + Име + + + + Size + Размер + + + + Progress + Изпълнение + + + + Priority + Предимство + + + + TorrentImportDlg + + + Torrent Import + Внос на торент + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Този помощник ще ви помогне до споделите с qBittorrent вече свален торент. + + + + Torrent file to import: + Торент файл за внос: + + + + + ... + ... + + + + Content location: + Място на съдържанието: + + + + Skip the data checking stage and start seeding immediately + Прескочи проверката на данните и започни да даваш веднага + + + + Import + Внос + + + + Torrent file to import + Торент файл за внос + + + + Torrent files (*.torrent) + Торент файлове (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 файлове + + + + Please provide the location of %1 + %1 is a file name + Моля посочете мястото на %1 + + + + Please point to the location of the torrent: %1 + Моля посочете мястото на торент: %1 + + + + Invalid torrent file + Невалиден торент файл + + + + This is not a valid torrent file. + Това не е валиден торент файл. + + + + TorrentModel + + + Name + i.e: torrent name + Име + + + + Size + i.e: torrent size + Размер + + + + Done + % Done + Готово + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Състояние + + + + Seeds + i.e. full sources (often untranslated) + Споделящи + + + + Peers + i.e. partial sources (often untranslated) + Двойки + + + + Down Speed + i.e: Download speed + Скорост Сваляне + + + + Up Speed + i.e: Upload speed + Скорост на качване + + + + Ratio + Share ratio + Съотношение + + + + ETA + i.e: Estimated Time of Arrival / Time left + Оставащо време + + + + Label + Етикет + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Добавен на + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Завършен на + + + + Tracker + Тракер + + + + Down Limit + i.e: Download limit + Лимит сваляне + + + + Up Limit + i.e: Upload limit + Лимит качване + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Количество свалено + + + + Amount left + Amount of data left to download (e.g. in MB) + Оставащо количество + + + + Time Active + Time (duration) the torrent is active (not paused) + Време активен + + + + TrackerList + + + URL + URL + + + + Status + Състояние + + + + Peers + Двойки + + + + Message + Съобщение + + + + [DHT] + [DHT] + + + + [PeX] + [PeX] + + + + [LSD] + [LSD] + + + + + + + + Working + Работи + + + + + + Disabled + Изключено + + + + This torrent is private + Този торент е личен + + + + Updating... + Обновяване... + + + + + Not working + Не работи + + + + + Not contacted yet + Още не е свързан + + + + Add a new tracker... + Добави нов тракер... + + + + Remove tracker + Премахни тракер + + + + Force reannounce + Ускори предлагането + + + + TrackersAdditionDlg + + + Trackers addition dialog + Допълнителен диалог на тракери + + + + List of trackers to add (one per line): + Списък тракери за добавяне (по един на ред): + + + + µTorrent compatible list URL: + URL на съвместима с µTorrent листа: + + + + I/O Error + Грешка на Вход/Изход + + + + Error while trying to open the downloaded file. + Грешка при опит за отваряне на сваления файл. + + + + No change + Без промяна + + + + No additional trackers were found. + Допълнителни тракери не бяха намерени. + + + + Download error + Грешка при сваляне + + + + The trackers list could not be downloaded, reason: %1 + Листата на тракера не може да бъде свалена, причина: %1 + + + + TransferListDelegate + + + Downloading + Сваляне + + + + Paused + Пауза + + + + Queued + i.e. torrent is queued + Прикачен + + + + Seeding + Torrent is complete and in upload-only mode + Споделяне + + + + Stalled + Torrent is waiting for download to begin + Отложен + + + + Checking + Torrent local data is being checked + Проверка + + + + /s + /second (.i.e per second) + + + + + KiB/s + KiB/second (.i.e per second) + KiB/с + + + + Seeded for %1 + e.g. Seeded for 3m10s + Даващ за %1 + + + + TransferListFiltersWidget + + + + All + Всички + + + + + Downloading + Сваляне + + + + + Completed + Завършено + + + + + Paused + Пауза + + + + + Active + Активен + + + + + Inactive + Неактивен + + + + + All labels + Всички етикети + + + + + Unlabeled + Без етикет + + + + Remove label + Премахни етикета + + + + Add label... + Добави етикет... + + + + Resume torrents + Продължи торентите + + + + Pause torrents + Пауза на торентите + + + + Delete torrents + Изтрий торентите + + + + New Label + Нов етикет + + + + Label: + Етикет: + + + + Invalid label name + Невалидно име на етикет + + + + Please don't use any special characters in the label name. + Моля, не ползвайте специални символи в името на етикета. + + + + TransferListWidget + + Down Speed + i.e: Download speed + Скорост Сваляне + + + Up Speed + i.e: Upload speed + Скорост на качване + + + ETA + i.e: Estimated Time of Arrival / Time left + ЕТА + + + + Column visibility + Видимост на колона + + + Name + i.e: torrent name + Име + + + Size + i.e: torrent size + Размер + + + Done + % Done + Готово + + + Status + Torrent status (e.g. downloading, seeding, paused) + Състояние + + + Seeds + i.e. full sources (often untranslated) + Споделящи + + + Peers + i.e. partial sources (often untranslated) + Двойки + + + Ratio + Share ratio + Съотношение + + + + Label + Етикет + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Добавен на + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Завършен на + + + Down Limit + i.e: Download limit + Лимит сваляне + + + Up Limit + i.e: Upload limit + Лимит качване + + + + Choose save path + Избери път за съхранение + + + Save path creation error + Грешка при създаване на път за съхранение + + + Could not create the save path + Не мога да създам път за съхранение + + + + Torrent Download Speed Limiting + Ограничаване Скорост на сваляне + + + + Torrent Upload Speed Limiting + Ограничаване Скорост на качване + + + + New Label + Нов етикет + + + + Label: + Етикет: + + + + Invalid label name + Невалидно име на етикет + + + + Please don't use any special characters in the label name. + Моля, не ползвайте специални символи в името на етикета. + + + + Rename + Преименувай + + + + New name: + Ново име: + + + + Resume + Resume/start the torrent + Продължи + + + + Pause + Pause the torrent + Пауза + + + + Delete + Delete the torrent + Изтрий + + + + Preview file... + Огледай файла... + + + + Limit share ratio... + Ограничение на съотношението за споделяне... + + + + Limit upload rate... + Ограничи процент качване... + + + + Limit download rate... + Ограничи процент сваляне... + + + + Priority + Предимство + + + + Open destination folder + Отвори папка получател + + + + Move up + i.e. move up in the queue + Нагоре в листата + + + + Move down + i.e. Move down in the queue + Надолу в листата + + + + Move to top + i.e. Move to top of the queue + На върха на листата + + + + Move to bottom + i.e. Move to bottom of the queue + На дъното на листата + + + + Set location... + Определи място... + + + + Force recheck + Включени проверки за промени + + + + Copy magnet link + Копирай връзка magnet + + + + Super seeding mode + Режим на супер-даване + + + + Rename... + Преименувай... + + + + Download in sequential order + Сваляне по азбучен ред + + + + Download first and last piece first + Свали първо и последно парче първо + + + + New... + New label... + Ново... + + + + Reset + Reset label + Нулирай + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Ограничение на съотношението Сваляне/Качване на торента + + + + Use global ratio limit + Ползвай стандартното ограничение + + + + + + buttonGroup + група Бутони + + + + Set no ratio limit + Не определяй ограничение + + + + Set ratio limit to + Определи ограничение на + + + + UsageDisplay + + + Usage: + Ползване: + + + + displays program version + показва версията на програмата + + + + disable splash screen + изключи начален екран + + + + displays this help message + показва помощно съобщение + + + + changes the webui port (current: %1) + променя порта Web UI (текущ: %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [файлове или URL]: сваля торентите избрани от потребителя (по избор) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Бих искал да благодаря на следните доброволци, превели qBittorent: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Моля, свържете се с мен ако искате да преведете qBittorrent на вашия език. + + + + addPeerDialog + + + Peer addition + Добавяне на двойка + + + + IP + IP + + + + Port + Порт + + + + addTorrentDialog + + + Torrent addition dialog + Торента добавя диалог + + + + Save path: + Съхрани път: + + + + ... + ... + + + + Torrent size: + Торент размер: + + + + + Unknown + Неизвестен + + + + Free disk space: + Празно пространство на диска: + + + + Label: + Етикет: + + + + Torrent content: + Съдържание на Торента: + + + + Select All + Избери всички + + + + Select None + Не избирай + + + + Download in sequential order (slower but good for previewing) + Сваляне поред (по-бавно но удобно за преглед) + + + + Skip file checking and start seeding immediately + Прескочи проверката на файла и започни да даваш веднага + + + + + Do not download + Не сваляй + + + + Add to download list in paused state + Добави в листа за сваляне в състояние на пауза + + + + Add + Добави + + + + Cancel + Прекъсни + + + + Normal + Нормален + + + + High + Висок + + + + Maximum + Максимален + + + + authentication + + + + Tracker authentication + Удостоверяване на тракера + + + + Tracker: + Тракер: + + + + Login + Вход + + + + Username: + Име на потребителя: + + + + Password: + Парола: + + + + Log in + Влизане + + + + Cancel + Прекъсни + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Потвърждение за изтриване -- qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Сигурни ли сте че искате да изтриете избраните торенти от списъка за сваляне? + + + + Remember choice + Запомни избора + + + + Also delete the files on the hard disk + Също изтрий файловете от твърдия диск + + + + createTorrentDialog + + + Cancel + Прекъсни + + + + Torrent Creation Tool + Инструмент за Създаване на Торент + + + + Torrent file creation + Създаване на Торент файл + + + Announce urls (trackers): + Предлагащи url (тракери): + + + Comment (optional): + Коментар (опция): + + + Web seeds urls (optional): + URL на даващи по Web (опция): + + + + File or folder to add to the torrent: + Файл или папка за добавяне към торента: + + + + Add file + Добави файл + + + + Add folder + Добави папка + + + + Tracker URLs: + Тракери URL: + + + + Web seeds urls: + Web даващи URL: + + + + Comment: + Коментар: + + + + Piece size: + Размер на част: + + + + 32 KiB + 32 КБ + + + + 64 KiB + 64 КБ + + + + 128 KiB + 128 КБ + + + + 256 KiB + 256 КБ + + + + 512 KiB + 512 КБ + + + + 1 MiB + 1 МБ + + + + 2 MiB + 2 МБ + + + + 4 MiB + 4 МБ + + + + Auto + Автоматично + + + + Private (won't be distributed on DHT network if enabled) + Лично (няма да бъде разпространено по мрежа DHT ако е включено) + + + + Start seeding after creation + Започни даване след образуване + + + + Create and save... + Създай и съхрани... + + + + Progress: + Изпълнение: + + + + createtorrent + + Select destination torrent file + Избери торент файл получател + + + Torrent Files + Торент Файлове + + + No input path set + Не е избран входящ път + + + Please type an input path first + Моля първо напишете входящ път + + + Torrent creation + Създаване на Торент + + + Torrent was created successfully: + Торента бе създаден успешно: + + + Select a folder to add to the torrent + Изберете папка за добавяне към торента + + + Please type an announce URL + Моля въведете даващ URL + + + Torrent creation was unsuccessful, reason: %1 + Създаване на торент неуспешно, причина: %1 + + + Announce URL: + Tracker URL + Предлагащ URL: + + + Please type a web seed url + Моля въведете web даващ url + + + Web seed URL: + Web даващ URL: + + + Select a file to add to the torrent + Изберете файл за добавяне към торента + + + Created torrent file is invalid. It won't be added to download list. + Създаденият торент файл е невалиден. Няма да бъде добавен в листа за сваляне. + + + + downloadFromURL + + Download Torrents from URLs + Сваляне на Торенти от URL + + + Only one URL per line + Само един URL на ред + + + + Add torrent links + Добави връзки торент + + + + Both HTTP and Magnet links are supported + И HTTP и Magnet връзки се поддържат + + + + Download + Свали + + + + Cancel + Прекъсни + + + + Download from urls + Свали от url-ове + + + + No URL entered + Невъведен URL + + + + Please type at least one URL. + Моля въведете поне един URL. + + + + downloadThread + + I/O Error + В/И Грешка + + + The remote host name was not found (invalid hostname) + Името на приемащия не бе намерено (невалидно име) + + + The operation was canceled + Действието бе прекъснато + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Приемащия сървър затвори едностранно връзката, преди отговора да бъде получен и изпълнен + + + The connection to the remote server timed out + Връзката с приемащия сървър затвори поради изтичане на времето + + + SSL/TLS handshake failed + Прекъсване на скачването SSL/TLS + + + The remote server refused the connection + Приемащия сървър отхвърли връзката + + + The connection to the proxy server was refused + Връзката с прокси сървъра бе отхвърлена + + + The proxy server closed the connection prematurely + Прокси сървъра затвори връзката едностранно + + + The proxy host name was not found + Името на приемащия прокси не бе намерено + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Връзката с прокси изтече или проксито не отговаря когато запитването бе изпратено + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Проксито изисква удостоверяване за да изпълни запитването но не приема предложените данни + + + The access to the remote content was denied (401) + Достъпа бе отхвърлен (401) + + + The operation requested on the remote content is not permitted + Поисканото действие не е разрешено + + + The remote content was not found at the server (404) + Поисканото не бе намерено на сървъра (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Сървъра изисква удостоверяване за да изпълни запитването но не приема предложените данни + + + The Network Access API cannot honor the request because the protocol is not known + Приложението за Мрежов Достъп не може да изпълни заявката поради неизвестен протокол + + + The requested operation is invalid for this protocol + Поисканото действие е невалидно за този протокол + + + An unknown network-related error was detected + Установена е неизвестна грешка свързана с мрежата + + + An unknown proxy-related error was detected + Установена е неизвестна грешка свързана с проксито + + + An unknown error related to the remote content was detected + Установена е неизвестна грешка свързана със съдържанието + + + A breakdown in protocol was detected + Установено е прекъсване в протокола + + + Unknown error + Неизвестна грешка + + + + engineSelect + + + Search plugins + Търси добавки + + + + Installed search engines: + Инсталирани търсачки: + + + + Name + Име + + + + Url + Url + + + + + Enabled + Включено + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Можете да вземете нови добавки за търсачката тук: <a href="http:plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Инсталирай нов + + + + Check for updates + Провери за обновяване + + + + Close + Затвори + + + Enable + Включи + + + Disable + Изключи + + + + Uninstall + Деинсталирай + + + + engineSelectDlg + + + Uninstall warning + Предупреждение за деинсталиране + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Някои добавки не могат да бъдат деинсталирани защото са част от qBittorrent. + Само добавените от вас могат да бъдат деинсталирани. +Обаче добавките бяха изключени. + + + + Uninstall success + Успешно деинсталиране + + + + Select search plugins + Избери добавки за търсене + + + + qBittorrent search plugins + qBittorrent добавки за търсене + + + + + + + + Search plugin install + Инсталиране на добавка за търсене + + + + + + Yes + Да + + + + + + + No + Не + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + По-нова версия на %1 добавката за търсене вече е инсталирана. + + + + + + + Search plugin update + Добавката за търсене е обновена + + + + + Sorry, update server is temporarily unavailable. + Съжалявам, сървъра за обновяване е временно недостъпен. + + + + All your plugins are already up to date. + Всички ваши добавки са вече обновени. + + + + All selected plugins were uninstalled successfully + Всички избрани добавки бяха успешно деинсталирани + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 добавка на търсачката не бе обновена, запазване на досегашната версия. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 добавка на търсачката не бе инсталирана. + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 добавка на търсачката беше успешно обновена. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1 добавка на търсачката беше успешно обновена. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Съжалявам, инсталацията на %1 добавката за търсене бе неуспешна. + + + + New search engine plugin URL + Нов URL за добавки на търсачката + + + + URL: + URL: + + + + misc + + + B + bytes + Б + + + + KiB + kibibytes (1024 bytes) + КБ + + + + MiB + mebibytes (1024 kibibytes) + МБ + + + + GiB + gibibytes (1024 mibibytes) + ГБ + + + + TiB + tebibytes (1024 gibibytes) + ТБ + + + + %1h %2m + e.g: 3hours 5minutes + %1ч%2мин + + + + %1d %2h + e.g: 2days 10hours + %1д%2ч + + + + + + + + + Unknown + Неизвестно + + + + Unknown + Unknown (size) + Неизвестен + + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent ще угаси компютъра, защото всички сваляния са завършени. + + + + < 1m + < 1 minute + < 1мин + + + + %1m + e.g: 10minutes + %1мин + + + + options_imp + + + + + + Choose a save directory + Изберете директория за съхранение + + + + Add directory to scan + Добави директория за сканиране + + + + Folder is already being watched. + Папката вече се наблюдава. + + + + Folder does not exist. + Папката не съществува. + + + + Folder is not readable. + Папката не се чете. + + + + Failure + Грешка + + + + Failed to add Scan Folder '%1': %2 + Грешка при добавяне Папка за Сканиране '%1': %2 + + + + + Choose export directory + Изберете Директория за Експорт + + + + + Choose an ip filter file + Избери файл за ip филтър + + + + + Filters + Филтри + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + Грешка при вмъкване + + + + Failed to parse the provided IP filter + Неуспешно вмъкване на дадения IP филтър + + + + Successfully refreshed + Успешно обновен + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + Succesfully refreshed + Успешно обновен + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Успешно вмъкване на дадения IP филтър: %1 правило бе добавено. + + + + pluginSourceDlg + + + Plugin source + Източник на добавката + + + + Search plugin source: + Търсене на източници на добавки: + + + + Local file + Локален файл + + + + Web link + Web линк + + + + preview + + + Preview selection + Оглед на избраното + + + + File preview + Оглед на файла + + + + The following files support previewing, <br>please select one of them: + Следните файлове поддържат оглед, <br>моля изберете един от тях: + + + + Preview + Оглед + + + + Cancel + Прекъсни + + + + previewSelect + + Preview impossible + Оглед невъзможен + + + Sorry, we can't preview this file + Съжалявам, не можем да огледаме този файл + + + Name + Име + + + Size + Размер + + + Progress + Изпълнение + + + + search_engine + + + + Search + Търси + + + + Status: + Състояние: + + + + Stopped + Спрян + + + + Download + Свали + + + + Go to description page + Отиди в страницата с описанието + + + + Search engines... + Търсачки... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + Не мога да декодирам торент-файла: + + + + + + Choose save path + Избери път за съхранение + + + + Unable to decode magnet link: + Не мога да декодирам връзката Magnet: + + + + Magnet Link + Връзка Magnet + + + + Rename... + Преименувай... + + + + Rename the file + Преименувай файла + + + + New name: + Ново име: + + + + + The file could not be renamed + Файла не може да се преименува + + + + This file name contains forbidden characters, please choose a different one. + Името на файла съдържа забранени символи, моля изберете различно име. + + + + + This name is already in use in this folder. Please use a different name. + Това име вече съществува в тази папка. Моля, ползвайте различно име. + + + + The folder could not be renamed + Папката не може да се преименува + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 остават след сваляне на торента) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (още %1 са необходими за свалянето) + + + + Empty save path + Празен път за съхранение + + + + Please enter a save path + Моля въведете път за съхранение + + + + Save path creation error + Грешка при създаване на път за съхранение + + + + Could not create the save path + Не мога да създам път за съхранение + + + + Invalid label name + Невалидно име на етикет + + + + Please don't use any special characters in the label name. + Моля, не ползвайте специални символи в името на етикета. + + + + Seeding mode error + Грешка в режим даване + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Избрахте прескачане на проверката. Обаче местните файлове изглежда не съществуват в папката получател. Моля изключете тази функция или обновете пътя за съхранение. + + + + Invalid file selection + Невалиден избор на файл + + + + You must select at least one file in the torrent + Трябва да изберете поне един файл в торента + + + + Priority + Предимство + + + diff --git a/src/lang/qbittorrent_ca.qm b/src/lang/qbittorrent_ca.qm new file mode 100644 index 0000000000000000000000000000000000000000..3a0014d447925ff86c9e39f3a68e8121a710fac5 GIT binary patch literal 107176 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 literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_ca.ts b/src/lang/qbittorrent_ca.ts new file mode 100644 index 000000000..8fe760978 --- /dev/null +++ b/src/lang/qbittorrent_ca.ts @@ -0,0 +1,6536 @@ + + + + + AboutDlg + + + About qBittorrent + Sobre qBittorrent + + + + About + Sobre + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Un client Bittorrent programat en C++, segons Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Pàgina Oficial:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + Author + Autor + + + + Name: + Nom: + + + + Country: + Pais: + + + + E-mail: + E-Mail: + + + + Christophe Dumez + Christophe Dumez + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + + France + França + + + + Translation + Traducció + + + + License + Llicència + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + + chris@qbittorrent.org + + + + + Thanks to + Gràcies a + + + + AdvancedSettings + + Property + Propietat + + + Value + Valor + + + + Disk write cache size + Mida cache del Disc + + + + MiB + MiB + + + + Outgoing ports (Min) [0: Disabled] + Ports de sortida (Min) [0: Desactivat] + + + + Outgoing ports (Max) [0: Disabled] + Ports de sortida (Max) [0: Desactivat] + + + + Recheck torrents on completion + Verificar Torrents completats + + + + Transfer list refresh interval + Interval de refresc de la llista de transferència + + + + ms + milliseconds + ms + + + + Setting + + + + + Value + Value set for this setting + Valor + + + + Resolve peer countries (GeoIP) + Mostrar Parells per Països (GeoIP) + + + + Resolve peer host names + Mostrar Parells per nom de Host + + + + Maximum number of half-open connections [0: Disabled] + Capacitat màxima de connexions obertes [0: Desactivat] + + + + Strict super seeding + Sembra super estricta + + + + Network Interface (requires restart) + Selecció de Xarxa (cal reiniciar) + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + Qualsevol Xarxa + + + + IP Address to report to trackers (requires restart) + Adreça IP per a informe d'incidències als trackers (cal reiniciar) + + + + Display program on-screen notifications + Visualització en pantalla de les notificacions + + + Display program notification balloons + Mostrar globus de notificació + + + + Enable embedded tracker + Habilitar integració de tracker + + + + Embedded tracker port + Port d'integració de tracker + + + + Check for software updates + Comprovar si hi ha actualitzacions + + + + Use system icon theme + Utilitza icones del tema actual + + + + Confirm torrent deletion + Confirmeu la supressió del torrent + + + Display program notification baloons + Mostra globus de notificació + + + + Ignore transfer limits on local network + Ignora límits de transferència de la xarxa local + + + Include TCP/IP overhead in transfer limits + Incloure TCP / IP en els límits generals de transferència + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Automatitzar Descàrrega de canals RSS + + + + Enable the automated RSS downloader + Activar Descàrrega automatitzada de canals RSS + + + + Download rules + Regles de Descàrregues + + + + Rule definition + Definició de regles + + + + Must contain: + Ha de contenir: + + + + Must not contain: + No ha de contenir: + + + + Use regular expressions + + + + + Import... + Importar... + + + + Export... + Exportar... + + + Save torrent to: + Guardar torrent a: + + + + ... + ... + + + + Assign label: + Etiquetar com: + + + + Save to a different directory + Guardar en un directori diferent + + + + Save to: + Guardar en: + + + + Apply rule to feeds: + Aplicar regles als canals: + + + + Matching RSS articles + Coincidència de canals RSS + + + + New rule name + Nova regla + + + + Please type the name of the new download rule. + Si us plau, escriviu el nom de la nova regla a descàrrega. + + + + + Rule name conflict + Conflicte amb el nom de la regla + + + + + A rule with this name already exists, please choose another name. + Ja existena una regla amb aquest nom, si us plau, trieu un altre nom. + + + + Are you sure you want to remove the download rule named %1? + Segur que voleu eliminar la regla de transferència anomenada %1? + + + + Are you sure you want to remove the selected download rules? + Segur que voleu eliminar les normes de descàrrega seleccionada? + + + + Rule deletion confirmation + Confirmar eliminar regla + + + + Destination directory + Directori de destinació + + + + Invalid action + Acció no vàlida + + + + The list is empty, there is nothing to export. + La llista està buida, no hi ha res per exportar. + + + + Where would you like to save the list? + On li agradaria guardar la llista? + + + + Rules list (*.rssrules) + Llista de regles (*.rssrules) + + + + I/O Error + Error d'Entrada/Sortida + + + + Failed to create the destination file + No s'ha pogut crear l'arxiu de destí + + + + Please point to the RSS download rules file + Si us plau, seleccioneu les normes de descàrrega de canals RSS + + + + Rules list (*.rssrules *.filters) + Llista de regles (*.rssrules *.filters) + + + + Import Error + Error al importar + + + + Failed to import the selected rules file + No s'ha pogut importar el fitxer de la regla seleccionada + + + + Add new rule... + Afegeix nova regla... + + + + Delete rule + Eliminar regla + + + + Rename rule... + Canviar el nom de la regla... + + + + Delete selected rules + Eliminar regles seleccionades + + + + Rule renaming + Regla renombrada + + + + Please type the new rule name + Si us plau, escriviu el nom de la nova regla + + + + Regex mode: use Perl-like regular expressions + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 va assolir el ratio màxim establert. + + + Removing torrent %1... + Extraient torrent %1... + + + Pausing torrent %1... + Torrent Pausat %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent està usant el port: TCP/%1 + + + UPnP support [ON] + Suport per a UPnP [Encesa] + + + UPnP support [OFF] + Suport per a UPnP [Apagat] + + + NAT-PMP support [ON] + Suport per a NAT-PMP [Encesa] + + + NAT-PMP support [OFF] + Suport per a NAT-PMP[Apagat] + + + HTTP user agent is %1 + HTTP d'usuari es %1 + + + Using a disk cache size of %1 MiB + Mida cache del Disc %1 MiB + + + DHT support [ON], port: UDP/%1 + Suport per a DHT [Encesa], port: UPD/%1 + + + DHT support [OFF] + Suport per a DHT [Apagat] + + + PeX support [ON] + Suport per a PeX [Encesa] + + + PeX support [OFF] + Suport PeX [Apagat] + + + Restart is required to toggle PeX support + És necessari reiniciar per activar suport PeX + + + Local Peer Discovery [ON] + Estat local de Parells [Encesa] + + + Local Peer Discovery support [OFF] + Suport per a estat local de Parells [Apagat] + + + Encryption support [ON] + Suport per a encriptat [Encesa] + + + Encryption support [FORCED] + Suport per a encriptat [forçat] + + + Encryption support [OFF] + Suport per a encriptat [Apagat] + + + The Web UI is listening on port %1 + Port d'escolta d'Interfície Usuari Web %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Error interfície d'Usuari Web - No es pot enllaçar al port %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' Va ser eliminat de la llista de transferència i del disc. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' Va ser eliminat de la llista de transferència. + + + '%1' is not a valid magnet URI. + '%1' no és una URI vàlida. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' ja està en la llista de descàrregues. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' reiniciat. (reinici ràpid) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' agregat a la llista de descàrregues. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Impossible descodificar l'arxiu torrent: '%1' + + + This file is either corrupted or this isn't a torrent. + Aquest arxiu pot ser corrupte, o no ser un torrent. + + + Note: new trackers were added to the existing torrent. + Nota: nous Trackers s'han afegit al torrent existent. + + + Note: new URL seeds were added to the existing torrent. + Nota: noves llavors URL s'han afegit al Torrent existent. + + + Error: The torrent %1 does not contain any file. + Error: aquest torrent %1 no conté cap fitxer. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>va ser bloquejat a causa del filtre IP</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>Va ser bloquejat a causa de fragments corruptes</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Descàrrega recursiva d'arxiu %1 incrustada en Torrent %2 + + + Unable to decode %1 torrent file. + No es pot descodificar %1 arxiu torrent. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Va fallar el mapatge del port, missatge: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Mapatge del port reeixit, missatge: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Es van negar les dades per a reinici ràpid del torrent: %1, verificant de nou... + + + Reason: %1 + Raó: %1 + + + Torrent name: %1 + Nom del torrent: %1 + + + Torrent size: %1 + Mida del torrent: %1 + + + Save path: %1 + Guardar ruta: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + El torrernt es va descarregar a %1. + + + Thank you for using qBittorrent. + Gràcies per utilitzar qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 s'ha finalitzat les descàrregues + + + An I/O error occured, '%1' paused. + Error E/S ocorregut, '%1' pausat. + + + File sizes mismatch for torrent %1, pausing it. + La mida del fitxer no coincideix amb el torrent %1, pausat. + + + Url seed lookup failed for url: %1, message: %2 + Va fallar la recerca de llavor per l'Url: %1, missatge: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Descarregant '%1', si us plau esperi... + + + + ConsoleDlg + + qBittorrent log viewer + qBittorrent visor de registres + + + General + General + + + Blocked IPs + IPs bloquejades + + + + CookiesDlg + + + Cookies management + Administració de Cookies + + + + Key + As in Key/Value pair + Clau + + + + Value + As in Key/Value pair + Valor + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Les Claus per a les Cookies són : '%1', '%2' +Podeu obtenir aquesta informació de les preferències del seu navegador web. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + + + + + Dynamic DNS error: Invalid username/password. + + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: Your username was blocked due to abuse. + + + + + Dynamic DNS error: supplied domain name is invalid. + + + + + Dynamic DNS error: supplied username is too short. + + + + + Dynamic DNS error: supplied password is too short. + + + + + DownloadThread + + + + I/O Error + Error d'Entrada/Sortida + + + + The remote host name was not found (invalid hostname) + El nom host no s'ha trobat (nom host no vàlid) + + + + The operation was canceled + L'operació va ser cancel-lada + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + El servidor remot va tancar la connexió abans de temps, abans que fos rebut i processat + + + + The connection to the remote server timed out + Connexió amb el servidor remot fallida, Temps d'espera esgotat + + + + SSL/TLS handshake failed + SSL/TLS handshake fallida + + + + The remote server refused the connection + El servidor remot va rebutjar la connexió + + + + The connection to the proxy server was refused + La connexió amb el servidor proxy va ser rebutjada + + + + The proxy server closed the connection prematurely + Connexió tancada abans de temps pel servidor proxy + + + + The proxy host name was not found + El nom host del proxy no s'ha trobat + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + La connexió amb el servidor proxy s'ha esgotat, o el proxy no va respondre a temps a la sol-licitud enviada + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + El proxy requereix autenticació a fi d'atendre la sol-licitud, però no va acceptar les credencials que va oferir + + + + The access to the remote content was denied (401) + L'accés al contingut remot ha estat rebutjat (401) + + + + The operation requested on the remote content is not permitted + L'operació sol-licitada en el contingut remot no està permesa + + + + The remote content was not found at the server (404) + El contingut remot no es troba al servidor (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + El servidor remot requereix autenticació per servir el contingut, però les credencials proporcionades no són correctes + + + + The Network Access API cannot honor the request because the protocol is not known + L'accés a la xarxa de l'API no pot complir amb la sol licitud pel fet que el protocol és desconegut + + + + The requested operation is invalid for this protocol + L'operació sol-licitada no és vàlida per a aquest protocol + + + + An unknown network-related error was detected + Error de Xarxa desconegut + + + + An unknown proxy-related error was detected + Error de Proxy desconegut + + + + An unknown error related to the remote content was detected + Error desconegut al servidor remot + + + + A breakdown in protocol was detected + Error de protocol + + + + Unknown error + Error desconegut + + + + EventManager + + + + Working + treballant + + + + Updating... + Actualizant... + + + + + Not working + Sense servei + + + + + Not contacted yet + No connectat encara + + + + + this session + aquesta sessió + + + + + /s + /second (i.e. per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + Complet des de %1 + + + + %1 max + e.g. 10 max + + + + + + %1/s + e.g. 120 KiB/s + + + + + ExecutionLog + + Form + Formulari + + + + General + General + + + + Blocked IPs + IPs bloquejades + + + + FeedDownloader + + RSS Feed downloader + Descarregant canal RSS + + + RSS feed: + Canal RSS: + + + Feed name + Nom del Canal + + + Automatically download torrents from this feed + Descarregar automàticament torrents des d'aquest Canal + + + Download filters + Descarregar filtres + + + Filters: + Filtres: + + + Filter settings + Ajusts de filtres + + + Matches: + Concordances: + + + Does not match: + No coincideixen amb: + + + Destination folder: + Carpeta de destinació: + + + ... + ... + + + Filter testing + Verifican filtres + + + Torrent title: + Titol Torrent: + + + Result: + Resultad: + + + Test + Prova + + + Import... + Importar... + + + Export... + Exportar... + + + Rename filter + Rebatejar filtre + + + Remove filter + Esborrar filtre + + + Add filter + Agregar filtre + + + + FeedDownloaderDlg + + New filter + Nou filtre + + + Please choose a name for this filter + Si us plau, elegeixi un nom per a aquest filtre + + + Filter name: + Nom del filtre: + + + Invalid filter name + Nom no valgut per al filtre + + + The filter name cannot be left empty. + El nom del filtre no pot quedar buid. + + + This filter name is already in use. + Aquest nom de filtre ja s'està usant. + + + Choose save path + Seleccioni la ruta on guardar-lo + + + Filter testing error + Error en la verificació del filtre + + + Please specify a test torrent name. + Si us plau, especifiqui el nom del torrent a verificar. + + + matches + Conté + + + does not match + no conté + + + Select file to import + Seleccioni l'arxiu a importar + + + Filters Files + Filtre d'arxius + + + Import successful + Importació satisfactòria + + + Filters import was successful. + Filtres importats satisfactòriament. + + + Import failure + Importació fallida + + + Filters could not be imported due to an I/O error. + Els filtres no poden ser importats a causa d'un Error d'Entrada/Sortida. + + + Select destination file + Seleccioni la ruta de l'arxiu + + + Export successful + Exportació satisfactòria + + + Filters export was successful. + Filtres exportats satisfactòriament. + + + Export failure + Exportació fallida + + + Filters could not be exported due to an I/O error. + Els filtres no poden ser exportats a causa d'un Error d'Entrada/Sortida. + + + + FeedList + + Unread + No llegit + + + + FeedListWidget + + + RSS feeds + Canals RSS + + + + Unread + No llegits + + + + GUI + + Open Torrent Files + Obrir arxius Torrent + + + Torrent Files + Arxius Torrent + + + qBittorrent + qBittorrent + + + Transfers + Transferint + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Vel. de Baixada: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Vel. de Pujada: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 ha acabat de descarregar-se. + + + I/O Error + i.e: Input/Output Error + Error d'Entrada/Sortida + + + Search + Buscar + + + Torrent file association + Associació d'arxius Torrent + + + Set the password... + Definint la contrasenya... + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent no és l'aplicació per defecte per obrir arxius Torrent o enllaços Magnet. +¿Vol que qBittorrent sigui el programa per defecte per gestionar aquests arxius? + + + Password update + Actualització de contrasenya + + + The UI lock password has been successfully updated + La contrasenya de bloqueig de qBittorrent s'ha actualitzat correctament + + + RSS + RSS + + + Transfers (%1) + Transferències (%1) + + + Download completion + Descàrrega completada + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Es va produir un Error d'Entrada/Sortida, torrent %1. +Raó: %2 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Confirmació descàrregues recursives + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Aquest torrent %1 conté arxius torrent, vol seguir endavant amb la seva descàrrega? + + + Yes + + + + No + No + + + Never + Mai + + + Global Upload Speed Limit + Límit global de Pujada + + + Global Download Speed Limit + Límit global de Baixada + + + A newer version is available + Hi ha una nova versió disponible + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Hi ha disponible una versió més recent de qBittorrent a Sourceforge. +¿Desitja actualitzar qBittorrent a la versión %1? + + + Impossible to update qBittorrent + Ha estat impossible actualitzar qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent no va poder actualitzar-se, per la següent raó: %1 + + + UI lock password + Contrasenya de bloqueig + + + Please type the UI lock password: + Si us plau, escrigui la contrasenya de bloqueig: + + + Invalid password + Contrasenya no vàlida + + + The password is invalid + La contrasenya no és vàlida + + + Exiting qBittorrent + Tancant qBittorrent + + + Always + Sempre + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Baixada: %2/s, Pujada: %3/s) + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Error de descàrrega d'Url + + + Couldn't download file at url: %1, reason: %2. + No es va poder descarregar l'arxiu en la url: %1, raó: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl + F + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Alguns arxius encara estan transferint. +Està segur que vol sortir? + + + Options were saved successfully. + Opcions guardades correctament. + + + + GeoIP + + France + França + + + Saudi Arabia + Aràbia Saudi + + + + HeadlessLoader + + + Information + Informació + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Control qBittorrent, accés a interfície d'usuari Web a http://localhost:%1 + + + + The Web UI administrator user name is: %1 + Nom d'usuari de l'administrador Web: %1 + + + + The Web UI administrator password is still the default one: %1 + La contrasenya de l'administrador d'interfície d'usuari web continua sent per defecto:%1 + + + + This is a security risk, please consider changing your password from program preferences. + Això és un risc de seguretat, si us plau consideri canviar la seva contrasenya de les preferències del programa. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + Després de molts intents de connexió, sembla ser que la teva direcció IP ha estat restringida. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Baixada: %1/s - Total: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Pujada: %1/s - Total: %2 + + + + HttpServer + + + File + Arxiu + + + + Edit + Editar + + + + Help + Ajuda + + + Delete from HD + Esborrar del disc + + + + Download Torrents from their URL or Magnet link + Descarregar Torrents des d'URL o Enllaç (Link) + + + + Only one link per line + Només un enllaç (Link) per línia + + + + Download local torrent + Descarregar torrent local + + + + Torrent files were correctly added to download list. + Els arxius torrents es van afegir correctament a la llista de descàrrega. + + + + Point to torrent file + Indiqui un arxiu torrent + + + + Download + Descarregar + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Està segur que vols esborrar els torrents seleccionats de la llista de transferència i del disc? + + + + Download rate limit must be greater than 0 or disabled. + El límit de la taxa de descàrrega ha de ser major que 0 o estar inhabilitat. + + + + Upload rate limit must be greater than 0 or disabled. + El límit de la taxa de pujada ha de ser major que 0 o estar inhabilitat. + + + + Maximum number of connections limit must be greater than 0 or disabled. + El nombre màxim del limiti de connexions ha de ser major que 0 o estar inhabilitat. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + El nombre màxim del limiti de connexions per torrent ha de ser major que 0 o estar inhabilitat. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + El nombre màxim de pujades de slots per torrent ha de ser major que 0 o estar inhabilitat. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + No es pot guardar les preferències del programa, qbittorrent probablement no és accessible. + + + + Language + Idioma + + + + Downloaded + Is the file downloaded or not? + Baixat + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + El port utilitzat per a connexions entrants ha de ser major de 1024 i menor de 65535. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + El port utilitzat per a la Interfície d'Usuari Web ha de ser major de 1024 i menor de 65535. + + + + The Web UI username must be at least 3 characters long. + El nom d'Interfície d'Usuari web ha de ser d'almenys 3 caràcters. + + + + The Web UI password must be at least 3 characters long. + La contrasenya d'Interfície d'Usuari Web ha de ser d'almenys 3 caràcters. + + + + Save + Guardar + + + + qBittorrent client is not reachable + El client qBittorrent no és accessible + + + + HTTP Server + Servidor HTTP + + + + The following parameters are supported: + + + + + Torrent path + + + + + Torrent name + + + + + LegalNotice + + + Legal Notice + Avís Legal + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent és un programa per compartir arxius. Quan s'executa un torrent, les seves dades es posaran a disposició dels altres per mitjà de pujada. I, sens dubte, qualsevol contingut que vostè comparteix és sota la seva responsabilitat. + +Probablement això és una cosa que ja sabia, així que no li dirà cap altra vegada. + + + + Press %1 key to accept and continue... + Premi qualsevol tecla per acceptar i continuar... + + + + Legal notice + Avís Legal + + + + Cancel + Cancel-lar + + + + I Agree + Estic d'acord + + + + LineEdit + + + Clear the text + Esborrar el text + + + + MainWindow + + + &Edit + &Editar + + + + &Tools + E&ines + + + + &File + &Axiu + + + + &Help + A&yuda + + + + &View + &Veure + + + &Add File... + &Afegir arxius... + + + E&xit + &Sortir + + + + &Options... + &Opcions... + + + Add &URL... + Afegir &URL... + + + + Torrent &creator + Crear &Torrent + + + + Set upload limit... + Límit de Pujada... + + + + Set download limit... + Límit de Baixada... + + + + &About + &Sobre + + + + &Pause + &Pausar + + + + &Delete + &Esborrar + + + + P&ause All + Pa&usar Totes + + + + &Resume + &Reprendre + + + + &Add torrent file... + &Afegeix arxiu torrent... + + + + + Exit + Sortir + + + + R&esume All + R&eprende Tot + + + + Visit &Website + Visitar el meu lloc &Web + + + + Auto-Shutdown on downloads completion + Tancar quan es completin les descàrregues + + + + Add &link to torrent... + Afegeix &enllaç torrent... + + + + Report a &bug + Comunicar un &bug + + + + &Documentation + &Documentasió + + + + Set global download limit... + Límit global de Baixada... + + + + Set global upload limit... + Límit global de Pujada... + + + + Exit qBittorrent + Tancant qBittorrent + + + + Suspend system + Suspendre sistema + + + + Shutdown system + Tancar sistema + + + + Disabled + Deshabilitat + + + &Log viewer... + Visor &d'registres... + + + Log viewer + Visor d'registres + + + Shutdown computer when downloads complete + Tancar l'equip en finalitzar les descàrregues + + + + + Lock qBittorrent + Bloca qBittorrent + + + + Ctrl+L + Ctrl+L + + + Shutdown qBittorrent when downloads complete + Apagar qBittorrent quan la descàrrega sigui completa + + + + Import existing torrent... + Importa torrent existent... + + + + Import torrent... + Importar torrent... + + + + Donate money + Donar + + + + If you like qBittorrent, please donate! + Si li agrada qBittorrent, si us plau feu una donació! + + + + Execution &Log + Execució &Log + + + + + Execution Log + Execució Log + + + + + Alternative speed limits + Límits de velocitat alternativa + + + + &RSS reader + &Lector RSS + + + + Search &engine + &Motor de cerca + + + + Top &tool bar + Barra d'eines &superior + + + + Display top tool bar + Mostrar barra d'eines superior + + + + &Speed in title bar + &Velocitat a la barra + + + + Show transfer speed in title bar + Mostra velocitat a la barra de títol + + + Preview file + Previsualitzar arxiu + + + Clear log + Netejar registre + + + + Decrease priority + Disminuir prioritat + + + + Increase priority + Incrementar prioritat + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + Definint la contrasenya... + + + + Transfers + Transferint + + + + Torrent file association + Associació d'arxius Torrent + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent no és l'aplicació per defecte per obrir arxius Torrent o enllaços Magnet. +¿Vol que qBittorrent sigui el programa per defecte per gestionar aquests arxius? + + + + + + UI lock password + Contrasenya de bloqueig + + + + + + Please type the UI lock password: + Si us plau, escrigui la contrasenya de bloqueig: + + + + The password should contain at least 3 characters + Com a mínim la contrasenya ha de tenir 3 caràcters + + + + Password update + Actualització de contrasenya + + + + The UI lock password has been successfully updated + La contrasenya de bloqueig de qBittorrent s'ha actualitzat correctament + + + + RSS + RSS + + + + Search + Cerca + + + + Transfers (%1) + Transferències (%1) + + + + Download completion + Descàrrega completada + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 ha acabat de descarregar-se. + + + + I/O Error + i.e: Input/Output Error + Error d'Entrada/Sortida + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Es va produir un Error d'Entrada/Sortida, torrent %1. +Raó: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Confirmació descàrregues recursives + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Aquest torrent %1 conté arxius torrent, vol seguir endavant amb la seva descàrrega? + + + + + Yes + + + + + + No + No + + + + Never + Mai + + + + Url download error + Error de descàrrega d'Url + + + + Couldn't download file at url: %1, reason: %2. + No es va poder descarregar l'arxiu en la url: %1, raó: %2. + + + + Global Upload Speed Limit + Velocitat límit global de pujada + + + + Global Download Speed Limit + Velocitat límit global de descàrrega + + + + + Invalid password + Contrasenya no vàlida + + + + The password is invalid + La contrasenya no és vàlida + + + + Exiting qBittorrent + Tancant qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Alguns arxius encara estan transferint. +Està segur que vol sortir? + + + + Always + Sempre + + + + Open Torrent Files + Obrir arxius Torrent + + + + Torrent Files + Arxius Torrent + + + + Options were saved successfully. + Opcions guardades correctament. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Vel. de Baixada: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Vel. de Pujada: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Baixada: %2/s, Pujada: %3/s) + + + + A newer version is available + Hi ha una nova versió disponible + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Hi ha disponible una versió més recent de qBittorrent a Sourceforge. +¿Desitja actualitzar qBittorrent a la versión %1? + + + + Impossible to update qBittorrent + Ha estat impossible actualitzar qBittorrent + + + + qBittorrent failed to update, reason: %1 + qBittorrent no va poder actualitzar-se, per la següent raó: %1 + + + + PeerAdditionDlg + + + Invalid IP + IP invàlida + + + + The IP you provided is invalid. + L'IP facilitada no és vàlida. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + + + + + Connection + Connexió + + + + Client + i.e.: Client application + Client + + + + Progress + i.e: % downloaded + Progrés + + + + Down Speed + i.e: Download speed + Velocitat de Baixada + + + + Up Speed + i.e: Upload speed + Velocitat de Pujada + + + + Downloaded + i.e: total data downloaded + Descarregat + + + + Uploaded + i.e: total data uploaded + Pujat + + + + Add a new peer... + Afegir nou Parell... + + + + Copy IP + Copiar IP + + + + Limit download rate... + Taxa límit de Baixada... + + + + Limit upload rate... + Taxa límit de Pujada... + + + + Ban peer permanently + Prohibició permanent de Parells + + + + + Peer addition + Incorporar Parell + + + + The peer was added to this torrent. + Els parells es van agregar al torrent. + + + + The peer could not be added to this torrent. + Els parells no siguin poguts ser agregats al torrent. + + + + Are you sure? -- qBittorrent + Està segur? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Segur que desitja prohibir-li la compartició permanent de Parells? + + + + &Yes + &Sí + + + + &No + &No + + + + Manually banning peer %1... + Prohibir manualment els Parells %1... + + + + Upload rate limiting + Límit taxa de pujada + + + + Download rate limiting + Límit taxa de baixada + + + + Preferences + + UI + User Interface + IU + + + + Downloads + Baixats + + + + Connection + Connexió + + + + Speed + Velocitat + + + + Web UI + IU Web + + + + Advanced + Avançat + + + Language: + Idioma: + + + + (Requires restart) + (Es necessita reiniciar qBittorrent) + + + Visual style: + Estil Visual: + + + Transfer list + Llista de Transferència + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Usar colors alterns en la llista de Transferència + + + + + Start / Stop Torrent + Iniciar / Aturar Torrent + + + + + No action + Sense acció + + + File system + Opcions sobre arxius del Sistema + + + + Copy .torrent files to: + Copiar arxius. Torrent a: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Els següents paràmetres són compatibles: +<ul> +<li>%f: Torrent ruta</li> +<li>%n: Torrent nom</li> +</ul> + + + Torrent queueing + Gestió de Cues + + + + Maximum active downloads: + Màxim d'arxius Baixant: + + + + Maximum active uploads: + Màxim d'arxius Pujant: + + + + Maximum active torrents: + Màxim d'arxius Torrents: + + + + When adding a torrent + En afegir un torrent + + + + + Options + Opcions + + + User Interface + Interfície d'usuari + + + Visual Appearance + Aparença Visual + + + + Action on double-click + Acció a realitzar amb un Doble-click + + + + Downloading torrents: + Torrents Descarregant: + + + + + Open destination folder + Obrir carpeta destí + + + + Completed torrents: + Torrents Completats: + + + + Desktop + Escriptori + + + + Show splash screen on start up + Mostra pantalla de benvinguda en iniciar + + + + Start qBittorrent minimized + Iniciar qBittorrent minimitzat + + + Show qBittorrent icon in notification area + Mostra icona de qBittorrent en l'àrea de notificació + + + Use monochrome system tray icon (requires restart) + Utilitza icona monocromàtic a la safata del sistema (cal reinicar) + + + + Minimize qBittorrent to notification area + Minimitzar qBittorrent en l'àrea de notificació + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + En tancar qBittorrent deixeu actiu en l'àrea de notificació + + + + Tray icon style: + + + + + Normal + Normal + + + + Monochrome (Dark theme) + + + + + Monochrome (Light theme) + + + + + Ask for program exit confirmation + Demanar confirmació per sortir del programa + + + + User Interface Language: + + + + + Transfer List + + + + + Show qBittorrent in notification area + + + + + Power Management + Administració d'energia + + + + Inhibit system sleep when torrents are active + Desactivar la suspensió de l'equip quan encara queden torrents actius + + + + Display torrent content and some options + Mostrar el contingut del Torrent i opcions + + + + Do not start the download automatically + The torrent will be added to download list in pause state + No iniciar la descàrrega de forma automàtica + + + + Hard Disk + + + + + Save files to location: + Guardar els arxius en la seva ubicació: + + + + Append the label of the torrent to the save path + Afegir l'etiqueta del torrent a la ruta on es guarda + + + + Pre-allocate disk space for all files + Pre-assignar espai al disc per a tots els arxius + + + + Keep incomplete torrents in: + Mantenir Torrents incomplets a: + + + Append .!qB extension to incomplete files' names + Afegir l'extensió.!qB als noms dels arxius incomplets + + + + Automatically add torrents from: + Carregar automàticament arxius Torrents des de: + + + + Add folder... + Afegeix carpeta... + + + + Email notification upon download completion + Avisa'm per correu electrònic de la finalització de les descàrregues + + + + Destination email: + Adreça de correu electrònic: + + + + SMTP server: + Servidor SMTP: + + + + This server requires a secure connection (SSL) + + + + + Run an external program on torrent completion + Executar un programa extern en acabar el torrent + + + + Otherwise, the proxy server is only used for tracker connections + + + + + Use proxy for peer connections + + + + + Global Rate Limits + + + + + Apply rate limit to uTP connections + + + + + Apply rate limit to transport overhead + + + + + Alternative Global Rate Limits + + + + + Schedule the use of alternative rate limits + + + + + Use HTTPS instead of HTTP + + + + + Import SSL Certificate + + + + + Import SSL Key + + + + + Certificate: + + + + + Key: + + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + Update my dynamic domain name + + + + + Service: + + + + + Register + + + + + Domain name: + + + + Use %f to pass the torrent path in parameters + Utilitzeu %f per a passar el torrent la ruta dels paràmetres + + + + Use UPnP / NAT-PMP port forwarding from my router + Utilitza UPnP / NAT-PMP reenviament de ports del router + + + Proxy server + Servidor Proxy + + + + Reload the filter + Actualització del filtre + + + + Enable bandwidth management (uTP) + + + + + Privacy + Privacitat + + + + Enable DHT (decentralized network) to find more peers + Activar DHT (xarxa descentralitzada) per trobar més parells + + + + Use a different port for DHT and BitTorrent + Utilitza difrentes port per DHT i BitTorrent + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Intercanviar parells amb clients Bittorrent compatibles (μTorrent, Vuze,...) + + + + Enable Peer Exchange (PeX) to find more peers + Habilitar intercanvi de parells (PEX) per trobar més parells + + + + Enable Local Peer Discovery to find more peers + Habilitar Trobat Local de Pares per trobar més parells + + + + Encryption mode: + Mode de xifrat: + + + + Prefer encryption + Preferència de xifrat + + + + Require encryption + Necessiten xifrat + + + + Disable encryption + Deshabilitar xifrat + + + Share ratio limiting + Límit ratio compartició + + + + Seed torrents until their ratio reaches + Ratio compartició de llavors Torrent + + + + then + després + + + + Pause them + Pausar + + + + Remove them + Esborrar + + + + Enable Web User Interface (Remote control) + Habilitar interfície Web d'usuari (Control remot) + + + + Use UPnP / NAT-PMP to forward the port from my router + + + + + Bypass authentication for localhost + Eludir la autenticació per localhost + + + Listening port + Port d'escolta + + + + Port used for incoming connections: + Port utilitzat per a connexions entrants: + + + + Random + Aleatori + + + Enable UPnP port mapping + Habilitar mapatge de ports UPnP + + + Enable NAT-PMP port mapping + Habilitar mapatge de ports NAT-PMP + + + Connections limit + Límit de connexions + + + + Global maximum number of connections: + Nombre global màxim de connexions: + + + + Maximum number of connections per torrent: + Nombre màxim de connexions per torrent: + + + + Maximum number of upload slots per torrent: + Nombre màxim de slots de pujada per torrent: + + + + + Upload: + Pujada: + + + + + Download: + Baixada: + + + + + + + KiB/s + + + + + + Behavior + Comportament + + + + BitTorrent + Bittorrent + + + + Language + Idioma + + + Global speed limits + Límits de velocitat global + + + Alternative global speed limits + Límits de velocitat global alternativa + + + + to + time1 to time2 + a + + + + Every day + Tots + + + + Week days + Dies laborals + + + + Week ends + Caps de setmana + + + Bittorrent features + Característiques de Bittorrent + + + Enable DHT network (decentralized) + Habilitar xarxa DHT (descentralitzada) + + + Use a different port for DHT and Bittorrent + Utilitzar un port diferent per a la DHT i Bittorrent + + + + DHT port: + Port DHT: + + + Enable Peer Exchange / PeX (requires restart) + Activar intercanvi de Parells / PeX (és necessari reiniciar qBittorrent) + + + Enable Local Peer Discovery + Habilitar la font de recerca local de Parells + + + Enabled + Habilitat + + + Forced + Forçat + + + Disabled + Deshabilitat + + + HTTP Communications (trackers, Web seeds, search engine) + Comunicacions HTTP (Trackers, Llavors de Web, Motors de Cerca) + + + + Host: + + + + Peer Communications + Comunicacions Parelles + + + + SOCKS4 + + + + + Type: + Tipus: + + + + Remove folder + Esborrar carpeta + + + + Listening Port + + + + + Connections Limits + + + + + Proxy Server + + + + + IP Filtering + filtrat IP + + + Schedule the use of alternative speed limits + Calendari per utilització dels límits de velocitat alternativa + + + + from + from (time1 to time2) + des de + + + + When: + Quan: + + + + Look for peers on your local network + Podeu cercar parells a la teva xarxa local + + + Protocol encryption: + Protocol d'encriptació: + + + + (None) + (Cap) + + + + HTTP + + + + + + Port: + Port: + + + + + + Authentication + Autentificació + + + + Append .!qB extension to incomplete files + + + + + + + + Username: + Nom d'Usuari: + + + + + + + Password: + Contrasenya: + + + + SOCKS5 + + + + + Filter path (.dat, .p2p, .p2b): + Ruta de Filtre (.dat, .p2p, .p2b): + + + + Torrent Queueing + + + + + Share Ratio Limiting + + + + HTTP Server + Servidor HTTP + + + + PreviewSelect + + + Name + Nom + + + + Size + Mida + + + + Progress + Progrés + + + + + + Preview impossible + Impossible vista prèvia + + + + + + Sorry, we can't preview this file + Ho sento, no es pot realitzar una vista prèvia d'aquest arxiu + + + + ProgramUpdater + + Could not create the file %1 + No es va poder crear l'arxiu %1 + + + Failed to download the update at %1 + %1 is an URL + Error en descarregar l'actualització %1 + + + + PropListDelegate + + + Not downloaded + No descarregar + + + + + Normal + Normal (priority) + Normal + + + + + High + High (priority) + Alt + + + + Mixed + Mixed (priorities + Mixt + + + + + Maximum + Maximum (priority) + Màxim + + + + PropTabBar + + + General + General + + + + Trackers + Trackers + + + + Peers + Parells + + + + HTTP Sources + Fonts HTTP + + + + Content + Contingut + + + URL Seeds + URL Llavors + + + Files + Arxius + + + + PropertiesWidget + + + Save path: + Directori de destí: + + + + Torrent hash: + Hash de torrent: + + + + Comment: + Comentari: + + + + Share ratio: + Ratio de Compartició: + + + + + Downloaded: + Baixat: + + + + Availability: + Disponibilitat: + + + + Transfer + Transferència + + + + Uploaded: + Pujada: + + + + Wasted: + Perdut: + + + + Time active: + Time (duration) the torrent is active (not paused) + Temps actiu: + + + + Pieces size: + Mida de la peça: + + + + Torrent content: + Contingut del torrent: + + + + Select All + Selecciona Totes + + + + Select None + Treure Seleccions + + + + + Do not download + No descarregar + + + + UP limit: + Límit Pujada: + + + + DL limit: + Límit Baixada: + + + Time elapsed: + Temps transcorregut: + + + + Connections: + Connexions: + + + + Reannounce in: + Republicar en: + + + + Information + Informació + + + + Created on: + Creat: + + + General + General + + + Trackers + Trackers + + + Peers + Parells + + + URL seeds + URL llavors + + + Files + Arxius + + + + Priority + Prioritat + + + + Normal + Normal + + + + Maximum + Màxim + + + + High + Alt + + + + + this session + en aquesta sessió + + + + + /s + /second (i.e. per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + Llavors per %1 + + + + %1 max + e.g. 10 max + + + + + + I/O Error + Error d'Entrada/Sortida + + + + This file does not exist yet. + Aquest arxiu encara no existeix. + + + + This folder does not exist yet. + Aquest arxiu encara no existeix. + + + + Rename... + Rebatejar... + + + + Rename the file + Rebatejar arxiu Torrent + + + + New name: + Nou nom: + + + + + The file could not be renamed + No es pot canviar el nom d'arxiu + + + + This file name contains forbidden characters, please choose a different one. + El nom introduït conté caràcters prohibits, si us plau n'elegeixi un altre. + + + + + This name is already in use in this folder. Please use a different name. + Aquest nom ja està en ús. Si us plau, usi un nom diferent. + + + + The folder could not be renamed + No es pot canviar el nom d'arxiu + + + + New url seed + New HTTP source + Nova llavor url + + + + New url seed: + Nova llavor url: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Aquesta llavor url ja està en la llista. + + + + + Choose save path + Seleccioni un directori de destinació + + + Save path creation error + Error en la creació del directori de destí + + + Could not create the save path + No es va poder crear el directori de destí + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 va assolir el ratio màxim establert. + + + + Removing torrent %1... + Extraient torrent %1... + + + + Pausing torrent %1... + Torrent Pausat %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent està usant el port: TCP/%1 + + + UPnP support [ON] + Suport per a UPnP [Encesa] + + + UPnP support [OFF] + Suport per a UPnP [Apagat] + + + NAT-PMP support [ON] + Suport per a NAT-PMP [Encesa] + + + NAT-PMP support [OFF] + Suport per a NAT-PMP[Apagat] + + + + HTTP user agent is %1 + HTTP d'usuari es %1 + + + Using a disk cache size of %1 MiB + Mida cache del Disc %1 MiB + + + + DHT support [ON], port: UDP/%1 + Suport per a DHT [Encesa], port: UPD/%1 + + + + + DHT support [OFF] + Suport per a DHT [Apagat] + + + + PeX support [ON] + Suport per a PeX [Encesa] + + + + PeX support [OFF] + Suport PeX [Apagat] + + + + Restart is required to toggle PeX support + És necessari reiniciar per activar suport PeX + + + Local Peer Discovery [ON] + Estat local de Parells [Encesa] + + + + Local Peer Discovery support [OFF] + Suport per a estat local de Parells [Apagat] + + + + Encryption support [ON] + Suport per a encriptat [Encesa] + + + + Encryption support [FORCED] + Suport per a encriptat [forçat] + + + + Encryption support [OFF] + Suport per a encriptat [Apagat] + + + + Embedded Tracker [ON] + Integrador de Tracker [Encès] + + + + Failed to start the embedded tracker! + Error en iniciar l'integrat de Tracker! + + + + Embedded Tracker [OFF] + Integrador de Tracker [Apagat] + + + + The Web UI is listening on port %1 + Port d'escolta d'Interfície Usuari Web %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Error interfície d'Usuari Web - No es pot enllaçar al port %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' Va ser eliminat de la llista de transferència i del disc. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' Va ser eliminat de la llista de transferència. + + + + '%1' is not a valid magnet URI. + '%1' no és una URI vàlida. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' ja està en la llista de descàrregues. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' reiniciat. (reinici ràpid) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' agregat a la llista de descàrregues. + + + + UPnP / NAT-PMP support [ON] + Suport UPnP / NAT-PMP [ON] + + + + UPnP / NAT-PMP support [OFF] + Suport UPnP / NAT-PMP [OFF] + + + + Reporting IP address %1 to trackers... + Adreça IP d'Infomes %1 de trackers... + + + + Local Peer Discovery support [ON] + Suport Trobat Local de Pares [ON] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Impossible descodificar l'arxiu torrent: '%1' + + + + This file is either corrupted or this isn't a torrent. + Aquest arxiu pot ser corrupte, o no ser un torrent. + + + + Error: The torrent %1 does not contain any file. + Error: aquest torrent %1 no conté cap fitxer. + + + + Note: new trackers were added to the existing torrent. + Nota: nous Trackers s'han afegit al torrent existent. + + + + Note: new URL seeds were added to the existing torrent. + Nota: noves llavors URL s'han afegit al Torrent existent. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>va ser bloquejat a causa del filtre IP</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>Va ser bloquejat a causa de fragments corruptes</i> + + + + The network interface defined is invalid: %1 + La interfície de la xarxa definida no és vàlida:%1 + + + + Trying any other network interface available instead. + Tractant qualsevol interfície de xarxa disponibles en el seu lloc. + + + + Listening on IP address %1 on network interface %2... + Escoltant l'adreça IP %1 de la interfície de xarxa %2... + + + + Failed to listen on network interface %1 + No s'ha pogut escoltar la interfície de xarxa %1 + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Descàrrega recursiva d'arxiu %1 incrustada en Torrent %2 + + + + + Unable to decode %1 torrent file. + No es pot descodificar %1 arxiu torrent. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + L'equip entrarà en 15 segons en estat de suspensió, a menys que ho cancel... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + L'equip s'apagarà en 15 segons, a menys que ho cancel... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent serà tancat en 15 segons, a menys que ho cancel... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Anàlisi reeixit de filtratge IP: %1 normes aplicades. + + + + Error: Failed to parse the provided IP filter. + Error: No s'ha pogut analitzar el filtratge IP. + + + + Torrent name: %1 + Nom del torrent: %1 + + + + Torrent size: %1 + Mida del torrent: %1 + + + + Save path: %1 + Guardar ruta: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + El torrernt es va descarregar a %1. + + + + Thank you for using qBittorrent. + Gràcies per utilitzar qBittorrent. + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 s'ha finalitzat les descàrregues + + + + An I/O error occured, '%1' paused. + Error E/S ocorregut, '%1' pausat. + + + + + Reason: %1 + Raó: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Va fallar el mapatge del port, missatge: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Mapatge del port reeixit, missatge: %1 + + + + File sizes mismatch for torrent %1, pausing it. + La mida del fitxer no coincideix amb el torrent %1, pausat. + + + + Fast resume data was rejected for torrent %1, checking again... + Es van negar les dades per a reinici ràpid del torrent: %1, verificant de nou... + + + + Url seed lookup failed for url: %1, message: %2 + Va fallar la recerca de llavor per l'Url: %1, missatge: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Descarregant '%1', si us plau esperi... + + + + RSS + + + Search + Cerca + + + + New subscription + Nova subscripció + + + + + + Mark items read + Marcar per llegir + + + + Update all + Actualitzar tot + + + + RSS Downloader... + Descarregar RSS... + + + + Settings... + Configuració... + + + Feed URL + Canal URL + + + + Rename... + Rebatejar... + + + + + Update + Actualitzar + + + RSS feed downloader... + Descarregar Canal RSS... + + + + New folder... + Nova carpeta... + + + + Manage cookies... + Administrar Cookies... + + + RSS feeds + Canals RSS + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(doble-click per iniciar la descàrrega)</span></p></body></html> + + + Article title + Títol de l'article + + + + New subscription... + Nova subscripció... + + + + + Update all feeds + Actualitzar tots els Canals + + + + + Delete + Esborrar + + + + Rename + Rebatejar + + + + Download torrent + Descarregar torrent + + + + Open news URL + Obrir nova URL + + + + Copy feed URL + Copiar Canal URL + + + + Refresh RSS streams + Actualitzar els Canals RSS + + + + RSSImp + + + Please type a rss stream url + Si us plau escriu una URL d'un Canal RSS + + + + Stream URL: + URL del Canal: + + + + + Are you sure? -- qBittorrent + Està segur? -- qBittorrent + + + + + &Yes + &Sí + + + + + &No + &No + + + + Please choose a folder name + Si us plau elegeixi un nom per a la carpeta + + + + Folder name: + Nom de la carpeta: + + + + New folder + Nova carpeta + + + + Overwrite attempt + Intentant sobreescriure + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Impossible sobreescriure %1 sector. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Aquesta font de RSS ja està en la llista. + + + + Are you sure you want to delete these elements from the list? + Segur que vols esborrar aquests elements de la llista? + + + + Are you sure you want to delete this element from the list? + Segur que vols esborrar aquest element de la llista? + + + + Please choose a new name for this RSS feed + Si us plau, elegeixi un nou nom per al Canal RSS + + + + New feed name: + Nom del nou Canal: + + + + Name already in use + Aquest nom ja es troba en ús + + + + This name is already used by another item, please choose another one. + Aquest nom ja s'està usant, si us plau, elegeixi un altre. + + + + Date: + Data: + + + + Author: + Autor: + + + + Unread + No llegits + + + + RssArticle + + No description available + Sense descripció disponible + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Descarregar automàtica %1 Torrent %2 Canal RSS... + + + + RssItem + + No description available + Sense descripció disponible + + + + RssSettings + + RSS Reader Settings + Ajustaments Lector RSS + + + RSS feeds refresh interval: + Interval d'actualització de Canals RSS: + + + minutes + minuts + + + Maximum number of articles per feed: + Nombre màxim d'articles per Canal: + + + + RssSettingsDlg + + + RSS Reader Settings + Ajustaments Lector RSS + + + + RSS feeds refresh interval: + Interval d'actualització de Canals RSS: + + + + minutes + minuts + + + + Maximum number of articles per feed: + Nombre màxim d'articles per Canal: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Descarregar automàtica %1 Torrent %2 Canal RSS... + + + + ScanFoldersModel + + + Watched Folder + Cerca fitxers .torrents + + + + Download here + Descarregar Torrent aquí + + + + SearchCategories + + + All categories + Totes les categories + + + + Movies + Vídeos + + + + TV shows + Programes TV + + + + Music + Música + + + + Games + Jocs + + + + Anime + + + + + Software + Programes + + + + Pictures + Imatges + + + + Books + Llibres + + + + SearchEngine + + + Empty search pattern + Patró de recerca buit + + + + Please type a search pattern first + Si us plau escrigui un patró de recerca primer + + + + + Results + Resultats + + + + Searching... + Buscant... + + + + Cut + Tallar + + + + Copy + Copiar + + + + Paste + Pegar + + + + Clear field + Esborrar de la llista + + + + Clear completion history + Netejar historial de recerques + + + + Confirmation + Confirmació + + + + Are you sure you want to clear the history? + Esteu segur que voleu esborrar l'historial? + + + + + + Search + Cerca + + + + Missing Python Interpreter + Manca intèrpret de Python + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x és necessari per utilitzar el motor de cerca però no sembla que estigui instal-lat. +¿Voleu instal-lo ara? + + + + Search Engine + Motor de cerca + + + + + Search has finished + Recerca acabada + + + + An error occured during search... + Va ocórrer un error durant la recerca... + + + + + Search aborted + Recerca avortada + + + + Download error + Error de descàrrega + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + La instal-lació de Python no es va poder realitzar, la raó:%1. +Si us plau, instal-li'l de forma manual. + + + + Search returned no results + La recerca no va tornar resultats + + + + Results + i.e: Search results + Resultats + + + + + Unknown + Desconegut + + + + SearchTab + + + Name + i.e: file name + Nom + + + + Size + i.e: file size + Mida + + + + Seeders + i.e: Number of full sources + Llavors + + + + Leechers + i.e: Number of partial sources + Leechers + + + + Search engine + Motor de cerca + + + + ShutdownConfirmDlg + + + Shutdown confirmation + Tancar confirmació + + + + SpeedLimitDialog + + + KiB/s + KiB/s + + + + StatusBar + + + + Connection status: + Estat de la connexió: + + + + + No direct connections. This may indicate network configuration problems. + No hi ha connexions directes. Això pot indicar problemes en la configuració de la xarxa. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + Baixada: %1 B/s - Total: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + Pujada: %1 B/s - Total: %2 + + + + + DHT: %1 nodes + DHT: %1 nodes + + + + qBittorrent needs to be restarted + És necessari reiniciar qBittorrent + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent ha estat actualitzat i ha de ser reiniciat perquè els canvis siguin efectius. + + + + + Connection Status: + Estat de la connexió: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Fora de línia. Això normalment significa que qBittorrent no pot escoltar el port seleccionat per a les connexions entrants. + + + + Online + En línea + + + + + %1/s + Per second + %1/s + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Baixada: %1/s - Total: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Pujada: %1/s - Total: %2 + + + + Click to switch to alternative speed limits + Cliqueu per canviar als límits de velocitat alternativa + + + + Click to switch to regular speed limits + Cliqueu per canviar als límits de velocitat normal + + + Click to disable alternative speed limits + Click per desactivar els límits de velocitat alternativa + + + Click to enable alternative speed limits + Click per activar els límits de velocitat alternativa + + + + Global Download Speed Limit + Velocitat límit global de descàrrega + + + + Global Upload Speed Limit + Velocitat límit global de pujada + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Seleccioni una altra carpeta per agregar el torrent + + + + Select a file to add to the torrent + Seleccioni un altre arxiu per agregar el torrent + + + Please type an announce URL + Si us plau escriu una URL d'anunci + + + Announce URL: + Tracker URL + URL d'anunci: + + + Please type a web seed url + Si us plau escriu una url de llavor web + + + Web seed URL: + URL de llavor web: + + + + No input path set + Sense ruta de destí establerta + + + + Please type an input path first + Si us plau escriu primer una ruta d'entrada + + + + Select destination torrent file + Seleccioni una destí per a l'arxiu torrent + + + + Torrent Files + Arxius Torrent + + + + + + Torrent creation + Crear Torrent + + + + Torrent creation was unsuccessful, reason: %1 + La creació del torrent no ha estat reeixida, raó: %1 + + + + Created torrent file is invalid. It won't be added to download list. + La creació de l'arxiu torrent no és vàlida. No s'afegirà a la llista de descàrregues. + + + + Torrent was created successfully: + El Torrent es va crear amb èxit: + + + + TorrentFilesModel + + + Name + Nom + + + + Size + Mida + + + + Progress + Progrés + + + + Priority + Prioritat + + + + TorrentImportDlg + + + Torrent Import + Importar Torrent + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Aquest assistent l'ajudarà a compartir amb qBittorrent, un torrent ja descarregat. + + + + Torrent file to import: + Arxiu Torrent per importar: + + + + + ... + ... + + + + Content location: + Ubicació del contingut: + + + + Skip the data checking stage and start seeding immediately + Saltar-se la fase de control de dades i començar a sembrar tot seguit + + + + Import + Importar + + + + Torrent file to import + Arxiu Torrent per importar + + + + Torrent files (*.torrent) + Arxius Torrent (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 Arxius + + + + Please provide the location of %1 + %1 is a file name + Si us plau, indiqui la ubicació del %1 + + + + Please point to the location of the torrent: %1 + Si us plau, elegeixi la ubicació del torrent: %1 + + + + Invalid torrent file + Arxiu torrent no vàlid + + + + This is not a valid torrent file. + Això no és un arxiu torrent vàlid. + + + + TorrentModel + + + Name + i.e: torrent name + Nom + + + + Size + i.e: torrent size + Mida + + + + Done + % Done + Progrés + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Estat + + + + Seeds + i.e. full sources (often untranslated) + Llavors + + + + Peers + i.e. partial sources (often untranslated) + Parells + + + + Down Speed + i.e: Download speed + Vel. Baixada + + + + Up Speed + i.e: Upload speed + Vel. Pujada + + + + Ratio + Share ratio + Ratio + + + + ETA + i.e: Estimated Time of Arrival / Time left + Temps estimat + + + + Label + Etiqueta + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Afegit el + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Completat a + + + + Tracker + Tracker + + + + Down Limit + i.e: Download limit + Límit Baixada + + + + Up Limit + i.e: Upload limit + Límit Pujada + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Quantitat descarregada + + + + Amount left + Amount of data left to download (e.g. in MB) + Quantitat que manca + + + + Time Active + Time (duration) the torrent is active (not paused) + Temps actiu + + + + TrackerList + + + URL + + + + + Status + Estat + + + + Peers + Parells + + + + Message + Missatge + + + + [DHT] + + + + + [PeX] + + + + + [LSD] + + + + + + + + + Working + Treballant + + + + + + Disabled + Deshabilitat + + + + This torrent is private + Aquest torrent és privat + + + + Updating... + Actualitzant... + + + + + Not working + Aturat + + + + + Not contacted yet + Encara sense connexió + + + + Add a new tracker... + Afegir nou tracker... + + + + Remove tracker + Esborrar traker + + + + Force reannounce + Forçar Re-publicar + + + + TrackersAdditionDlg + + + Trackers addition dialog + Diàleg per afegir trackers + + + + List of trackers to add (one per line): + Llista de trackers a afegir (un per línia): + + + + µTorrent compatible list URL: + Llista d'URL de µTorrent compatibles: + + + + I/O Error + Error d'Entrada/Sortida + + + + Error while trying to open the downloaded file. + Error en intentar obrir l'arxiu descarregat. + + + + No change + Sense canvis + + + + No additional trackers were found. + No es va trobar cap Tracker. + + + + Download error + Error de descàrrega + + + + The trackers list could not be downloaded, reason: %1 + La llista de Trackers no va poder ser descarregada. Raó: %1 + + + + TransferListDelegate + + + Downloading + Descarregant + + + + Paused + Pausat + + + + Queued + i.e. torrent is queued + A cua + + + + Seeding + Torrent is complete and in upload-only mode + Sembrando + + + + Stalled + Torrent is waiting for download to begin + Detinguda + + + + Checking + Torrent local data is being checked + Verificant + + + + /s + /second (.i.e per second) + + + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Sembrant %1 + + + + TransferListFiltersWidget + + + + All + Tots + + + + + Downloading + Descarregant + + + + + Completed + Completats + + + + + Paused + Pausats + + + + + Active + Actius + + + + + Inactive + Inactius + + + + + All labels + Etiquetades + + + + + Unlabeled + Sense Etiquetar + + + + Remove label + Esborrar etiqueta + + + + Add label... + Afegir Etiqueta... + + + + Resume torrents + Reprèn Torrents + + + + Pause torrents + Pausar torrents + + + + Delete torrents + Esborrar torrents + + + + New Label + Nova Etiqueta + + + + Label: + Etiqueta: + + + + Invalid label name + Nom d'Etiqueta no vàlid + + + + Please don't use any special characters in the label name. + Si us plau, no utilitzi caràcters especials per al nom de l'Etiqueta. + + + + TransferListWidget + + Down Speed + i.e: Download speed + Vel. Baixada + + + Up Speed + i.e: Upload speed + Vel. Pujada + + + ETA + i.e: Estimated Time of Arrival / Time left + Temps estimat + + + + Column visibility + Visibilitat de columnes + + + Name + i.e: torrent name + Nom + + + Size + i.e: torrent size + Mida + + + Done + % Done + Progrés + + + Status + Torrent status (e.g. downloading, seeding, paused) + Estat + + + Seeds + i.e. full sources (often untranslated) + Llavors + + + Peers + i.e. partial sources (often untranslated) + Parells + + + Ratio + Share ratio + Ratio + + + + Label + Etiqueta + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Afegit el + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Completat a + + + Tracker + Tracker + + + Down Limit + i.e: Download limit + Límit Baixada + + + Up Limit + i.e: Upload limit + Límit Pujada + + + + Choose save path + Seleccioni un directori de destinació + + + Save path creation error + Error en la creació del directori de destí + + + Could not create the save path + No es va poder crear el directori de destí + + + + Torrent Download Speed Limiting + Límit de velocitat de Baixada Torrent + + + + Torrent Upload Speed Limiting + Límit de velocitat de Pujada Torrent + + + + New Label + Nova Etiqueta + + + + Label: + Etiqueta: + + + + Invalid label name + Nom d'Etiqueta no vàlid + + + + Please don't use any special characters in the label name. + Si us plau, no utilitzi caràcters especials per al nom de l'Etiqueta. + + + + Rename + Rebatejar + + + + New name: + Nou nom: + + + + Resume + Resume/start the torrent + Reprende + + + + Pause + Pause the torrent + Pausar + + + + Delete + Delete the torrent + Esborrar + + + + Preview file... + Previsualitzar arxiu... + + + + Limit share ratio... + Límit ràtio compartició ... + + + + Limit upload rate... + Taxa límit de Pujada... + + + + Limit download rate... + Taxa límit de Baixada... + + + + Priority + Prioritat + + + + Open destination folder + Obrir carpeta destí + + + + Move up + i.e. move up in the queue + Moure amunt + + + + Move down + i.e. Move down in the queue + Moure avall + + + + Move to top + i.e. Move to top of the queue + Moure al principi + + + + Move to bottom + i.e. Move to bottom of the queue + Moure al final + + + + Set location... + Establir una destinació... + + + + Force recheck + Forçar verificació de arxiu + + + + Copy magnet link + Copiar magnet link + + + + Super seeding mode + Mode de SuperSembra + + + + Rename... + Rebatejar... + + + + Download in sequential order + Descarregar en ordre seqüencial + + + + Download first and last piece first + Descarregar primer, primeres i últimes parts + + + + New... + New label... + Nou... + + + + Reset + Reset label + Reset Etiquetas + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Límits de ràtio de Pujada/Baixada + + + + Use global ratio limit + Utilitza límit de ràtio global + + + + + + buttonGroup + buttonGroup + + + + Set no ratio limit + Sense límits de ràtio + + + + Set ratio limit to + Limitar ràtio a + + + + UsageDisplay + + + Usage: + Us: + + + + displays program version + Mostra la versió del programa + + + + disable splash screen + Desactivar pantalla d'inici + + + + displays this help message + Mostra missatge d'ajuda + + + + changes the webui port (current: %1) + Canviar el port d'IU Web (actual:%1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [arxius o URLs] : la descàrrega de torrents necessita aprovació per l'usuari (opcional) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Vull agrair a les següents persones que voluntàriament van traduir qBittorrent: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Si us plau contacta'm si vols traduir qBittorrent al teu propi idioma. + + + + addPeerDialog + + + Peer addition + Incorporar Parell + + + + IP + + + + + Port + Port + + + + addTorrentDialog + + + Torrent addition dialog + Diàleg per afegir un torrent + + + + Save path: + Directori de destí: + + + + ... + ... + + + + Torrent size: + Mida torrent: + + + + + Unknown + Desconegut + + + + Free disk space: + Espai lliure al Disc: + + + + Label: + Etiqueta: + + + + Torrent content: + Contingut del torrent: + + + + Select All + Selecciona Totes + + + + Select None + Treure Seleccions + + + + Download in sequential order (slower but good for previewing) + Descarregar en ordre seqüencial (més lent, però millor per a la vista prèvia) + + + + Skip file checking and start seeding immediately + Anul-lar verificació i començar a sembrar tot seguit + + + + + Do not download + No descarregar + + + + Add to download list in paused state + Agregar la llista de descàrregues en estat pausat + + + + Add + Agregar + + + + Cancel + Cancel-lar + + + + Normal + Normal + + + + High + Alt + + + + Maximum + Màxima + + + + authentication + + + + Tracker authentication + Autentificació del Tracker + + + + Tracker: + Tracker: + + + + Login + Autentificar-se + + + + Username: + Usuari: + + + + Password: + Contrasenya: + + + + Log in + Connectar + + + + Cancel + Cancel-lar + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Confirmar esborrament - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Segur que vols esborrar els torrents seleccionats de la llista de transferències? + + + + Remember choice + Recordar sempre aquesta elecció + + + + Also delete the files on the hard disk + Esborrar també l'arxiu del disc físic + + + + createTorrentDialog + + + Cancel + Cancel-lar + + + + Torrent Creation Tool + Eina de creació de Torrent + + + + Torrent file creation + Creació d'arxiu torrent + + + Announce urls (trackers): + Url's d'anunci (trackers): + + + Comment (optional): + Comentari (opcional): + + + Web seeds urls (optional): + Url's de llavors web (opcional): + + + + File or folder to add to the torrent: + Arxiu o carpeta a agregar al torrent: + + + + Add file + Nou arxius + + + + Add folder + Nova carpeta + + + + Tracker URLs: + Tracker URLs: + + + + Web seeds urls: + Llavors web urls: + + + + Comment: + Comentari: + + + + Piece size: + Mida de la peça: + + + + 32 KiB + 32 KiB + + + + 64 KiB + 64 KiB + + + + 128 KiB + 128 KiB + + + + 256 KiB + 256 KiB + + + + 512 KiB + 512 KiB + + + + 1 MiB + 1 MiB + + + + 2 MiB + 2 MiB + + + + 4 MiB + 4 MiB + + + + Auto + Auto + + + + Private (won't be distributed on DHT network if enabled) + Privat (no es distribuirà per xarxa DHT si s'habilita) + + + + Start seeding after creation + Començar amb la sembra després de la creació + + + + Create and save... + Crear i guardar... + + + + Progress: + Progrés: + + + + createtorrent + + Select destination torrent file + Selecciona una destí per a l'arxiu torrent + + + Torrent Files + Arxiu Torrent + + + No input path set + Sense ruta de destí establerta + + + Please type an input path first + Si us plau escriu primer una ruta d'entrada + + + Torrent creation + Crear Torrent + + + Torrent was created successfully: + El Torrent es va crear amb èxit: + + + Select a folder to add to the torrent + Selecciona una altra carpeta per agregar el torrent + + + Please type an announce URL + Si us plau escriu una URL d'anunci + + + Torrent creation was unsuccessful, reason: %1 + La creació del torrent no ha estat reeixida, raó: %1 + + + Announce URL: + Tracker URL + URL d'anunci: + + + Please type a web seed url + Si us plau escriu una url de llavor web + + + Web seed URL: + URL de llavor web: + + + Select a file to add to the torrent + Seleccioni un altre arxiu per agregar el torrent + + + Created torrent file is invalid. It won't be added to download list. + La creació de l'arxiu torrent no és vàlida. No s'afegirà a la llista de descàrregues. + + + + downloadFromURL + + Download Torrents from URLs + Descarregar torrents de URLs + + + Only one URL per line + Sol una URL per línia + + + + Add torrent links + Afegir enllaç torrent + + + + Both HTTP and Magnet links are supported + Els dos HTTP i Magnet links són suportats + + + + Download + Descarregar + + + + Cancel + Cancel-lar + + + + Download from urls + Descarregar d'urls + + + + No URL entered + No s'ha escrit cap URL + + + + Please type at least one URL. + Si us plau escriu almenys una URL. + + + + downloadThread + + I/O Error + Error d'Entrada/Sortida + + + The remote host name was not found (invalid hostname) + El nom host no s'ha trobat (nom host no vàlid) + + + The operation was canceled + L'operació va ser cancel-lada + + + The remote server closed the connection prematurely, before the entire reply was received and processed + El servidor remot va tancar la connexió abans de temps, abans que fos rebut i processat + + + The connection to the remote server timed out + Connexió amb el servidor remot fallida, Temps d'espera esgotat + + + SSL/TLS handshake failed + SSL/TLS handshake fallida + + + The remote server refused the connection + El servidor remot va rebutjar la connexió + + + The connection to the proxy server was refused + La connexió amb el servidor proxy va ser rebutjada + + + The proxy server closed the connection prematurely + Connexió tancada abans de temps pel servidor proxy + + + The proxy host name was not found + El nom host del proxy no s'ha trobat + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + La connexió amb el servidor proxy s'ha esgotat, o el proxy no va respondre a temps a la sol-licitud enviada + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + El proxy requereix autenticació a fi d'atendre la sol-licitud, però no va acceptar les credencials que va oferir + + + The access to the remote content was denied (401) + L'accés al contingut remot ha estat rebutjat (401) + + + The operation requested on the remote content is not permitted + L'operació sol-licitada en el contingut remot no està permesa + + + The remote content was not found at the server (404) + El contingut remot no es troba al servidor (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + El servidor remot requereix autenticació per servir el contingut, però les credencials proporcionades no són correctes + + + The Network Access API cannot honor the request because the protocol is not known + Protocol desconegut + + + The requested operation is invalid for this protocol + L'operació sol-licitada no és vàlida per a aquest protocol + + + An unknown network-related error was detected + Error de Xarxa desconegut + + + An unknown proxy-related error was detected + Error de Proxy desconegut + + + An unknown error related to the remote content was detected + Error desconegut al servidor remot + + + A breakdown in protocol was detected + Error de protocol + + + Unknown error + Error desconegut + + + + engineSelect + + + Search plugins + Cerca plugins + + + + Installed search engines: + Motors de cerca instal-lats: + + + + Name + Nom + + + + Url + Url + + + + + Enabled + Habilitat + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Pots obtenir nous plugins de motors de cerca aquí <a href="http:plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Instal-lar-ne un de nou + + + + Check for updates + Cerca actualitzacions + + + + Close + Tancar + + + Enable + Habilitar + + + Disable + Deshabilitar + + + + Uninstall + Desinstal-lar + + + + engineSelectDlg + + + Uninstall warning + Alerta de desinstal-lació + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Alguns plugins no van poder ser instal-lats perquè estan inclosos en qBittorrent. +Només els que has agregat per tí mateix poden ser desinstal-lats. +De qualsevol manera, aquests plugins van ser deshabilitats. + + + + Uninstall success + Desinstal-lació correcta + + + + Select search plugins + Seleccioni els plugins de recerca + + + + qBittorrent search plugins + Plugins de de recerca qBittorrent + + + + + + + + Search plugin install + Instal-lar plugin de recerca + + + + + + Yes + + + + + + + + No + No + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Una versió més recent del plugin de motor de cerca %1 ja està instal-lada. + + + + + + + Search plugin update + Actualització del plugin de recerca + + + + + Sorry, update server is temporarily unavailable. + Ho sento, el servidor d'actualització aquesta temporalment no disponible. + + + + All your plugins are already up to date. + Tots els teus plugins ja estan actualitzats. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + El plugin de motor de cerca %1 no va poder ser actualitzat, es mantindrà la versió antiga. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + El plugin de motor de cerca %1 no va poder ser instal-lat. + + + + All selected plugins were uninstalled successfully + Tots els plugins seleccionats van ser instal-lats reeixidament + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + El plugin de motor de cerca %1 va ser actualitzat reeixidament. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + El plugin de motor de cerca %1 va ser instal-lat reeixidament. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Ho lamento, la instal-lació del plugin de recerca %1 ha fallat. + + + + New search engine plugin URL + URL del nou plugin de motor de cerca + + + + URL: + URL: + + + + misc + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent tancarà l'equip ara, perquè totes les baixades s'han completat. + + + + B + bytes + B + + + + KiB + kibibytes (1024 bytes) + KiB + + + + MiB + mebibytes (1024 kibibytes) + MiB + + + + GiB + gibibytes (1024 mibibytes) + GiB + + + + TiB + tebibytes (1024 gibibytes) + TiB + + + + %1h %2m + e.g: 3hours 5minutes + + + + + %1d %2h + e.g: 2days 10hours + + + + + + + + + + Unknown + Desconocido + + + + Unknown + Unknown (size) + Desconegut + + + + < 1m + < 1 minute + <1m + + + + %1m + e.g: 10minutes + %1m + + + + options_imp + + + + + + Choose a save directory + Seleccioni un directori per guardar + + + + Add directory to scan + Afegir directori per escanejar + + + + Folder is already being watched. + Aquesta carpeta ja està seleccionada per escanejar. + + + + Folder does not exist. + La carpeta no existeix. + + + + Folder is not readable. + La carpeta no és llegible. + + + + Failure + Error + + + + Failed to add Scan Folder '%1': %2 + No es pot escanejar aquesta carpetes '%1':%2 + + + + + Choose export directory + Seleccioni directori d'exportació + + + + + Choose an ip filter file + Seleccioni un arxiu de filtre d'ip + + + + + Filters + Filtres + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + Error d'anàlisi + + + + Failed to parse the provided IP filter + No s'ha pogut analitzar el filtratge IP + + + + Successfully refreshed + Actualitzat amb èxit + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + Succesfully refreshed + Actualitzat amb èxit + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Anàlisi reeixit del filtrat IP: %1 normes aplicades. + + + + pluginSourceDlg + + + Plugin source + Font del plugin + + + + Search plugin source: + Font del plugin de recerca: + + + + Local file + Arxiu local + + + + Web link + Vincle web + + + + preview + + + Preview selection + Selecció de vista prèvia + + + + File preview + Vista prèvia d'arxiu + + + + The following files support previewing, <br>please select one of them: + Els següents arxius suporten vista prèvia, <br>por favor seleccioni un d'ells: + + + + Preview + Vista prèvia + + + + Cancel + Cancel-lar + + + + previewSelect + + Preview impossible + Impossible vista prèvia + + + Sorry, we can't preview this file + Ho sento, no es pot realitzar una vista prèvia d'aquest arxiu + + + Name + Nom + + + Size + Mida + + + Progress + Progrés + + + + search_engine + + + + Search + Cerca + + + + Status: + Estat: + + + + Stopped + Detingut + + + + Download + Descarregar + + + + Go to description page + Pàgina de descripció + + + + Search engines... + Motors de cerca... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + Impossible descodificar l'arxiu torrent: + + + + + + Choose save path + Escollir directori de destí + + + + Unable to decode magnet link: + No es pot descodificar l'enllaç magnet: + + + + Magnet Link + Enllaç magnet + + + + Rename... + Rebatejar... + + + + Rename the file + Rebatejar arxiu + + + + New name: + Nou nom: + + + + + The file could not be renamed + No es pot canviar el nom d'arxiu + + + + This file name contains forbidden characters, please choose a different one. + El nom introduït conté caràcters prohibits, si us plau n'elegeixi un altre. + + + + + This name is already in use in this folder. Please use a different name. + Aquest nom ja està en ús. Si us plau, usi un nom diferent. + + + + The folder could not be renamed + No es pot canviar el nom d'arxiu + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 disponible després de descarregar el torrent) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (Es necessiten més %1) + + + + Empty save path + Ruta de destí buida + + + + Please enter a save path + Si us plau introdueixi un directori de destí + + + + Save path creation error + Error en la creació del directori de destí + + + + Could not create the save path + Impossible crear el directori de destí + + + + Invalid label name + Nom d'Etiqueta no vàlid + + + + Please don't use any special characters in the label name. + Si us plau, no utilitzi caràcters especials per al nom de l'Etiqueta. + + + + Seeding mode error + Error en la Sembra + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Vostè ha decidit ignorar la verificació d'arxius. Tanmateix, els arxius locals no semblen existir a la carpeta de destí actual. Si us plau, desactivi aquesta funció o actualitzi la ruta de destinació. + + + + Invalid file selection + Selecció d'arxiu invàlida + + + + You must select at least one file in the torrent + Ha de seleccionar almenys un arxiu torrent + + + + Priority + Prioritat + + + diff --git a/src/lang/qbittorrent_cs.qm b/src/lang/qbittorrent_cs.qm new file mode 100644 index 0000000000000000000000000000000000000000..24bd17fdaf749f95ee75b5c7c15bbf36a8c3b264 GIT binary patch literal 117216 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 Oer$B~|LuQk|NjR@+jjW? literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_cs.ts b/src/lang/qbittorrent_cs.ts new file mode 100644 index 000000000..d6407fb1b --- /dev/null +++ b/src/lang/qbittorrent_cs.ts @@ -0,0 +1,6778 @@ + + + + + AboutDlg + + + About qBittorrent + O aplikaci qBittorrent + + + + About + O aplikaci + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Bittorrent klient naprogramován v C++, používající Qt4 </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">a libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Domovská stránka:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Fórum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent na Freenode</span></p></body></html> + + + + Author + Autor + + + + Name: + Jméno: + + + + Country: + Stát: + + + + E-mail: + E-mail: + + + + Christophe Dumez + Christophe Dumez + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Pokročilý BitTorrent klient programovaný v C++, používající QT4 alibtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent na Freenode</span></p></body></html> + + + + France + Francie + + + + Translation + Překlad + + + + License + Licence + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + + chris@qbittorrent.org + chris@qbittorrent.org + + + + Thanks to + Poděkování + + + + AdvancedSettings + + Property + Vlastnost + + + Value + Hodnota + + + + Disk write cache size + Velikost diskové vyrovnávací paměťi pro zápis + + + + MiB + MiB + + + + Outgoing ports (Min) [0: Disabled] + Odchozí porty (Min) [0: Vypnuto] + + + + Outgoing ports (Max) [0: Disabled] + Odchozí porty (Max) [0: Vypnuto] + + + + Recheck torrents on completion + Při dokončení překontrolovat torrenty + + + + Transfer list refresh interval + Interval obnovování seznamu přenosů + + + + ms + milliseconds + ms + + + + Setting + Nastavení + + + + Value + Value set for this setting + Hodnota + + + + Resolve peer countries (GeoIP) + Zjišťovat zemi původu protějšků (GeoIP) + + + + Resolve peer host names + Zjišťovat názvy počítačů protějšků + + + + Maximum number of half-open connections [0: Disabled] + Maximální počet napůl otevřených spojení [0: Vypnuto] + + + + Strict super seeding + Striktní super seeding + + + + Network Interface (requires restart) + Síťové rozhraní (vyžaduje restart) + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + Jakékoli rozhraní + + + + IP Address to report to trackers (requires restart) + IP adresa hlášená trackerům (vyžaduje restart) + + + + Display program on-screen notifications + Zobrazovat on-screen oznámení programu + + + Display program notification balloons + Zobrazovat informační bubliny programu + + + + Enable embedded tracker + Povolit vestavěný tracker + + + + Embedded tracker port + Port vestavěného trackeru + + + + Check for software updates + Zkontrolovat aktualizace + + + + Use system icon theme + Použít systémový motiv ikon + + + + Confirm torrent deletion + Potvrdit smazání torrentu + + + Display program notification baloons + Zobrazovat informační bubliny programu + + + + Ignore transfer limits on local network + Ignorovat limity přenosu dat v místní síti + + + Include TCP/IP overhead in transfer limits + Započítat režii TCP/IP do limitu přenosu dat + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Automatizované stahování RSS + + + + Enable the automated RSS downloader + Povolit automatizované stahování RSS + + + + Download rules + Pravidla stahování + + + + Rule definition + Definice pravidla + + + + Must contain: + Musí obsahovat: + + + + Must not contain: + Nesmí obsahovat: + + + + Use regular expressions + Používat regulární výrazy + + + + Import... + Import... + + + + Export... + Export... + + + + ... + ... + + + + Assign label: + Přiřadit štítek: + + + + Save to a different directory + Uložit do jiného adresáře + + + + Save to: + Uložit do: + + + + Apply rule to feeds: + Použít pravidlo na kanály: + + + + Matching RSS articles + Odpovídající RSS články + + + + New rule name + Nový název pravidla + + + + Please type the name of the new download rule. + Napište název nového pravidla stahování, prosím. + + + + + Rule name conflict + Název pravidla koliduje + + + + + A rule with this name already exists, please choose another name. + Pravidlo s tímto názvem již existuje, vyberte prosím název jiný. + + + + Are you sure you want to remove the download rule named %1? + Opravdu chcete odstranit pravidlo s názvem %1? + + + + Are you sure you want to remove the selected download rules? + Jste si jist, že chcete odstranit označená pravidla? + + + + Rule deletion confirmation + Potvrdit smazání pravidla + + + + Destination directory + Cílový adresář + + + + Invalid action + Neplatná akce + + + + The list is empty, there is nothing to export. + Seznam je prázdný, není co exportovat. + + + + Where would you like to save the list? + Kam chcete seznam uložit? + + + + Rules list (*.rssrules) + Seznam pravidel (*.rssrules) + + + + I/O Error + Chyba I/O + + + + Failed to create the destination file + Nezdařilo se vytvořit cílový soubor + + + + Please point to the RSS download rules file + Odkažte na soubor s pravidly stahování RSS, prosím + + + + Rules list (*.rssrules *.filters) + Seznam pravidel (*.rssrules *.filters) + + + + Import Error + Import selhal + + + + Failed to import the selected rules file + Import vybraného seznamu pravidel se nezdařil + + + + Add new rule... + Přidat nové pravidlo... + + + + Delete rule + Smazat pravidlo + + + + Rename rule... + Přejmenovat pravidlo... + + + + Delete selected rules + Smazat označená pravidla + + + + Rule renaming + Přejmenování pravidla + + + + Please type the new rule name + Napište název nového pravidla, prosím + + + + Regex mode: use Perl-like regular expressions + Regex mód: použijte Perl syntaxi pro regulární výrazy + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Zástupné znaky: lze použít<ul><li>? který odpovídá libovolnému jednomu znaku</li><li>* který odpovídá žádnému nebo více libovolných znaků</li><li>Mezery se počítají jako operátor AND</li></ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Zástupné znaky: lze použít<ul><li>? který odpovídá libovolnému jednomu znaku</li><li>* který odpovídá žádnému nebo více libovolných znaků</li><li>| odpovídá operátoru OR</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 dosáhl maximálního nastaveného poměru sdílení. + + + Removing torrent %1... + Odstraňování torrentu %1... + + + Pausing torrent %1... + Pozastavování torrentu %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent naslouchá na portu: TCP/%1 + + + UPnP support [ON] + Podpora UPnP [ZAP] + + + UPnP support [OFF] + Podpora UPnP [VYP] + + + NAT-PMP support [ON] + Podpora NAT-PMP [ZAP] + + + NAT-PMP support [OFF] + Podpora NAT-PMP [VYP] + + + HTTP user agent is %1 + HTTP user agent je %1 + + + Using a disk cache size of %1 MiB + Použita vyrovnávací paměť o velikosti %1 MiB + + + DHT support [ON], port: UDP/%1 + Podpora DHT [ZAP], port: UDP/%1 + + + DHT support [OFF] + Podpora DHT [VYP] + + + PeX support [ON] + Podpora PeX [ZAP] + + + PeX support [OFF] + Podpora PeX [VYP] + + + Restart is required to toggle PeX support + Kvůli přepnutí podpory PEX je nutný restart + + + Local Peer Discovery [ON] + Local Peer Discovery [ZAP] + + + Local Peer Discovery support [OFF] + Podpora Local Peer Discovery [VYP] + + + Encryption support [ON] + Podpora šifrování [ZAP] + + + Encryption support [FORCED] + Podpora šifrování [VYNUCENO] + + + Encryption support [OFF] + Podpora šifrování [VYP] + + + The Web UI is listening on port %1 + Webové rozhraní naslouchá na portu %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Chyba webového rozhraní - Nelze se připojit k Web UI na port %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' byl odstraněn ze seznamu i z pevného disku. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' byl odstraněn ze seznamu přenosů. + + + '%1' is not a valid magnet URI. + '%1' není platný magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' už je v seznamu stahování. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' obnoven. (rychlé obnovení) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' přidán do seznamu stahování. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Nelze dekódovat soubor torrentu: '%1' + + + This file is either corrupted or this isn't a torrent. + Tento soubor je buď poškozen, nebo to není soubor torrentu. + + + Note: new trackers were added to the existing torrent. + Poznámka: ke stávajícímu torrentu byly přidány nové trackery. + + + Note: new URL seeds were added to the existing torrent. + Poznámka: ke stávajícímu torrentu byly přidány nové URL seedy. + + + Error: The torrent %1 does not contain any file. + Chyba: Torrent %1 neobsahuje žádný soubor. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>byl zablokován kvůli filtru IP</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>byl zakázán kvůli poškozeným částem</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekurzivní stahování souboru %1 vloženého v torrentu %2 + + + Unable to decode %1 torrent file. + Nelze dekódovat soubor torrentu %1. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Namapování portů selhalo, zpráva: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Namapování portů bylo úspěšné, zpráva: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Rychlé obnovení torrentu %1 bylo odmítnuto, zkouším znovu... + + + Reason: %1 + Důvod: %1 + + + Torrent name: %1 + Název torrentu: %1 + + + Torrent size: %1 + Velikost torrentu: %1 + + + Save path: %1 + Cesta pro uložení: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent byl stažen za %1. + + + Thank you for using qBittorrent. + Děkujeme za používání qBittorrentu. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] bylo dokončeno stahování %1 + + + An I/O error occured, '%1' paused. + Došlo k chybě I/O, '%1' je pozastaven. + + + File sizes mismatch for torrent %1, pausing it. + Nesouhlasí velikost souborů u torrentu %1, pozastaveno. + + + Url seed lookup failed for url: %1, message: %2 + Vyhledání URL seedu selhalo pro URL: %1, zpráva: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Stahuji '%1', prosím čekejte... + + + + ConsoleDlg + + qBittorrent log viewer + Prohlížeč záznamů qBittorrentu + + + General + Obecné + + + Blocked IPs + Blokované IP + + + + CookiesDlg + + + Cookies management + Správa cookies + + + + Key + As in Key/Value pair + Klíč + + + + Value + As in Key/Value pair + Hodnota + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Obvyklé klíče pro cookie jsou : '%1', '%2'. +Tyto informace by měly jít získat z nastavení webového prohlížeče. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + Vaše dynamická DNS byla úspěšně aktualizována. + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Chyba dynamické DNS: Služba je dočasně nedostupná, akce bude opakována za 30 minut. + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Chyba dynamické DNS: poskytnutý název počítače pod tímto účtem neexistuje. + + + + Dynamic DNS error: Invalid username/password. + Chyba dynamické DNS: Chybné jméno/heslo. + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Chyba dynamické DNS: qBittorrent je na černé listině této služby, nahlašte prosím chybu na http://bugs.qbittorrent.org. + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Chyba dynamické DNS: služba odpověděla %1, nahlašte prosím chybu na http://bugs.qbittorrent.org. + + + + Dynamic DNS error: Your username was blocked due to abuse. + Chyba dynamické DNS: Vaše přihlašovací jméno bylo zablokováno v důsledku zneužití. + + + + Dynamic DNS error: supplied domain name is invalid. + Chyba dynamické DNS: poskytnuté doménové jméno je neplatné. + + + + Dynamic DNS error: supplied username is too short. + Chyba dynamické DNS: poskytnuté přihlašovací jméno je příliš krátké. + + + + Dynamic DNS error: supplied password is too short. + Chyba dynamické DNS: poskytnuté heslo je příliš krátké. + + + + DownloadThread + + + + I/O Error + Chyba I/O + + + + The remote host name was not found (invalid hostname) + Vzdálený server nebyl nalezen (neplatný název počítače) + + + + The operation was canceled + Operace byla zrušena + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Vzdálený server předčasně ukončil připojení, dříve než byla celá odpověď přijata a zpracována + + + + The connection to the remote server timed out + Připojení k vzdálenému serveru vypršelo + + + + SSL/TLS handshake failed + SSL/TLS handshake selhalo + + + + The remote server refused the connection + Vzdálený server odmítl připojení + + + + The connection to the proxy server was refused + Připojení k proxy serveru bylo odmítnuto + + + + The proxy server closed the connection prematurely + Proxy server předčasně ukončil připojení + + + + The proxy host name was not found + Název proxy serveru nebyl nalezen + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Připojení k proxy serveru vypršelo nebo proxy dostatečně rychle neodpověla na zaslaný požadavek + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Proxy vyžaduje ověření, ale neakceptovala žádné z nabízených přihlašovacích údajů + + + + The access to the remote content was denied (401) + Přístup ke vzdálenému obsahu byl odepřen (401) + + + + The operation requested on the remote content is not permitted + Požadovaná operace na vzdáleném obsahu není dovolena + + + + The remote content was not found at the server (404) + Vzdálený obsah nebyl na serveru nalezen (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Vzdálený server vyžaduje ověření, ale neakceptoval žádné z nabízených přihlašovacích údajů + + + + The Network Access API cannot honor the request because the protocol is not known + API připojení k síti nemohlo akceptovat požadavek z důvodu neznámého protokolu + + + + The requested operation is invalid for this protocol + Požadovaná operace není pro tento protokol platná + + + + An unknown network-related error was detected + Byla detekována neznámá chyba sítě + + + + An unknown proxy-related error was detected + Byla detekována neznámá chyba související s proxy + + + + An unknown error related to the remote content was detected + Byla detekována neznámá chyba související se vzdáleným obsahem + + + + A breakdown in protocol was detected + Byla detekována chyba v protokolu + + + + Unknown error + Neznámá chyba + + + + EventManager + + + + Working + Funkční + + + + Updating... + Aktualizuji... + + + + + Not working + Nefunkční + + + + + Not contacted yet + Dosud nekontaktován + + + + + this session + tato relace + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Sdíleno %1 + + + + %1 max + e.g. 10 max + %1 max + + + + + %1/s + e.g. 120 KiB/s + %1/s + + + + ExecutionLog + + Form + Formulář + + + + General + Obecné + + + + Blocked IPs + Blokované IP + + + + FeedDownloader + + RSS Feed downloader + Stahování z RSS kanálů + + + RSS feed: + RSS kanál: + + + Feed name + Název kanálu + + + Automatically download torrents from this feed + Automaticky stahovat torrenty z tohoto kanálu + + + Download filters + Filtry stahování + + + Filters: + Filtry: + + + Filter settings + Nastavení filtrů + + + Matches: + Shody: + + + Does not match: + Neshoduje se: + + + Destination folder: + Cílový adresář: + + + ... + ... + + + Filter testing + Test filtru + + + Torrent title: + Název torrentu: + + + Result: + Výsledek: + + + Test + Test + + + Import... + Import... + + + Export... + Export... + + + Rename filter + Přejmenovat filtr + + + Remove filter + Odstranit filter + + + Add filter + Přidat filter + + + + FeedDownloaderDlg + + New filter + Nový filtr + + + Please choose a name for this filter + Vyberte název pro tento filter + + + Filter name: + Název filtru: + + + Invalid filter name + Neplatný název filtru + + + The filter name cannot be left empty. + Název filtru nesmí být prázdný. + + + This filter name is already in use. + Tento název filtru již existuje. + + + Choose save path + Vyberte cestu pro uložení + + + Filter testing error + Chyba testu filtru + + + Please specify a test torrent name. + Prosím zadejte název torrentu pro test. + + + matches + shody + + + does not match + neshoduje se + + + Select file to import + Označit soubory k importu + + + Filters Files + Soubory s filtry + + + Import successful + Import úspěšný + + + Filters import was successful. + Import filtrů nebyl úspěšný. + + + Import failure + Import selhal + + + Filters could not be imported due to an I/O error. + Filtry nemohou být importovány kvůli chybě I/O. + + + Select destination file + Vybrat cílový soubor + + + Export successful + Export byl úspěšný + + + Filters export was successful. + Export filtrů byl úspěšný. + + + Export failure + Export selhal + + + Filters could not be exported due to an I/O error. + Filtry nemohou být exportovány kvůli chybě I/O. + + + + FeedList + + Unread + Nepřečtené + + + + FeedListWidget + + + RSS feeds + RSS kanály + + + + Unread + Nepřečtené + + + + GUI + + Open Torrent Files + Otevřít torrent soubory + + + Torrent file association + Asociace souboru .torrent + + + Password update + Změna hesla + + + The UI lock password has been successfully updated + Heslo zamykající UI bylo úspěšně změněno + + + Transfers (%1) + Přenosy (%1) + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Potvrzení rekurzivního stahování + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent %1 obsahuje soubory .torrent, chcete je také začít stahovat? + + + Yes + Ano + + + No + Ne + + + Never + Nikdy + + + Global Upload Speed Limit + Celkový limit rychlosti nahrávání + + + Global Download Speed Limit + Celkový limit rychlosti stahování + + + A newer version is available + Je k dispozici nová verze + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Na Sourceforge je k dispozici nová verze qBittorrent. +Přejete si aktualizovat qBittorrent na verzi %1? + + + Impossible to update qBittorrent + Nelze provést aktualizaci qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent se nezdařilo aktualizovat, důvod: %1 + + + UI lock password + Heslo pro zamknutí UI + + + Please type the UI lock password: + Zadejte prosím heslo pro zamknutí UI: + + + Invalid password + Špatné heslo + + + The password is invalid + Heslo není správné + + + Exiting qBittorrent + Ukončování qBittorrent + + + Always + Vždy + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Stahování: %2/s, Nahrávání: %3/s) + + + Torrent Files + Torrent soubory + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Rychlost stahování: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Rychlost nahrávání: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Stahování %1 bylo dokončeno. + + + I/O Error + i.e: Input/Output Error + Chyba I/O + + + Search + Hledat + + + RSS + RSS + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Transfers + Přenosy + + + Set the password... + Nastavit heslo... + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent není výchozí aplikací pro otevírání souborů .torrent ani Magnet odkazů. +Chcete asociovat qBittorrent se soubory .torrent a Magnet odkazů? + + + Download completion + Kompletace stahování + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Došlo k chybě I/O u torrentu %1. + Důvod: %2 + + + Url download error + Chyba stahování URL + + + Couldn't download file at url: %1, reason: %2. + Nelze stáhnout soubor z URL: %1, důvod: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Některé soubory se právě přenášejí. +Opravdu chcete ukončit qBittorrent? + + + Options were saved successfully. + Nastavení bylo úspěšně uloženo. + + + + GeoIP + + Australia + Austrálie + + + Argentina + Argentina + + + Austria + Rakousko + + + United Arab Emirates + Spojené arabské emiráty + + + Brazil + Brazílie + + + Bulgaria + Bulharsko + + + Belarus + Bělorusko + + + Belgium + Belgie + + + Bosnia + Bosna + + + Canada + Kanada + + + Czech Republic + Česká republika + + + China + Čína + + + Costa Rica + Kostarika + + + Switzerland + Švýcarsko + + + Germany + Německo + + + Denmark + Dánsko + + + Algeria + Alžírsko + + + Spain + Španělsko + + + Egypt + Egypt + + + Finland + Finsko + + + France + Francie + + + United Kingdom + Spojené království + + + Greece + Řecko + + + Georgia + Gruzie + + + Hungary + Maďarsko + + + Croatia + Chorvatsko + + + Italy + Itálie + + + India + Indie + + + Israel + Izrael + + + Ireland + Irsko + + + Iceland + Island + + + Indonesia + Indonésie + + + Japan + Japonsko + + + South Korea + Jižní Korea + + + Luxembourg + Lucembursko + + + Malaysia + Malajsie + + + Mexico + Mexiko + + + Serbia + Srbsko + + + Morocco + Maroko + + + Netherlands + Nizozemí + + + Norway + Norsko + + + New Zealand + Nový Zéland + + + Portugal + Portugalsko + + + Poland + Polsko + + + Pakistan + Pákistán + + + Philippines + Filipíny + + + Russia + Rusko + + + Romania + Rumunsko + + + France (Reunion Island) + Francie (Réunion) + + + Saudi Arabia + Saúdská Arábie + + + Sweden + Švédsko + + + Slovakia + Slovensko + + + Singapore + Singapur + + + Slovenia + Slovinsko + + + Taiwan + Taiwan + + + Turkey + Turecko + + + Thailand + Thajsko + + + USA + USA + + + Ukraine + Ukrajina + + + South Africa + Jihoafrická republika + + + + HeadlessLoader + + + Information + Informace + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Pro kontrolu qBittorrentu navštivte webové rozhraní na http://localhost:%1 + + + + The Web UI administrator user name is: %1 + Uživatelské jméno admistrátora webového rozhraní je: %1 + + + + The Web UI administrator password is still the default one: %1 + Heslo administrátora webového rozhraní je stále to výchozí: %1 + + + + This is a security risk, please consider changing your password from program preferences. + To je bezpečnostní riziko, zvažte prosím změnu helsa v nastavení programu. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + Vaše IP adresa byla zablokována kvůli vysokém počtu neúspěšných pokusů o přihlášení. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + S: %1/s - P: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + N: %1/s - P: %2 + + + + HttpServer + + + File + Soubor + + + + Edit + Úpravy + + + + Help + Nápověda + + + Delete from HD + Smazat z pevného disku + + + + Download Torrents from their URL or Magnet link + Stahovat torrenty z jejich URL nebo Magnet odkazu + + + + Only one link per line + Pouze jeden odkaz na řádek + + + + Download local torrent + Stáhnout lokální torrent + + + + Torrent files were correctly added to download list. + Torrent soubory byly úspěšně přidány do seznamu stahování. + + + + Point to torrent file + Odkazovat na torrent soubor + + + + Download + Stahování + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Jste si jist, že chcete smazat vybrané torrenty ze seznamu stahování i pevného disku? + + + + Download rate limit must be greater than 0 or disabled. + Limit stahování musí být větší než 0 nebo vypnut. + + + + Upload rate limit must be greater than 0 or disabled. + Limit nahrávání musí být větší než 0 nebo vypnut. + + + + Maximum number of connections limit must be greater than 0 or disabled. + Maximální počet spojení musí být větší než 0 nebo vypnut. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Maximální počet spojení na torrent musí být větší než 0 nebo vypnut. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Limit maximálního počtu slotů na torrent musí být větší než 0 nebo vypnut. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Nelze uložit nastavení programu, qBittorrent je pravděpodobně nedosažitelný. + + + + Language + Jazyk + + + + Downloaded + Is the file downloaded or not? + Staženo + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Port použitý pro příchozí připojení musí být větší než 1024 a menší než 65535. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Port použitý pro webové rozhraní musí být větší než 1024 a menší než 65535. + + + + The Web UI username must be at least 3 characters long. + Uživatelské jméno pro webové rozhraní musí být nejméně 3 znaky dlouhé. + + + + The Web UI password must be at least 3 characters long. + Heslo pro webové rozhraní musí být nejméně 3 znaky dlouhé. + + + + Save + Uložit + + + + qBittorrent client is not reachable + Klient qBittorrent není dostupný + + + + HTTP Server + HTTP Server + + + + The following parameters are supported: + Podporovány jsou následující parametry: + + + + Torrent path + Cesta k torrentu + + + + Torrent name + Název torrentu + + + + LegalNotice + + + Legal Notice + Právní upozornění + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent je program na sdílení souborů. Spustíte-li torrent, jeho data budou zpřístupněna ostatním ke stažení. Veškerý obsah sdílíte na svou vlastní odpovědnost. + +Další upozornění již nebudou zobrazena. + + + + Press %1 key to accept and continue... + Stisknutím klávesy %1 souhlasíte a pokračujte... + + + + Legal notice + Právní upozornění + + + + Cancel + Zrušit + + + + I Agree + Souhlasím + + + + LineEdit + + + Clear the text + Vymazat text + + + + MainWindow + + + &Edit + Ú&pravy + + + + &Tools + &Nástroje + + + + &File + &Soubor + + + + &Help + Nápo&věda + + + + &View + Po&hled + + + &Add File... + Při&dat soubor... + + + E&xit + U&končit + + + + &Options... + &Možnosti... + + + + &About + O &aplikaci + + + + &Pause + Po&zastavit + + + + &Delete + Smaza&t + + + + P&ause All + Pozastavit vš&e + + + + &Resume + &Obnovit + + + + &Add torrent file... + Př&idat torrent soubor... + + + + + Exit + Ukončit + + + + R&esume All + Obnovit vš&e + + + + Visit &Website + Navštívit &webovou stránku + + + Add &URL... + Přidat &URL... + + + + Torrent &creator + Průvod&ce vytvořením torrentu + + + + Report a &bug + Nahlásit chybu + + + + Set upload limit... + Nastavit limit nahrávání... + + + + Set download limit... + Nastavit limit stahování... + + + + &Documentation + Dokumentace + + + + Set global download limit... + Nastavit celkový limit stahování... + + + + Set global upload limit... + Nastavit celkový limit nahrávání... + + + + Exit qBittorrent + Ukončit qBittorrent + + + + Suspend system + Uspat počítač + + + + Shutdown system + Vypnout počítač + + + + Disabled + Zakázáno + + + &Log viewer... + Prohlížeč záznamů... + + + Log viewer + Prohlížeč záznamů + + + Shutdown computer when downloads complete + Vypnout počítač po dokončení stahování + + + + + Lock qBittorrent + Zamknout qBittorrent + + + + Ctrl+L + Ctrl+L + + + Shutdown qBittorrent when downloads complete + Vypnout qBittorrent po dokončení stahování + + + + Import existing torrent... + Importovat existující torrent... + + + + Import torrent... + Importovat torrent... + + + + Donate money + Přispějte peníze + + + + If you like qBittorrent, please donate! + Máte-li rád qBittorrent, prosím přispějte! + + + + Execution &Log + Záznamy pro&gramu + + + + + Execution Log + Záznamy programu + + + + + Alternative speed limits + Alternativní limity rychlosti + + + + &RSS reader + RSS kanály + + + + Search &engine + Vyhledávač + + + + Top &tool bar + Horní panel nástrojů + + + + Auto-Shutdown on downloads completion + Automatické vypnutí počítače po dokončení stahování + + + + Add &link to torrent... + Přidat odkaz k to&rrentu... + + + + Display top tool bar + Zobrazit horní panel nástrojů + + + + &Speed in title bar + R&ychlost v záhlaví okna + + + + Show transfer speed in title bar + Zobrazit aktuální rychlost v záhlaví okna + + + Preview file + Náhled souboru + + + Clear log + Vyprázdnit záznamy + + + + Decrease priority + Snížit prioritu + + + + Increase priority + Zvýšit prioritu + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + Nastavit heslo... + + + + Transfers + Přenosy + + + + Torrent file association + Asociace souboru .torrent + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent není výchozí aplikací pro otevírání souborů .torrent ani odkazů Magnet. +Chcete asociovat qBittorrent se soubory .torrent a odkazů Magnet? + + + + + + UI lock password + Heslo pro zamknutí UI + + + + + + Please type the UI lock password: + Zadejte prosím heslo pro zamknutí UI: + + + + The password should contain at least 3 characters + Heslo musí obsahovat nejméně 3 znaky + + + + Password update + Změna hesla + + + + The UI lock password has been successfully updated + Heslo zamykající UI bylo úspěšně změněno + + + + RSS + RSS + + + + Search + Hledat + + + + Transfers (%1) + Přenosy (%1) + + + + Download completion + Kompletace stahování + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Stahování %1 bylo dokončeno. + + + + I/O Error + i.e: Input/Output Error + Chyba I/O + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Došlo k chybě I/O u torrentu %1. + Důvod: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Potvrzení rekurzivního stahování + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent %1 obsahuje soubory .torrent, chcete je také začít stahovat? + + + + + Yes + Ano + + + + + No + Ne + + + + Never + Nikdy + + + + Url download error + Chyba stahování URL + + + + Couldn't download file at url: %1, reason: %2. + Nelze stáhnout soubor z URL: %1, důvod: %2. + + + + Global Upload Speed Limit + Celkový limit rychlosti nahrávání + + + + Global Download Speed Limit + Celkový limit rychlosti stahování + + + + + Invalid password + Špatné heslo + + + + The password is invalid + Heslo není správné + + + + Exiting qBittorrent + Ukončování qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Některé soubory se právě přenášejí. +Opravdu chcete ukončit qBittorrent? + + + + Always + Vždy + + + + Open Torrent Files + Otevřít torrent soubory + + + + Torrent Files + Torrent soubory + + + + Options were saved successfully. + Nastavení bylo úspěšně uloženo. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Rychlost stahování: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Rychlost nahrávání: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Stahování: %2/s, Nahrávání: %3/s) + + + + A newer version is available + Je k dispozici nová verze + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Na Sourceforge je k dispozici nová verze qBittorrent. +Přejete si aktualizovat qBittorrent na verzi %1? + + + + Impossible to update qBittorrent + Nelze provést aktualizaci qBittorrent + + + + qBittorrent failed to update, reason: %1 + qBittorrent se nezdařilo aktualizovat, důvod: %1 + + + + PeerAdditionDlg + + + Invalid IP + Neplatná IP + + + + The IP you provided is invalid. + Poskytnutá IP je neplatná. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + IP + + + + Connection + Připojení + + + + Client + i.e.: Client application + Klient + + + + Progress + i.e: % downloaded + Průběh + + + + Down Speed + i.e: Download speed + Rychlost stahování + + + + Up Speed + i.e: Upload speed + Rychlost nahrávání + + + + Downloaded + i.e: total data downloaded + Staženo + + + + Uploaded + i.e: total data uploaded + Nahráno + + + + Add a new peer... + Přidat nový protějšek... + + + + Copy IP + Kopírovat IP + + + + Limit download rate... + Omezit rychlost stahování... + + + + Limit upload rate... + Omezit rychlost nahrávání... + + + + Ban peer permanently + Natrvalo zakázat protějšek + + + + + Peer addition + Přidání protějšku + + + + The peer was added to this torrent. + Protějšek byl přidán do tohoto torrentu. + + + + The peer could not be added to this torrent. + Protějšek nemohl být přidán do tohoto torrentu. + + + + Are you sure? -- qBittorrent + Jste si jist? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Jste si jist, že chcete natrvalo zakázat označené protějšky? + + + + &Yes + &Ano + + + + &No + &Ne + + + + Manually banning peer %1... + Ručně zakázat protějšek %1... + + + + Upload rate limiting + Omezení rychlosti nahrávání + + + + Download rate limiting + Omezení rychlosti stahování + + + + Preferences + + UI + User Interface + Uživ. rozhraní + + + + Downloads + Stahování + + + + Connection + Připojení + + + + Speed + Rychlost + + + Bittorrent + Bittorrent + + + Proxy + Proxy + + + + Web UI + Webové rozhraní + + + + Advanced + Pokročilé + + + Language: + Jazyk: + + + + (Requires restart) + (Vyžaduje restart) + + + Visual style: + Nastavení vzhledu: + + + Transfer list + Seznam přenosů + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Použít střídající se barvu řádků + + + + + Start / Stop Torrent + Spustit / Zastavit torrent + + + + + No action + Žádná činnost + + + File system + Souborový systém + + + + Copy .torrent files to: + Kopírovat soubory .torrent do: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Podporovány jsou následující parametry: +<ul> +<li>%f: Cesta k torrentu</li> +<li>%n: Název torrentu</li> +</ul> + + + Torrent queueing + Řazení torrentů do fronty + + + + Maximum active downloads: + Max. počet aktivních stahování: + + + + Maximum active uploads: + Max. počet aktivních nahrávání: + + + + Maximum active torrents: + Maximální počet aktivních torrentů: + + + + When adding a torrent + Při přidání torrentu + + + + + Options + Možnosti + + + Visual Appearance + Vzhled + + + + Action on double-click + Akce po dvojitém kliknutí + + + + Downloading torrents: + Stahování torrentů: + + + Start / Stop + Start / Stop + + + + + Open destination folder + Otevřít cílový adresář + + + + Completed torrents: + Dokončené torrenty: + + + + Desktop + Plocha + + + + Show splash screen on start up + Při startu zobrazovat úvodní obrazovku + + + + Start qBittorrent minimized + Spustit qBittorrent minimalizovaný + + + Show qBittorrent icon in notification area + Zobrazovat ikonu qBittorrent v oznamovací oblasti (tray) + + + Use monochrome system tray icon (requires restart) + Použít černobílou ikonu v oznamovací oblasti (vyžaduje restart) + + + + Minimize qBittorrent to notification area + Minimalizovat qBittorrent do oznamovací oblasti (tray) + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Zavírat qBittorrent do oznamovací oblasti (tray) + + + + Tray icon style: + Styl ikony v oznamovací oblasti: + + + + Normal + Normální + + + + Monochrome (Dark theme) + Monochromatický (Tmavý motiv) + + + + Monochrome (Light theme) + Monochromatický (Světlý motiv) + + + + Ask for program exit confirmation + Vyžadovat potvrzení při ukončení programu + + + + User Interface Language: + Jazyk uživatelského rozhraní: + + + + Transfer List + Seznam přenosů + + + + Show qBittorrent in notification area + Zobrazovat qBittorrent v oznamovací oblasti + + + + Power Management + Správa napájení + + + + Inhibit system sleep when torrents are active + Zakázat uspání počítače existují-li aktivní torrenty + + + + Display torrent content and some options + Zobrazit obsah torrentu a některé volby + + + + Do not start the download automatically + The torrent will be added to download list in pause state + Nespouštět stahování automaticky + + + + Hard Disk + Pevný disk + + + + Save files to location: + Ukládat soubory do umístění: + + + + Append the label of the torrent to the save path + Připojit štítek torrentu do cesty pro uložení + + + + Pre-allocate disk space for all files + Dopředu přidělit místo všem souborům + + + + Keep incomplete torrents in: + Uchovat neúplné torrenty v: + + + Append .!qB extension to incomplete files' names + Připojit příponu .!qB k nedokončeným souborům + + + + Automatically add torrents from: + Automaticky přidávat .torrent soubory z: + + + + Add folder... + Přidat adresář ... + + + + Email notification upon download completion + Oznámení emailem po dokončení stahování + + + + Destination email: + Email: + + + + SMTP server: + Server SMTP: + + + + This server requires a secure connection (SSL) + Tento server vyžaduje zabezpečené připojení (SSL) + + + + Run an external program on torrent completion + Po dokončení torrentu spustit externí program + + + + Otherwise, the proxy server is only used for tracker connections + V opačném případě je proxy server použit pouze pro připojení k trackeru + + + + Use proxy for peer connections + Použít proxy pro připojení k protějškům + + + + Global Rate Limits + Celkové limity rychlosti + + + + Apply rate limit to uTP connections + Použít omezení rychlosti pro uTP připojení + + + + Apply rate limit to transport overhead + Použít limity rychlosti pro režijní provoz + + + + Alternative Global Rate Limits + Alternativní celkové limity rychlosti + + + + Schedule the use of alternative rate limits + Načasovat použití alternativních limitů rychlosti + + + + Use HTTPS instead of HTTP + Použít HTTPS místo HTTP + + + + Import SSL Certificate + Importovat SSL certifikát + + + + Import SSL Key + Importovat SSL klíč + + + + Certificate: + Certifikát: + + + + Key: + Klíč: + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Informace o certifikátech</a> + + + + Update my dynamic domain name + Aktualizovat moje dynamické doménové jméno + + + + Service: + Služba: + + + + Register + Registrovat + + + + Domain name: + Doménové jméno: + + + Use %f to pass the torrent path in parameters + Použijte %f pro zadání cesty k torrentu v parametrech + + + + Use UPnP / NAT-PMP port forwarding from my router + Použít přesměrování portů UPnP / NAT-PMP + + + Proxy server + Proxy server + + + + Reload the filter + Obnovit filtr + + + + Enable bandwidth management (uTP) + Zapnout řízení šířky pásma (uTP) + + + + Privacy + Soukromí + + + + Enable DHT (decentralized network) to find more peers + Zapnout DHT síť (decentralizovaná síť) k nalezení většího počtu protějšků + + + + Use a different port for DHT and BitTorrent + Použít jiný port pro DHT a bittorrent + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Vyměňovat protějšky s kompatibilními klienty Bittorrent (µTorrent, Vuze, ...) + + + + Enable Peer Exchange (PeX) to find more peers + Zapnout Peer Exchange (PeX) k nalezení většího počtu protějšků + + + + Enable Local Peer Discovery to find more peers + Zapnout Local Peer Discovery k nalezení většího počtu protějšků + + + + Encryption mode: + Režim šifrování: + + + + Prefer encryption + Upřednostňovat šifrování + + + + Require encryption + Vyžadovat šifrování + + + + Disable encryption + Zakázat šifrování + + + Share ratio limiting + Omezení poměru sdílení + + + + Seed torrents until their ratio reaches + Sdílet torrenty dokud poměr sdílení nedosáhne + + + + then + potom + + + + Pause them + Pozastavit je + + + + Remove them + Odstranit je + + + + Enable Web User Interface (Remote control) + Zapnout webové rozhraní (dálkové ovládání) + + + + Use UPnP / NAT-PMP to forward the port from my router + Použít UPnP / NAT-PMP k přesměrování portu z mého routeru + + + + Bypass authentication for localhost + Přeskočit přihlášení pro místní připojení + + + Listening port + Naslouchat na portu + + + + Port used for incoming connections: + Port použitý pro příchozí spojení: + + + + Random + Náhodný + + + Enable UPnP port mapping + Zapnout mapování portů UPnP + + + Enable NAT-PMP port mapping + Zapnout mapování portů NAT-PMP + + + Connections limit + Limit připojení + + + + Global maximum number of connections: + Celkový maximální počet připojení: + + + + Maximum number of connections per torrent: + Maximální počet spojení na torrent: + + + + Maximum number of upload slots per torrent: + Maximální počet slotů pro nahrávání na torrent: + + + + + Upload: + Nahrávání: + + + + + Download: + Stahování: + + + + + + + KiB/s + KiB/s + + + User Interface + Uživatelské rozhraní + + + + BitTorrent + BitTorrent + + + Global speed limits + Celkové limity rychlosti + + + Alternative global speed limits + Alternativní celkové limity rychlosti + + + + to + time1 to time2 + do + + + + Every day + Každý den + + + + Week days + Pracovní dny + + + + Week ends + Víkend + + + Bittorrent features + Vlastnosti bittorrentu + + + Enable DHT network (decentralized) + Zapnout DHT síť (decentralizovaná) + + + Use a different port for DHT and Bittorrent + Použít jiný port pro DHT a bittorrent + + + + DHT port: + Port DHT: + + + Enable Peer Exchange / PeX (requires restart) + Zapnout Peer eXchange / PeX (vyžaduje restart) + + + Enable Local Peer Discovery + Zapnout Local Peer Discovery + + + Enabled + Zapnuto + + + Forced + Vynuceno + + + Disabled + Vypnuto + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP komunikace (trackery, web seedy, vyhledávač) + + + + Host: + Host: + + + Peer Communications + Komunikace protějšků + + + + SOCKS4 + SOCKS4 + + + + Type: + Typ: + + + + + Behavior + Chování + + + + Language + Jazyk + + + + Append .!qB extension to incomplete files + Přidat příponu .!qB k nedokončeným souborům + + + + Remove folder + Odstranit adresář + + + + Listening Port + Naslouchat na portu + + + + Connections Limits + Limit připojení + + + + Proxy Server + Proxy server + + + + IP Filtering + Filtrování IP + + + Schedule the use of alternative speed limits + Načasovat použití alternativních limitů rychlosti + + + + from + from (time1 to time2) + od + + + + When: + Kdy: + + + + Look for peers on your local network + Hledat protějšky na lokální síti + + + Protocol encryption: + Šifrování protokolu: + + + + (None) + (žádný) + + + + HTTP + HTTP + + + + + Port: + Port: + + + + + + Authentication + Ověření + + + + + + + Username: + Uživatelské jméno: + + + + + + + Password: + Heslo: + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + Cesta k filtru (.dat, .p2p, .p2b): + + + + Torrent Queueing + Řazení torrentů do fronty + + + + Share Ratio Limiting + Omezení poměru sdílení + + + HTTP Server + HTTP Server + + + + PreviewSelect + + + Name + Název + + + + Size + Velikost + + + + Progress + Průběh + + + + + + Preview impossible + Náhled není možný + + + + + + Sorry, we can't preview this file + Je nám líto, nelze zobrazit náhled tohoto souboru + + + + ProgramUpdater + + Could not create the file %1 + Nelze vytvořit soubor %1 + + + Failed to download the update at %1 + %1 is an URL + Selhalo stažení aktualizace z %1 + + + + PropListDelegate + + + Not downloaded + Nestaženo + + + + + Normal + Normal (priority) + Normální + + + + + High + High (priority) + Vysoká + + + + Mixed + Mixed (priorities + Mix + + + + + Maximum + Maximum (priority) + Maximální + + + + PropTabBar + + + General + Obecné + + + + Trackers + Trackery + + + + Peers + Protějšky + + + + HTTP Sources + HTTP zdroje + + + + Content + Obsah + + + URL Seeds + URL seedy + + + Files + Soubory + + + + PropertiesWidget + + + Save path: + Uložit do: + + + + Torrent hash: + Kontrolní součet (hash) torrentu: + + + + Comment: + Komentář: + + + + Share ratio: + Poměr sdílení: + + + + + Downloaded: + Staženo: + + + + Availability: + Dostupnost: + + + + Transfer + Přenos + + + + Uploaded: + Nahráno: + + + + Wasted: + Zahozeno: + + + + Time active: + Time (duration) the torrent is active (not paused) + Aktivní po dobu: + + + + Pieces size: + Velikost částí: + + + + Torrent content: + Obsah torrentu: + + + + Select All + Vybrat vše + + + + Select None + Zrušit výběr + + + + + Do not download + Nestahovat + + + + UP limit: + Limit nahrávání: + + + + DL limit: + Limit stahování: + + + Time elapsed: + Uplynulý čas: + + + + Connections: + Připojení: + + + + Reannounce in: + Znovu-oznámit za: + + + + Information + Informace + + + + Created on: + Vytvořeno: + + + General + Obecné + + + Trackers + Trackery + + + Peers + Protějšky + + + URL seeds + URL seedy + + + Files + Soubory + + + + Priority + Priorita + + + + Normal + Normální + + + + Maximum + Maximální + + + + High + Vysoká + + + + + this session + tato relace + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Sdíleno %1 + + + + %1 max + e.g. 10 max + + + + + + I/O Error + Chyba I/O + + + + This file does not exist yet. + Tento soubor dosud neexistuje. + + + + This folder does not exist yet. + Tento adresář dosud neexistuje. + + + + Rename... + Přejmenovat... + + + + Rename the file + Přejmenovat soubor + + + + New name: + Nový název: + + + + + The file could not be renamed + Soubor nelze přejmenovat + + + + This file name contains forbidden characters, please choose a different one. + Název souboru obsahuje nepovolené znaky, zvolte prosím jiný. + + + + + This name is already in use in this folder. Please use a different name. + Tento název je již v tomto adresáři použit. Vyberte prosím jiný. název. + + + + The folder could not be renamed + Adresář nelze přejmenovat + + + + New url seed + New HTTP source + Nový URL seed + + + + New url seed: + Nový URL seed: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Tento URL seed už v seznamu existuje. + + + + + Choose save path + Vyberte cestu pro uložení + + + Save path creation error + Chyba při vytváření cesty pro uložení + + + Could not create the save path + Nemohu vytvořit cestu pro uložení + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 dosáhl maximálního nastaveného poměru sdílení. + + + + Removing torrent %1... + Odstraňování torrentu %1... + + + + Pausing torrent %1... + Pozastavování torrentu %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent naslouchá na portu: TCP/%1 + + + UPnP support [ON] + Podpora UPnP [ZAP] + + + UPnP support [OFF] + Podpora UPnP [VYP] + + + NAT-PMP support [ON] + Podpora NAT-PMP [ZAP] + + + NAT-PMP support [OFF] + Podpora NAT-PMP [VYP] + + + + HTTP user agent is %1 + HTTP user agent je %1 + + + Using a disk cache size of %1 MiB + Použita vyrovnávací paměť o velikosti %1 MiB + + + + DHT support [ON], port: UDP/%1 + Podpora DHT [ZAP], port: UDP/%1 + + + + + DHT support [OFF] + Podpora DHT [VYP] + + + + PeX support [ON] + Podpora PeX [ZAP] + + + + PeX support [OFF] + Podpora PeX [VYP] + + + + Restart is required to toggle PeX support + Kvůli přepnutí podpory PEX je nutný restart + + + Local Peer Discovery [ON] + Local Peer Discovery [ZAP] + + + + Local Peer Discovery support [OFF] + Podpora Local Peer Discovery [VYP] + + + + Encryption support [ON] + Podpora šifrování [ZAP] + + + + Encryption support [FORCED] + Podpora šifrování [VYNUCENO] + + + + Encryption support [OFF] + Podpora šifrování [VYP] + + + + Embedded Tracker [ON] + Vestavěný tracker [ZAP] + + + + Failed to start the embedded tracker! + Start vestavěného trackeru selhal! + + + + Embedded Tracker [OFF] + Vestavěný tracker [VYP] + + + + The Web UI is listening on port %1 + Webové rozhraní naslouchá na portu %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Chyba webového rozhraní - Nelze se připojit k Web UI na port %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' byl odstraněn ze seznamu i z pevného disku. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' byl odstraněn ze seznamu přenosů. + + + + '%1' is not a valid magnet URI. + '%1' není platný magnet URI. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' už je v seznamu stahování. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' obnoven. (rychlé obnovení) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' přidán do seznamu stahování. + + + + UPnP / NAT-PMP support [ON] + Podpora UPnP / NAT-PMP [ZAP] + + + + UPnP / NAT-PMP support [OFF] + Podpora UPnP / NAT-PMP [VYP] + + + + Reporting IP address %1 to trackers... + Ohlašuji IP adresu %1 trackerům... + + + + Local Peer Discovery support [ON] + Podpora Local Peer Discovery [ZAP] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Nelze dekódovat soubor torrentu: '%1' + + + + This file is either corrupted or this isn't a torrent. + Tento soubor je buď poškozen, nebo to není soubor torrentu. + + + + Error: The torrent %1 does not contain any file. + Chyba: Torrent %1 neobsahuje žádný soubor. + + + + Note: new trackers were added to the existing torrent. + Poznámka: ke stávajícímu torrentu byly přidány nové trackery. + + + + Note: new URL seeds were added to the existing torrent. + Poznámka: ke stávajícímu torrentu byly přidány nové URL seedy. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>byl zablokován kvůli filtru IP</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>byl zakázán kvůli poškozeným částem</i> + + + + The network interface defined is invalid: %1 + Nastavené síťové rozhraní je neplatné: %1 + + + + Trying any other network interface available instead. + Zkouším jakékoli další dostupné síťové rozhraní. + + + + Listening on IP address %1 on network interface %2... + Naslouchám na IP adrese %1 a síťovém rozhraní %2... + + + + Failed to listen on network interface %1 + Selhalo naslouchání na síťovém rozhraní %1 + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekurzivní stahování souboru %1 vloženého v torrentu %2 + + + + + Unable to decode %1 torrent file. + Nelze dekódovat soubor torrentu %1. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Nezrušíte-li akci do 15 sekund, počítač přejde do režimu spánku... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Nezrušíte-li akci do 15 sekund, počítač bude vypnut... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + Nezrušíte-li akci do 15 sekund, qBittorrent bude ukončen... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Poskytnutý IP filtr byl úspěšně zpracován. Počet aplikovaných pravidel: %1 + + + + Error: Failed to parse the provided IP filter. + Chyba: Nepovedlo se zpracovat poskytnutý IP filtr. + + + + Torrent name: %1 + Název torrentu: %1 + + + + Torrent size: %1 + Velikost torrentu: %1 + + + + Save path: %1 + Cesta pro uložení: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent byl stažen za %1. + + + + Thank you for using qBittorrent. + Děkujeme za používání qBittorrentu. + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] bylo dokončeno stahování %1 + + + + An I/O error occured, '%1' paused. + Došlo k chybě I/O, '%1' je pozastaven. + + + + + Reason: %1 + Důvod: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Namapování portů selhalo, zpráva: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Namapování portů bylo úspěšné, zpráva: %1 + + + + File sizes mismatch for torrent %1, pausing it. + Nesouhlasí velikost souborů u torrentu %1, pozastaveno. + + + + Fast resume data was rejected for torrent %1, checking again... + Rychlé obnovení torrentu %1 bylo odmítnuto, zkouším znovu... + + + + Url seed lookup failed for url: %1, message: %2 + Vyhledání URL seedu selhalo pro URL: %1, zpráva: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Stahuji '%1', prosím čekejte... + + + + RSS + + + Search + Hledat + + + + New subscription + Nové přihlášení k odběru + + + + + + Mark items read + Označit jako přečtené + + + + Update all + Aktualizovat vše + + + + RSS Downloader... + Stahování z RSS... + + + + Settings... + Nastavení... + + + RSS feed downloader... + Stahování z RSS kanálů... + + + + New folder... + Nový adresář... + + + + Manage cookies... + Nastavení cookies... + + + Feed URL + URL kanálu + + + + Rename... + Přejmenovat... + + + + + Update + Aktualizovat + + + RSS feeds + RSS kanály + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrenty:</span> <span style=" font-style:italic;">(dvojité kliknutí pro stažení)</span></p></body></html> + + + Article title + Název položky + + + + New subscription... + Nové přihlášení k odběru... + + + + + Update all feeds + Aktualizovat všechny kanály + + + + + Delete + Smazat + + + + Rename + Přejmenovat + + + + Download torrent + Stáhnout torrent + + + + Open news URL + Otevřít URL s novinkami + + + + Copy feed URL + Kopírovat URL kanálu + + + + Refresh RSS streams + Obnovit RSS kanály + + + + RSSImp + + + Please type a rss stream url + Prosím napište URL RSS kanálu + + + + Stream URL: + URL kanálu: + + + + + Are you sure? -- qBittorrent + Jste si jist? -- qBittorrent + + + + + &Yes + &Ano + + + + + &No + &Ne + + + + Please choose a folder name + Prosím vyberte název adresáře + + + + Folder name: + Název adresáře: + + + + New folder + Nový adresář + + + + Overwrite attempt + Pokus o přepsání + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Nelze přepsat %1. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Tento RSS kanál už v seznamu existuje. + + + + Are you sure you want to delete these elements from the list? + Jste si jist, že chcete smazat tyto prvky ze seznamu? + + + + Are you sure you want to delete this element from the list? + Jste si jist, že chcete smazat tento prvek ze seznamu? + + + + Please choose a new name for this RSS feed + Prosím vyberte nový název pro tento RSS kanál + + + + New feed name: + Název nového kanálu: + + + + Name already in use + Název je již používán + + + + This name is already used by another item, please choose another one. + Tento název již používá jiná položka, vyberte prosím jiný. + + + + Date: + Datum: + + + + Author: + Autor: + + + + Unread + Nepřečtené + + + + RssArticle + + No description available + Popis není k dispozici + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Automaticky stahovat %1 torrent z %2 RSS kanálu... + + + + RssItem + + No description available + Popis není k dispozici + + + + RssSettings + + RSS Reader Settings + Nastavení RSS čtečky + + + RSS feeds refresh interval: + Interval obnovování RSS kanálů: + + + minutes + minut + + + Maximum number of articles per feed: + Maximální počet článků na kanál: + + + + RssSettingsDlg + + + RSS Reader Settings + Nastavení RSS čtečky + + + + RSS feeds refresh interval: + Interval obnovování RSS kanálů: + + + + minutes + minut + + + + Maximum number of articles per feed: + Maximální počet článků na kanál: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Automaticky stahovat %1 torrent z %2 RSS kanálu... + + + + ScanFoldersModel + + + Watched Folder + Sledovaný adresář + + + + Download here + Stáhnout zde + + + + SearchCategories + + + All categories + Všechny kategorie + + + + Movies + Filmy + + + + TV shows + TV seriály + + + + Music + Hudba + + + + Games + Hry + + + + Anime + Anime + + + + Software + Software + + + + Pictures + Obrázky + + + + Books + Knihy + + + + SearchEngine + + + Cut + Vyjmout + + + + Copy + Kopírovat + + + + Paste + Vložit + + + + Clear field + Vyprázdnit pole + + + + Clear completion history + Vymazat historii + + + + Confirmation + Potvrzení + + + + Are you sure you want to clear the history? + Jste si jist, že chcete smazat historii? + + + + + + Search + Hledat + + + + Missing Python Interpreter + Chybí překladač jazyka Python + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Pro použití funkce hledání je vyžadován Python 2.x, ten ale není nainstalován. +Chcete jej nyní nainstalovat? + + + + Empty search pattern + Prázdný hledaný řetězec + + + + Please type a search pattern first + Nejdříve prosím napište hledaný řetězec + + + + + Results + Výsledky + + + + Searching... + Hledám... + + + + Search Engine + Vyhledávač + + + + + Search has finished + Hledání ukončeno + + + + An error occured during search... + Během hledání nastala chyba... + + + + + Search aborted + Hledání přerušeno + + + + Download error + Chyba stahování + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Instalační soubor Pyhon nelze stáhnout, důvod: %1. +Nainstalujte jej prosím ručně. + + + + Search returned no results + Nebyly nalezeny žádné výsledky + + + + Results + i.e: Search results + Výsledky + + + + + Unknown + Neznámý + + + + SearchTab + + + Name + i.e: file name + Název + + + + Size + i.e: file size + Velikost + + + + Seeders + i.e: Number of full sources + Seedeři + + + + Leechers + i.e: Number of partial sources + Leecheři + + + + Search engine + Vyhledávač + + + + ShutdownConfirmDlg + + + Shutdown confirmation + Potvrdit vypnutí + + + + SpeedLimitDialog + + + KiB/s + KiB/s + + + + StatusBar + + + + Connection status: + Stav připojení: + + + + + No direct connections. This may indicate network configuration problems. + Žádná přímá spojení. To může značit problémy s nastavením sítě. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + S: %1 B/s - P: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + N: %1 B/s - P: %2 + + + + + DHT: %1 nodes + DHT: %1 uzlů + + + + qBittorrent needs to be restarted + Je nutné restartartovat qBittorrent + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent byl právě aktualizován a kvůli provedení změn je nutné jej restartovat. + + + + + Connection Status: + Stav připojení: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Offline. To obvykle znamená, že qBittorrent nedokázal naslouchat na portu nastaveném pro příchozí spojení. + + + + Online + Online + + + + + %1/s + Per second + %1/s + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + S: %1/s - P: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + N: %1/s - P: %2 + + + + Click to switch to alternative speed limits + Kliknutí přepne na alternativní limity rychlosti + + + + Click to switch to regular speed limits + Kliknutí přepne na normální limity rychlosti + + + Click to disable alternative speed limits + Kliknutí vypne alternativní limity rychlosti + + + Click to enable alternative speed limits + Kliknutí zapne alternativní limity rychlosti + + + + Global Download Speed Limit + Celkový limit rychlosti stahování + + + + Global Upload Speed Limit + Celkový limit rychlosti nahrávání + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Vyberte adresář pro přidání do torrentu + + + + Select a file to add to the torrent + Vyberte soubor pro přidání do torrentu + + + Please type an announce URL + Prosím napište oznamovací URL + + + Announce URL: + Tracker URL + Oznamovací URL: + + + Please type a web seed url + Prosím napište URL webových seedů + + + Web seed URL: + URL webových seedů: + + + + No input path set + Nebyla zadána vstupní cesta + + + + Please type an input path first + Nejdříve prosím zadejte vstupní cestu + + + + Select destination torrent file + Vybrat cílový torrent soubor + + + + Torrent Files + Torrent soubory + + + + + + Torrent creation + Vytvoření torrentu + + + + Torrent creation was unsuccessful, reason: %1 + Vytvoření torrentu selhalo, důvod: %1 + + + + Created torrent file is invalid. It won't be added to download list. + Vytvořený torrent soubor je špatný. Nebude přidán do seznamu stahování. + + + + Torrent was created successfully: + Torrent byl úspěšně vytvořen: + + + + TorrentFilesModel + + + Name + Název + + + + Size + Velikost + + + + Progress + Průběh + + + + Priority + Priorita + + + + TorrentImportDlg + + + Torrent Import + Import torrent + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Tento průvodce Vám pomůže s importem torrentu staženého jiným programem. + + + + Torrent file to import: + Soubor torrentu k importu: + + + + + ... + ... + + + + Content location: + Umístění obsahu: + + + + Skip the data checking stage and start seeding immediately + Přeskočit fázi kontroly dat a začít sdílet okamžitě + + + + Import + Import + + + + Torrent file to import + Soubor torrentu k importu + + + + Torrent files (*.torrent) + Soubory torrent (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 soubory + + + + Please provide the location of %1 + %1 is a file name + Zadejte umístění souboru %1 + + + + Please point to the location of the torrent: %1 + Odkažte na umístění torrentu: %1 + + + + Invalid torrent file + Neplatný soubor torrentu + + + + This is not a valid torrent file. + Toto není platný soubor torrent. + + + + TorrentModel + + + Name + i.e: torrent name + Název + + + + Size + i.e: torrent size + Velikost + + + + Done + % Done + Hotovo + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + + Seeds + i.e. full sources (often untranslated) + Seedy + + + + Peers + i.e. partial sources (often untranslated) + Protějšky + + + + Down Speed + i.e: Download speed + Rychlost stahování + + + + Up Speed + i.e: Upload speed + Rychlost nahrávání + + + + Ratio + Share ratio + Poměr + + + + ETA + i.e: Estimated Time of Arrival / Time left + Odh. čas + + + + Label + Štítek + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Přidán + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Dokončen + + + + Tracker + Tracker + + + + Down Limit + i.e: Download limit + Limit stahování + + + + Up Limit + i.e: Upload limit + Limit nahrávání + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Stažené množství + + + + Amount left + Amount of data left to download (e.g. in MB) + Zbývající množství + + + + Time Active + Time (duration) the torrent is active (not paused) + Aktivní po dobu + + + + TrackerList + + + URL + URL + + + + Status + Status + + + + Peers + Protějšky + + + + Message + Zpráva + + + + [DHT] + [DHT] + + + + [PeX] + [PeX] + + + + [LSD] + [LSD] + + + + + + + + Working + Funkční + + + + + + Disabled + Vypnuto + + + + This torrent is private + Tento torrent je soukromý + + + + Updating... + Aktualizuji... + + + + + Not working + Nefunkční + + + + + Not contacted yet + Dosud nekontaktován + + + + Add a new tracker... + Přidat nový tracker... + + + + Remove tracker + Odstranit tracker + + + + Force reannounce + Vynutit znovu-oznámení + + + + TrackersAdditionDlg + + + Trackers addition dialog + Dialog pro přidání torrentu + + + + List of trackers to add (one per line): + Seznam trackerů pro přidání (jeden na řádek): + + + + µTorrent compatible list URL: + Seznam URL kompatibilní s µTorrent: + + + + I/O Error + Chyba I/O + + + + Error while trying to open the downloaded file. + Chyba při pokusu o otevření staženého souboru. + + + + No change + Žádná změna + + + + No additional trackers were found. + Nebyly nalezeny žádné další trackery. + + + + Download error + Chyba stahování + + + + The trackers list could not be downloaded, reason: %1 + Seznam trackerů nemohl být stažen, důvod: %1 + + + + TransferListDelegate + + + Downloading + Stahuji + + + + Paused + Pozastaveno + + + + Queued + i.e. torrent is queued + Zařazeno do fronty + + + + Seeding + Torrent is complete and in upload-only mode + Sdílím + + + + Stalled + Torrent is waiting for download to begin + Zastaveno + + + + Checking + Torrent local data is being checked + Kontroluji + + + + /s + /second (.i.e per second) + /s + + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Sdíleno %1 + + + + TransferListFiltersWidget + + + + All + Vše + + + + + Downloading + Stahováno + + + + + Completed + Dokončeno + + + + + Paused + Pozastaveno + + + + + Active + Aktivní + + + + + Inactive + Neaktivní + + + + + All labels + Všechny štítky + + + + + Unlabeled + Neoznačené + + + + Remove label + Odstranit štítek + + + + Add label... + Přidat štítek... + + + + Resume torrents + Obnovit torrenty + + + + Pause torrents + Pozastavit torrenty + + + + Delete torrents + Smazat torrenty + + + + New Label + Nový štítek + + + + Label: + Štítek: + + + + Invalid label name + Neplatný název štítku + + + + Please don't use any special characters in the label name. + Nepoužívejte prosím v názvu štítku žádné speciální znaky. + + + + TransferListWidget + + Down Speed + i.e: Download speed + Rychlost stahování + + + Up Speed + i.e: Upload speed + Rychlost nahrávání + + + ETA + i.e: Estimated Time of Arrival / Time left + Odh. čas + + + + Column visibility + Zobrazení sloupců + + + Name + i.e: torrent name + Název + + + Size + i.e: torrent size + Velikost + + + Done + % Done + Hotovo + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + Seeds + i.e. full sources (often untranslated) + Seedy + + + Peers + i.e. partial sources (often untranslated) + Protějšky + + + Ratio + Share ratio + Poměr + + + + Label + Štítek + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Přidán + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Dokončen + + + Down Limit + i.e: Download limit + Limit stahování + + + Up Limit + i.e: Upload limit + Limit nahrávání + + + + Choose save path + Vyberte cestu pro uložení + + + Save path creation error + Chyba při vytváření cesty pro uložení + + + Could not create the save path + Nemohu vytvořit cestu pro uložení + + + + Torrent Download Speed Limiting + Limit rychlosti stahování torrentu + + + + Torrent Upload Speed Limiting + Limit rychlosti nahrávání torrentu + + + + New Label + Nový štítek + + + + Label: + Štítek: + + + + Invalid label name + Neplatný název štítku + + + + Please don't use any special characters in the label name. + Nepoužívejte prosím v názvu štítku žádné speciální znaky. + + + + Rename + Přejmenovat + + + + New name: + Nový název: + + + + Resume + Resume/start the torrent + Obnovit + + + + Pause + Pause the torrent + Pozastavit + + + + Delete + Delete the torrent + Smazat + + + + Preview file... + Náhled souboru... + + + + Limit share ratio... + Omezit poměr sdílení... + + + + Limit upload rate... + Omezit rychlost nahrávání... + + + + Limit download rate... + Omezit rychlost stahování... + + + + Priority + Priorita + + + + Open destination folder + Otevřít cílový adresář + + + + Move up + i.e. move up in the queue + Přesunout nahoru + + + + Move down + i.e. Move down in the queue + Přesunout dolů + + + + Move to top + i.e. Move to top of the queue + Přesunout navrch + + + + Move to bottom + i.e. Move to bottom of the queue + Přesunout dospodu + + + + Set location... + Nastavit umístění... + + + + Force recheck + Překontrolovat platnost + + + + Copy magnet link + Kopírovat odkaz Magnet + + + + Super seeding mode + Super seeding mód + + + + Rename... + Přejmenovat... + + + + Download in sequential order + Stahovat v souvislém pořadí + + + + Download first and last piece first + Stáhnout nejdříve první a poslední část + + + + New... + New label... + Nový... + + + + Reset + Reset label + Reset + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Omezení poměru nahrávání/stahování torrentu + + + + Use global ratio limit + Použít globální omezení poměru + + + + + + buttonGroup + + + + + Set no ratio limit + Nastavit poměr bez omezení + + + + Set ratio limit to + Nastavit omezení poměru na + + + + UsageDisplay + + + Usage: + Použití: + + + + displays program version + zobrazí verzi programu + + + + disable splash screen + zakáže úvodní obrazovku + + + + displays this help message + zobrazí tuto zprávu + + + + changes the webui port (current: %1) + změní port webového rozhraní (nyní: %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [soubory nebo url]: stahovat torrenty poskytnuté uživatelem (volitelné) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Chtěl bych poděkovat následujícím lidem, kteří dobrovolně přeložili qBittorrent: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Kontaktujte mě, prosím, pokud byste chtěli přeložit qBittorrent do svého jazyka. + + + + addPeerDialog + + + Peer addition + Přidání protějšku + + + + IP + IP + + + + Port + Port + + + + addTorrentDialog + + + Torrent addition dialog + Dialog pro přidání torrentu + + + + Save path: + Uložit do: + + + + ... + ... + + + + Torrent size: + Velikost torrentu: + + + + + Unknown + Neznámý + + + + Free disk space: + Volné místo na disku: + + + + Label: + Štítek: + + + + Torrent content: + Obsah torrentu: + + + + Select All + Vybrat vše + + + + Select None + Zrušit výběr + + + + Download in sequential order (slower but good for previewing) + Stahovat v sekvenčním pořadí (pomalejší, ale dobré pro náhled) + + + + Skip file checking and start seeding immediately + Přeskočit kontrolu souboru a začít sdílet okamžitě + + + + + Do not download + Nestahovat + + + + Add to download list in paused state + Přidat do seznamu stahování jako pozastavené + + + + Add + Přidat + + + + Cancel + Zrušit + + + + Normal + Normální + + + + High + Vysoká + + + + Maximum + Maximální + + + + authentication + + + + Tracker authentication + Tracker - ověření + + + + Tracker: + Tracker: + + + + Login + Přihlášení + + + + Username: + Uživatelské jméno: + + + + Password: + Heslo: + + + + Log in + Přihlásit se + + + + Cancel + Zrušit + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Potvrzení o smazání - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Jste si jist, že chcete smazat vybrané torrenty ze seznamu přenosů? + + + + Remember choice + Zapamatovat volbu + + + + Also delete the files on the hard disk + Smazat soubory také z pevného disku + + + + createTorrentDialog + + + Cancel + Zrušit + + + + Torrent Creation Tool + Nástroj pro vytváření torrentů + + + + Torrent file creation + Vytvořit soubor torrentu + + + + Add file + Přidat soubor + + + + Add folder + Přidat adresář + + + Announce urls (trackers): + Oznamovací URL (trackery): + + + Comment (optional): + Komentář (nepovinné): + + + Web seeds urls (optional): + URL webových seedů (nepovinné): + + + + File or folder to add to the torrent: + Soubor nebo adresář pro přidání do torrentu: + + + + Tracker URLs: + URL trackeru: + + + + Web seeds urls: + URL webových seedů: + + + + Comment: + Komentář: + + + + Piece size: + Velikost části: + + + + 32 KiB + 32 KiB + + + + 64 KiB + 64 KiB + + + + 128 KiB + 128 KiB + + + + 256 KiB + 256 KiB + + + + 512 KiB + 512 KiB + + + + 1 MiB + 1 MiB + + + + 2 MiB + 2 MiB + + + + 4 MiB + 4 MiB + + + + Auto + Auto + + + + Private (won't be distributed on DHT network if enabled) + Soukromý (je-li zapnuto, nebude šířen na síti DHT) + + + + Start seeding after creation + Po vytvoření začít seedovat + + + + Create and save... + Vytvořit a uložit... + + + + Progress: + Průběh: + + + + createtorrent + + Select destination torrent file + Vybrat cílový torrent soubor + + + Torrent Files + Torrent soubory + + + No input path set + Nebyla zadaná vstupní cesta + + + Please type an input path first + Nejdříve prosím zadejte vstupní cestu + + + Torrent creation + Vytvoření torrentu + + + Torrent was created successfully: + Torrent byl úspěšně vytvořen: + + + Select a folder to add to the torrent + Vyberte adresář pro přidání do torrentu + + + Please type an announce URL + Prosím napište oznamovací URL + + + Torrent creation was unsuccessful, reason: %1 + Vytvoření torrentu selhalo, důvod: %1 + + + Announce URL: + Tracker URL + Oznamovací URL: + + + Please type a web seed url + Prosím napište URL webových seedů + + + Web seed URL: + URL webových seedů: + + + Select a file to add to the torrent + Vyberte soubor pro přidání do torrentu + + + Created torrent file is invalid. It won't be added to download list. + Vytvořený torrent soubor je špatný. Nebude přidán do seznamu stahování. + + + + downloadFromURL + + Download Torrents from URLs + Stahovat torrenty z URL + + + Only one URL per line + Jen jeden torrent na řádek + + + + Add torrent links + Přidat odkazy torrentů + + + + Both HTTP and Magnet links are supported + Jsou podporovány HTTP i Magnet odkazy + + + + Download + Stahování + + + + Cancel + Zrušit + + + + Download from urls + Stahovat z URL + + + + No URL entered + Nebylo vloženo žádné URL + + + + Please type at least one URL. + Prosím napište alespoň jedno URL. + + + + downloadThread + + I/O Error + Chyba I/O + + + The remote host name was not found (invalid hostname) + Vzdálený server nebyl nalezen (neplatný název počítače) + + + The operation was canceled + Operace byla zrušena + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Vzdálený server předčasně ukončil připojení, dříve než byla celá odpověď přijata a zpracována + + + The connection to the remote server timed out + Připojení k vzdálenému serveru vypršelo + + + SSL/TLS handshake failed + SSL/TLS handshake selhalo + + + The remote server refused the connection + Vzdálený server odmítl připojení + + + The connection to the proxy server was refused + Připojení k proxy serveru bylo odmítnuto + + + The proxy server closed the connection prematurely + Proxy server předčasně ukončil připojení + + + The proxy host name was not found + Název proxy serveru nebyl nalezen + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Připojení k proxy serveru vypršelo nebo proxy dostatečně rychle neodpověla na zaslaný požadavek + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Proxy vyžaduje ověření, ale neakceptovala žádné z nabízených přihlašovacích údajů + + + The access to the remote content was denied (401) + Přístup ke vzdálenému obsahu byl odepřen (401) + + + The operation requested on the remote content is not permitted + Požadovaná operace na vzdáleném obsahu není dovolena + + + The remote content was not found at the server (404) + Vzdálený obsah nebyl na serveru nalezen (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Vzdálený server vyžaduje ověření, ale neakceptoval žádné z nabízených přihlašovacích údajů + + + The Network Access API cannot honor the request because the protocol is not known + API připojení k síti nemohlo akceptovat požadavek z důvodu neznámého protokolu + + + The requested operation is invalid for this protocol + Požadovaná operace není pro tento protokol platná + + + An unknown network-related error was detected + Byla detekována neznámá chyba sítě + + + An unknown proxy-related error was detected + Byla detekována neznámá chyba související s proxy + + + An unknown error related to the remote content was detected + Byla detekována neznámá chyba související se vzdáleným obsahem + + + A breakdown in protocol was detected + Byla detekována chyba v protokolu + + + Unknown error + Neznámá chyba + + + + engineSelect + + + Search plugins + Hledat zásuvné moduly + + + + Installed search engines: + Nainstalované vyhledávače: + + + + Name + Název + + + + Url + URL + + + + + Enabled + Zapnuto + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Nové vyhledávače můžete získat zde: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Nainstalovat nový + + + + Check for updates + Zkontrolovat aktualizace + + + + Close + Zavřít + + + Enable + Zapnout + + + Disable + Vypnout + + + + Uninstall + Odinstalovat + + + + engineSelectDlg + + + Uninstall warning + Upozornění na odstranění + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Některé zásuvné moduly nelze odstranit, protože jsou součástí qBittorrent. +Můžete odstranit pouze moduly, které jste sám přidal. +Nicméně, tyto moduly byly vypnuty. + + + + Uninstall success + Odstranění bylo úspěšné + + + + Select search plugins + Vybrat vyhledávače + + + + qBittorrent search plugins + qBittorrent - vyhledávače + + + + + + + + Search plugin install + Nainstalovat vyhledávač + + + + + + Yes + Ano + + + + + + + No + Ne + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + V systému je již nainstalována novější verze vyhledávače %1. + + + + + + + Search plugin update + Aktualizovat vyhledávač + + + + + Sorry, update server is temporarily unavailable. + Omlouvám se, server s aktualizacemi je dočasně nedostupný. + + + + All your plugins are already up to date. + Všechny zásuvné moduly jsou aktuální. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + Vyhledávač %1 nelze aktualizovat, ponechávám starou verzi. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Vyhledávač %1 nelze nainstalovat. + + + + All selected plugins were uninstalled successfully + Všechny zásuvné moduly byly úspěšně odstraněny + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + Vyhledávač %1 byl úspěšně aktualizován. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Vyhledávač %1 byl úspěšně nainstalován. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Omlouvám se, instalace vyhledávače %1 selhala. + + + + New search engine plugin URL + URL nového zásuvného modulu + + + + URL: + URL: + + + + misc + + + B + bytes + B + + + + KiB + kibibytes (1024 bytes) + KiB + + + + MiB + mebibytes (1024 kibibytes) + MiB + + + + GiB + gibibytes (1024 mibibytes) + GiB + + + + TiB + tebibytes (1024 gibibytes) + TiB + + + + %1h %2m + e.g: 3hours 5minutes + %1h %2m + + + + %1d %2h + e.g: 2days 10hours + %1d %2h + + + + Unknown + Unknown (size) + Neznámý + + + + qBittorrent will shutdown the computer now because all downloads are complete. + Protože jsou staženy všechny torrenty, qBittorrent nyní vypne počítač. + + + + + + + + + Unknown + Neznámý + + + + < 1m + < 1 minute + < 1m + + + + %1m + e.g: 10minutes + %1m + + + + options_imp + + + + Choose export directory + Vyberte adresář pro export + + + + + + + Choose a save directory + Vyberte adresář pro ukládání + + + + + Choose an ip filter file + Vyberte soubor IP filtrů + + + + Add directory to scan + Přidat adresář ke sledování + + + + Folder is already being watched. + Adresář je již sledován. + + + + Folder does not exist. + Adresář neexistuje. + + + + Folder is not readable. + Adresář nelze přečíst. + + + + Failure + Chyba + + + + Failed to add Scan Folder '%1': %2 + Nelze přidat adresář ke sledování '%1': %2 + + + + + Filters + Filtry + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + Chyba zpracování + + + + Failed to parse the provided IP filter + Nepovedlo se zpracovat poskytnutý IP filtr + + + + Successfully refreshed + Úspěšně obnoveno + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + Succesfully refreshed + Úspěšně obnoveno + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Poskytnutý IP filtr byl úspěšně zpracován. Počet aplikovaných pravidel: %1 + + + + pluginSourceDlg + + + Plugin source + Zdroj zásuvného modulu + + + + Search plugin source: + Hledat zdroj zásuvného modulu: + + + + Local file + Místní soubor + + + + Web link + Webový odkaz + + + + preview + + + Preview selection + Výběr náhledu + + + + File preview + Náhled souboru + + + + The following files support previewing, <br>please select one of them: + Následující soubory podporují náhled, <br>vyberte prosím jeden z nich: + + + + Preview + Náhled + + + + Cancel + Zrušit + + + + previewSelect + + Preview impossible + Náhled není možný + + + Sorry, we can't preview this file + Je nám líto, nelze zobrazit náhled tohoto souboru + + + Name + Název + + + Size + Velikost + + + Progress + Průběh + + + + search_engine + + + + Search + Hledat + + + + Status: + Status: + + + + Stopped + Zastaveno + + + + Download + Stahování + + + + Go to description page + Přejít na stránku s popisem + + + + Search engines... + Vyhledávače... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + Nelze dekódovat soubor torrentu: + + + + Unable to decode magnet link: + Nelze dekódovat odkaz Magnet: + + + + Magnet Link + Odkaz Magnet + + + + Rename... + Přejmenovat... + + + + Rename the file + Přejmenovat soubor + + + + New name: + Nový název: + + + + + The file could not be renamed + Soubor nelze přejmenovat + + + + This file name contains forbidden characters, please choose a different one. + Název souboru obsahuje nepovolené znaky, zvolte prosím jiný. + + + + + This name is already in use in this folder. Please use a different name. + Tento název je již v tomto adresáři použit. Vyberte prosím jiný. název. + + + + The folder could not be renamed + Adresář nelze přejmenovat + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 zbývá po stažení torrentu) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 nebo více je potřeba pro stažení) + + + + + + Choose save path + Vyberte cestu pro uložení + + + + Empty save path + Prázdná cesta pro uložení + + + + Please enter a save path + Vložte prosím cestu pro uložení + + + + Save path creation error + Chyba při vytváření cesty pro uložení + + + + Could not create the save path + Nemohu vytvořit cestu pro uložení + + + + Invalid label name + Neplatný název štítku + + + + Please don't use any special characters in the label name. + Nepoužívejte prosím v názvu štítku žádné speciální znaky. + + + + Seeding mode error + Chyba sdílení + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Rozhodl jste se přeskočit kontrolu souborů. Nicméně místní soubory v zadaném cílovém adresáři neexistují. Vypněte prosím tuto funkci nebo zaktualizujte cestu pro uložení. + + + + Invalid file selection + Neplatný výběr souboru + + + + You must select at least one file in the torrent + Musíte v torrentu vybrat alespoň jeden soubor + + + + Priority + Priorita + + + diff --git a/src/lang/qbittorrent_da.qm b/src/lang/qbittorrent_da.qm new file mode 100644 index 0000000000000000000000000000000000000000..e794fe835db49a6291f5220a032217e47c4dc95e GIT binary patch literal 50563 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 + + + + AboutDlg + + + About qBittorrent + Om qBittorrent + + + + About + Om + + + + Author + Skaber + + + + Name: + Navn: + + + + Country: + Land: + + + + E-mail: + E-mail: + + + + Christophe Dumez + Christophe Dumez + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + + France + Frankrig + + + + Translation + Oversættelse + + + + License + Licens + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + + chris@qbittorrent.org + chris@qbittorrent.org + + + + Thanks to + + + + + AdvancedSettings + + + Disk write cache size + + + + + MiB + + + + + Outgoing ports (Min) [0: Disabled] + + + + + Outgoing ports (Max) [0: Disabled] + + + + + Recheck torrents on completion + + + + + Transfer list refresh interval + + + + + ms + milliseconds + + + + + Setting + + + + + Value + Value set for this setting + + + + + Resolve peer countries (GeoIP) + + + + + Resolve peer host names + Opdage hostnames for peers + + + + Maximum number of half-open connections [0: Disabled] + + + + + Strict super seeding + + + + + Network Interface (requires restart) + + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + + + + + IP Address to report to trackers (requires restart) + + + + + Display program on-screen notifications + + + + + Enable embedded tracker + + + + + Embedded tracker port + + + + + Check for software updates + + + + + Use system icon theme + + + + + Confirm torrent deletion + + + + + Ignore transfer limits on local network + + + + + AutomatedRssDownloader + + + Automated RSS Downloader + + + + + Enable the automated RSS downloader + + + + + Download rules + + + + + Rule definition + + + + + Must contain: + + + + + Must not contain: + + + + + Use regular expressions + + + + + Import... + Importer... + + + + Export... + Eksporter... + + + + ... + ... + + + + Assign label: + + + + + Save to a different directory + + + + + Save to: + + + + + Apply rule to feeds: + + + + + Matching RSS articles + + + + + New rule name + + + + + Please type the name of the new download rule. + + + + + + Rule name conflict + + + + + + A rule with this name already exists, please choose another name. + + + + + Are you sure you want to remove the download rule named %1? + + + + + Are you sure you want to remove the selected download rules? + + + + + Rule deletion confirmation + + + + + Destination directory + + + + + Invalid action + + + + + The list is empty, there is nothing to export. + + + + + Where would you like to save the list? + + + + + Rules list (*.rssrules) + + + + + I/O Error + I/O Fejl + + + + Failed to create the destination file + + + + + Please point to the RSS download rules file + + + + + Rules list (*.rssrules *.filters) + + + + + Import Error + + + + + Failed to import the selected rules file + + + + + Add new rule... + + + + + Delete rule + + + + + Rename rule... + + + + + Delete selected rules + + + + + Rule renaming + + + + + Please type the new rule name + + + + + Regex mode: use Perl-like regular expressions + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 nåede den maksimale ratio du har valgt. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent bruger port: TCP/%1 + + + UPnP support [ON] + UPnP understøttelse [ON] + + + UPnP support [OFF] + UPnP understøttelse [OFF] + + + NAT-PMP support [ON] + NAT-PMP understøttelse [ON] + + + NAT-PMP support [OFF] + NAT-PMP understøttelse [OFF] + + + DHT support [ON], port: UDP/%1 + DHT understøttelse [ON], port: UDP/%1 + + + DHT support [OFF] + DHT understøttelse [OFF] + + + PeX support [ON] + PEX understøttelse [ON] + + + Local Peer Discovery [ON] + Lokal Peer Discovery [ON] + + + Local Peer Discovery support [OFF] + Lokal Peer Discovery understøttelse [OFF] + + + Encryption support [ON] + Understøttelse af kryptering [ON] + + + Encryption support [FORCED] + Understøttelse af kryptering [FORCED] + + + Encryption support [OFF] + Understøttelse af kryptering [OFF] + + + Web User Interface Error - Unable to bind Web UI to port %1 + Web User Interface fejl - Ikke i stand til at binde Web UI til port %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' blev fjernet fra listen og harddisken. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' blev fjernet fra listen. + + + '%1' is not a valid magnet URI. + '%1' er ikke en gyldig magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' findes allerede i download listen. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' fortsat. (hurtig fortsættelse) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' lagt til download listen. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Kan ikke dekode torrent filen: '%1' + + + This file is either corrupted or this isn't a torrent. + Denne fil er enten fejlbehæftet eller ikke en torrent. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>blev blokeret af dit IP filter</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>blev bandlyst pga. fejlbehæftede stykker</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekursiv download af filen %1 indlejret i torrent %2 + + + Unable to decode %1 torrent file. + Kan ikke dekode %1 torrent fil. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port mapping fejlede, besked: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port mapping lykkedes, besked: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Der blev fundet fejl i data for hurtig genstart af torrent %1, tjekker igen... + + + Url seed lookup failed for url: %1, message: %2 + Url seed lookup fejlede for url: %1, besked: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Downloader '%1', vent venligst... + + + + ConsoleDlg + + General + Generel + + + Blocked IPs + Blokerede IP adresser + + + + CookiesDlg + + + Cookies management + + + + + Key + As in Key/Value pair + + + + + Value + As in Key/Value pair + + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + + + + + Dynamic DNS error: Invalid username/password. + + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: Your username was blocked due to abuse. + + + + + Dynamic DNS error: supplied domain name is invalid. + + + + + Dynamic DNS error: supplied username is too short. + + + + + Dynamic DNS error: supplied password is too short. + + + + + DownloadThread + + + + I/O Error + I/O Fejl + + + + The remote host name was not found (invalid hostname) + Remote hostname blev ikke funder (ugyldigt hostname) + + + + The operation was canceled + Handlingen blev annulleret + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Servern lukkede forbindelsen for tidligt, før hele svaret var modtaget og behandlet + + + + The connection to the remote server timed out + Forbindelsen til serveren fik time-out + + + + SSL/TLS handshake failed + SSL/TLS handshake mislykkedes + + + + The remote server refused the connection + Serveren nægtede at oprette forbindelse + + + + The connection to the proxy server was refused + Der blev nægtet at oprette forbindelse til proxy-serveren + + + + The proxy server closed the connection prematurely + Proxy--serveren lukkede forbindelsen for tidligt + + + + The proxy host name was not found + Proxy hostname ikke fundet + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Forbindelsen til proxy fik timeout eller også nåede proxy ikke at svare i tide + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Denne proxy kræve autenticering for at acceptere anmodningen, men tog ikke imod nogen af de credentials den blev tilbudt + + + + The access to the remote content was denied (401) + Adgang til indholdet blev nægtet (401) + + + + The operation requested on the remote content is not permitted + Handlingen der bliver efterspurgt på det fjerne indhold er ikke tilladt + + + + The remote content was not found at the server (404) + Indholdet blev ikke fundet på serveren (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Denne server kræve autenticering for at vise indholdet, men tog ikke imod nogen af de credentials den blev tilbudt + + + + The Network Access API cannot honor the request because the protocol is not known + Network Access API kan ikke udføre forespørgslen fordi protokollen ikke kan genkendes + + + + The requested operation is invalid for this protocol + Den anmodede handling er ugyldig for denne protokol + + + + An unknown network-related error was detected + En ukendt netværksrelateret fejl blev fundet + + + + An unknown proxy-related error was detected + En ukendt proxyrelateret fejl blev fundet + + + + An unknown error related to the remote content was detected + En ukendt fejl relateret til indholdet blev fundet + + + + A breakdown in protocol was detected + Et nedbrud i protokollen blev fundet + + + + Unknown error + Ukendt fejl + + + + EventManager + + + + Working + Arbejder + + + + Updating... + Opdaterer... + + + + + Not working + Arbejder ikke + + + + + Not contacted yet + Ikke kontaktet endnu + + + + + this session + denne session + + + + + /s + /second (i.e. per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + Seeded i %1 + + + + %1 max + e.g. 10 max + + + + + + %1/s + e.g. 120 KiB/s + + + + + ExecutionLog + + + General + Generel + + + + Blocked IPs + Blokerede IP adresser + + + + FeedDownloader + + Feed name + Feed navn + + + Automatically download torrents from this feed + Download automatisk torrents fra denne feed + + + Download filters + Download filtre + + + Filters: + Filtre: + + + Filter settings + Indstillinger for filter + + + Matches: + Matcher: + + + Does not match: + Matcher ikke: + + + Destination folder: + Destinationsmappe: + + + ... + ... + + + Filter testing + Test af filter + + + Torrent title: + Torrent titel: + + + Result: + Resultat: + + + Test + Test + + + Import... + Importer... + + + Export... + Eksporter... + + + Rename filter + Omdøb filter + + + Remove filter + Fjern filter + + + Add filter + Tilføj filter + + + + FeedDownloaderDlg + + New filter + Nyt filter + + + Please choose a name for this filter + Vælg venligst et navn til dette filter + + + Filter name: + Filter navn: + + + Invalid filter name + Ikke gyldigt filter navn + + + The filter name cannot be left empty. + Filternavnet kan ikke være tomt. + + + This filter name is already in use. + Dette navn er allerede i brug. + + + Choose save path + Gem til denne mappe + + + Filter testing error + Fejl ved test af filter + + + Please specify a test torrent name. + Specificer venligst navnet på en test torrent. + + + matches + matcher + + + does not match + matcher ikke + + + Select file to import + Vælg fil der skal importeres + + + Filters Files + Filter Filer + + + Import successful + Import lykkedes + + + Filters import was successful. + Import af filtrer lykkedes. + + + Import failure + Fejl ved import + + + Filters could not be imported due to an I/O error. + Filtrer kunne ikke importeres pga. en I/O fejl. + + + Select destination file + Vælg destinationsfil + + + Export successful + Eksport lykkedes + + + Filters export was successful. + Eksport af filtre lykkedes. + + + Export failure + Fejl ved eksport + + + Filters could not be exported due to an I/O error. + Filtrer kunne ikke eksporteres pga. en I/O fejl. + + + + FeedList + + Unread + Ulæst + + + + FeedListWidget + + + RSS feeds + + + + + Unread + Ulæst + + + + GUI + + Open Torrent Files + Åbn Torrent Filer + + + Torrent Files + Torrent Filer + + + Transfers + Overførsler + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + DL hastighed: %1 KB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + UP hastighed: %1 KB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 er hentet færdig. + + + I/O Error + i.e: Input/Output Error + I/O Fejl + + + Search + Søg + + + RSS + RSS + + + Url download error + Url download fejl + + + Couldn't download file at url: %1, reason: %2. + Kunne ikke downloade filen via url: %1, begrundelse: %2. + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + En I/Ofejl opstod for torrent %1 +Begrundelse: %2 + + + Download completion + Download færdig + + + Yes + Ja + + + No + Nej + + + Global Upload Speed Limit + Global Upload Hastighedsbegrænsning + + + Global Download Speed Limit + Global Download Hastighedsbegrænsning + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Nogen filer er stadig ved at bliver overført. +Er du sikker på at du vil afslutte qBittorrent? + + + Options were saved successfully. + Indstillingerne blev gemt. + + + + GeoIP + + France + Frankrig + + + + HeadlessLoader + + + Information + + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + + + + + The Web UI administrator user name is: %1 + + + + + The Web UI administrator password is still the default one: %1 + + + + + This is a security risk, please consider changing your password from program preferences. + + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + + + + + HttpServer + + + File + Fil + + + + Edit + Rediger + + + + Help + Hjælp + + + Delete from HD + Slet fra HD + + + + Download Torrents from their URL or Magnet link + Download Torrents fra deres URL eller Magnet link + + + + Only one link per line + Kun et link per linje + + + + Download local torrent + Download lokal torrent + + + + Torrent files were correctly added to download list. + Torrentfiler blev korrekt tilføjet til downloadlisten. + + + + Point to torrent file + Peg på torrentfil + + + + Download + + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Er du sikker på at du vil slette de markerede elementer i listen og på harddisken? + + + + Download rate limit must be greater than 0 or disabled. + Grænse for download hastighed skal være større end 0 eller slået fra. + + + + Upload rate limit must be greater than 0 or disabled. + Grænse for upload hastighed skal være større end 0 eller slået fra. + + + + Maximum number of connections limit must be greater than 0 or disabled. + Grænsen for det maksimale antal forbindelser skal være større end 0 eller slået fra. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Grænsen for det maksimale antal forbindelser per torrent skal være større end 0 eller slået fra. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Grænsen for det maksimale antal upload slots per torrent skal være større end 0 eller slået fra. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Kunne ikke gemme program indstillinger, qBittorrent kan sikkert ikke nåes. + + + + Language + Sprog + + + + Downloaded + Is the file downloaded or not? + + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + + + + + The Web UI username must be at least 3 characters long. + + + + + The Web UI password must be at least 3 characters long. + + + + + Save + + + + + qBittorrent client is not reachable + + + + + HTTP Server + + + + + The following parameters are supported: + + + + + Torrent path + + + + + Torrent name + + + + + LegalNotice + + + Legal Notice + + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + + + + + Press %1 key to accept and continue... + + + + + Legal notice + + + + + Cancel + Annuller + + + + I Agree + + + + + LineEdit + + + Clear the text + + + + + MainWindow + + + &Edit + &Rediger + + + + &Tools + + + + + &File + &Filer + + + + &Help + &Hjælp + + + + &View + + + + + &Options... + + + + + &About + + + + + &Pause + + + + + &Delete + + + + + P&ause All + + + + + &Resume + + + + + &Add torrent file... + + + + + + Exit + + + + + R&esume All + + + + + Visit &Website + + + + + Auto-Shutdown on downloads completion + + + + + Torrent &creator + + + + + Report a &bug + + + + + Set upload limit... + + + + + Set download limit... + + + + + &Documentation + + + + + Set global download limit... + + + + + Set global upload limit... + + + + + Execution &Log + + + + + + Execution Log + + + + + Exit qBittorrent + + + + + Suspend system + + + + + Shutdown system + + + + + Disabled + Frakoblet + + + + + Lock qBittorrent + + + + + Ctrl+L + + + + + Import existing torrent... + + + + + Import torrent... + + + + + Donate money + + + + + If you like qBittorrent, please donate! + + + + + + Alternative speed limits + + + + + &RSS reader + + + + + Search &engine + + + + + Top &tool bar + + + + + Add &link to torrent... + + + + + Display top tool bar + + + + + &Speed in title bar + + + + + Show transfer speed in title bar + + + + Preview file + Smugkig fil + + + Clear log + Ryd log + + + + Decrease priority + Sæt lavere prioritet + + + + Increase priority + Sæt højere prioritet + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + + + + + Transfers + Overførsler + + + + Torrent file association + + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + + + + + + + UI lock password + + + + + + + Please type the UI lock password: + + + + + The password should contain at least 3 characters + + + + + Password update + + + + + The UI lock password has been successfully updated + + + + + RSS + RSS + + + + Search + Søg + + + + Transfers (%1) + + + + + Download completion + Download færdig + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 er hentet færdig. + + + + I/O Error + i.e: Input/Output Error + I/O Fejl + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + En I/Ofejl opstod for torrent %1 +Begrundelse: %2 + + + + Alt+1 + shortcut to switch to first tab + + + + + Alt+2 + shortcut to switch to third tab + + + + + Ctrl+F + shortcut to switch to search tab + + + + + Alt+3 + shortcut to switch to fourth tab + + + + + Recursive download confirmation + + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + + + + + + Yes + Ja + + + + + No + Nej + + + + Never + + + + + Url download error + Url download fejl + + + + Couldn't download file at url: %1, reason: %2. + Kunne ikke downloade filen via url: %1, begrundelse: %2. + + + + Global Upload Speed Limit + + + + + Global Download Speed Limit + + + + + + Invalid password + + + + + The password is invalid + + + + + Exiting qBittorrent + + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Nogen filer er stadig ved at bliver overført. +Er du sikker på at du vil afslutte qBittorrent? + + + + Always + + + + + Open Torrent Files + Åbn Torrent Filer + + + + Torrent Files + + + + + Options were saved successfully. + Indstillingerne blev gemt. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + DL hastighed: %1 KB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + UP hastighed: %1 KB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + + + + + A newer version is available + + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + + + + + Impossible to update qBittorrent + + + + + qBittorrent failed to update, reason: %1 + + + + + PeerAdditionDlg + + + Invalid IP + Ugyldig IP + + + + The IP you provided is invalid. + IP adressen du opgav er ugyldig + + + + PeerListDelegate + + + /s + /second (i.e. per second) + + + + + PeerListWidget + + + IP + + + + + Connection + Forbindelse + + + + Client + i.e.: Client application + Klient + + + + Progress + i.e: % downloaded + Fremgang + + + + Down Speed + i.e: Download speed + Down hastighed + + + + Up Speed + i.e: Upload speed + Up hastighed + + + + Downloaded + i.e: total data downloaded + + + + + Uploaded + i.e: total data uploaded + + + + + Add a new peer... + + + + + Copy IP + + + + + Limit download rate... + + + + + Limit upload rate... + + + + + Ban peer permanently + Bandlys peer permanent + + + + + Peer addition + Tilføjelse af peer + + + + The peer was added to this torrent. + Peer tilfæjet til denne torrent. + + + + The peer could not be added to this torrent. + Peer kunne ikke tilføjes til denne torrent. + + + + Are you sure? -- qBittorrent + Er du sikker? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Er du sikker på at du vil bandlyse de valgte peers permanent? + + + + &Yes + &Ja + + + + &No + &Nej + + + + Manually banning peer %1... + Banlyser peer %1 manuelt... + + + + Upload rate limiting + Upload begrænsning + + + + Download rate limiting + Download begræsning + + + + Preferences + + + Downloads + Downloads + + + + Connection + Forbindelse + + + + Speed + + + + Proxy + Proxy + + + + Web UI + + + + + Advanced + + + + Language: + Sprog: + + + + (Requires restart) + + + + Visual style: + Udseende: + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + + + + + + Start / Stop Torrent + + + + + + No action + + + + File system + Fil system + + + + Copy .torrent files to: + + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + + + + + Connections Limits + + + + + Proxy Server + + + + + Global Rate Limits + + + + + Apply rate limit to uTP connections + + + + + Apply rate limit to transport overhead + + + + + Alternative Global Rate Limits + + + + + Schedule the use of alternative rate limits + + + + + Enable Local Peer Discovery to find more peers + + + + + Encryption mode: + + + + + Prefer encryption + + + + + Require encryption + + + + + Disable encryption + + + + Torrent queueing + Torrent kø + + + + Maximum active downloads: + Maksimale antal aktive downloads: + + + + Maximum active uploads: + Maksimale antal aktive uploads: + + + + Maximum active torrents: + Maksimale antal aktive torrents: + + + + When adding a torrent + Når en torrent tilføjes + + + + Display torrent content and some options + Vis indhold af torrent og nogle indstillinger + + + Listening port + Port + + + + Port used for incoming connections: + Port til indkommende forbindelser: + + + + Random + Tilfældig + + + Enable UPnP port mapping + Tænd for UPnP port mapping + + + Enable NAT-PMP port mapping + Tænd for NAT-PMP port mapping + + + Connections limit + Grænse for forbindelser + + + + Global maximum number of connections: + Global grænse for det maksimale antal forbindelser: + + + + Maximum number of connections per torrent: + Maksimale antal forbindelser per torrent: + + + + Maximum number of upload slots per torrent: + Maksimale antal upload slots per torrent: + + + + + Upload: + Upload: + + + + + Download: + Download: + + + + + + + KiB/s + KB/s + + + + Append .!qB extension to incomplete files + + + + + Remove folder + + + + + to + time1 to time2 + til + + + + Every day + + + + + Week days + + + + + Week ends + + + + Enable DHT network (decentralized) + Brug DHT netværk (decentraliseret) + + + Use a different port for DHT and Bittorrent + Brug en anden port til DHT og Bittorrent + + + + DHT port: + DHT port: + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + + + + Enable Local Peer Discovery + Brug lokal Peer Discovery + + + Enabled + Slået til + + + Forced + Tvungen + + + Disabled + Frakoblet + + + + Host: + + + + + SOCKS4 + SOCKS4 + + + + Type: + + + + + + Options + Indstillinger + + + + Action on double-click + + + + + Downloading torrents: + + + + + + Open destination folder + Åben destinationsmappe + + + + Completed torrents: + + + + + Desktop + + + + + Show splash screen on start up + + + + + Start qBittorrent minimized + + + + + Minimize qBittorrent to notification area + + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + + + + + Tray icon style: + + + + + Normal + Normal + + + + Monochrome (Dark theme) + + + + + Monochrome (Light theme) + + + + + Ask for program exit confirmation + + + + + User Interface Language: + + + + + Transfer List + + + + + Show qBittorrent in notification area + + + + + Power Management + + + + + Inhibit system sleep when torrents are active + + + + + Do not start the download automatically + The torrent will be added to download list in pause state + + + + + Hard Disk + + + + + Save files to location: + + + + + Append the label of the torrent to the save path + + + + + Pre-allocate disk space for all files + + + + + Keep incomplete torrents in: + + + + + Automatically add torrents from: + + + + + Add folder... + + + + + Email notification upon download completion + + + + + Destination email: + + + + + SMTP server: + + + + + This server requires a secure connection (SSL) + + + + + Run an external program on torrent completion + + + + + Listening Port + + + + + Use UPnP / NAT-PMP port forwarding from my router + + + + + Otherwise, the proxy server is only used for tracker connections + + + + + Use proxy for peer connections + + + + + IP Filtering + + + + + Reload the filter + + + + + Enable bandwidth management (uTP) + + + + + from + from (time1 to time2) + + + + + When: + + + + + Privacy + + + + + Enable DHT (decentralized network) to find more peers + + + + + Use a different port for DHT and BitTorrent + + + + + Enable Peer Exchange (PeX) to find more peers + + + + + Look for peers on your local network + + + + + Seed torrents until their ratio reaches + + + + + then + + + + + Pause them + + + + + Remove them + + + + + Use UPnP / NAT-PMP to forward the port from my router + + + + + Use HTTPS instead of HTTP + + + + + Import SSL Certificate + + + + + Import SSL Key + + + + + Certificate: + + + + + Key: + + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + Bypass authentication for localhost + + + + + Update my dynamic domain name + + + + + Service: + + + + + Register + + + + + Domain name: + + + + + (None) + (Ingen) + + + + + Behavior + + + + + BitTorrent + + + + + Language + Sprog + + + + HTTP + HTTP + + + + + Port: + Port: + + + + + + Authentication + Godkendelse + + + + + + + Username: + Brugernavn: + + + + + + + Password: + Kodeord: + + + + Torrent Queueing + + + + + Share Ratio Limiting + + + + + Enable Web User Interface (Remote control) + + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + + + + + PreviewSelect + + + Name + Navn + + + + Size + Størrelse + + + + Progress + + + + + + + Preview impossible + Smugkig ikke muligt + + + + + + Sorry, we can't preview this file + Beklager, denne fil kan ikke smugkigges + + + + PropListDelegate + + + Not downloaded + + + + + + Normal + Normal (priority) + Normal + + + + + High + High (priority) + Høj + + + + Mixed + Mixed (priorities + + + + + + Maximum + Maximum (priority) + Maksimal + + + + PropTabBar + + + General + Generel + + + + Trackers + Trackere + + + + Peers + + + + + HTTP Sources + + + + + Content + + + + Files + Filer + + + + PropertiesWidget + + + Save path: + Gem i: + + + + Torrent hash: + + + + + Comment: + Kommentar: + + + + Share ratio: + Delingsforhold: + + + + + Downloaded: + + + + + Availability: + Tilgængelighed: + + + + Transfer + Overførsel + + + + Uploaded: + + + + + Wasted: + Spildt: + + + + UP limit: + UP grænse: + + + + DL limit: + DL grænse: + + + Time elapsed: + Tidsforbrug: + + + + Connections: + Forbindelser: + + + + Time active: + Time (duration) the torrent is active (not paused) + + + + + Reannounce in: + + + + + Information + + + + + Created on: + Oprettet på: + + + + Pieces size: + + + + + Torrent content: + Indhold af torrent: + + + + Select All + + + + + Select None + + + + + Normal + Normal + + + + + Do not download + + + + General + Generel + + + Trackers + Trackere + + + Files + Filer + + + + Priority + Prioritet + + + + Maximum + Maksimal + + + + High + Høj + + + + + this session + denne session + + + + %1 max + e.g. 10 max + + + + + + /s + /second (i.e. per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + Har seeded i %1 + + + + + I/O Error + I/O Fejl + + + + This file does not exist yet. + + + + + This folder does not exist yet. + + + + + Rename... + + + + + Rename the file + + + + + New name: + + + + + + The file could not be renamed + + + + + This file name contains forbidden characters, please choose a different one. + + + + + + This name is already in use in this folder. Please use a different name. + + + + + The folder could not be renamed + + + + + New url seed + New HTTP source + Ny url seed + + + + New url seed: + Ny url seed: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Denne url seed er allerede på listen. + + + + + Choose save path + Gem til denne mappe + + + Save path creation error + Fejl ved oprettelse af mappe + + + Could not create the save path + Kunne ikke oprette mappe svarende til den indtastede sti + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 nåede den maksimale ratio du har valgt. + + + + Removing torrent %1... + + + + + Pausing torrent %1... + + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent bruger port: TCP/%1 + + + UPnP support [ON] + UPnP understøttelse [ON] + + + UPnP support [OFF] + UPnP understøttelse [OFF] + + + NAT-PMP support [ON] + NAT-PMP understøttelse [ON] + + + NAT-PMP support [OFF] + NAT-PMP understøttelse [OFF] + + + + HTTP user agent is %1 + + + + + DHT support [ON], port: UDP/%1 + DHT understøttelse [ON], port: UDP/%1 + + + + + DHT support [OFF] + DHT understøttelse [OFF] + + + + PeX support [ON] + PEX understøttelse [ON] + + + + PeX support [OFF] + + + + + Restart is required to toggle PeX support + + + + Local Peer Discovery [ON] + Lokal Peer Discovery [ON] + + + + Local Peer Discovery support [OFF] + Lokal Peer Discovery understøttelse [OFF] + + + + Encryption support [ON] + Understøttelse af kryptering [ON] + + + + Encryption support [FORCED] + Understøttelse af kryptering [FORCED] + + + + Encryption support [OFF] + Understøttelse af kryptering [OFF] + + + + Embedded Tracker [ON] + + + + + Failed to start the embedded tracker! + + + + + Embedded Tracker [OFF] + + + + + The Web UI is listening on port %1 + + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Web User Interface fejl - Ikke i stand til at binde Web UI til port %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' blev fjernet fra listen og harddisken. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' blev fjernet fra listen. + + + + '%1' is not a valid magnet URI. + '%1' er ikke en gyldig magnet URI. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' findes allerede i download listen. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' fortsat. (hurtig fortsættelse) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' lagt til download listen. + + + + UPnP / NAT-PMP support [ON] + + + + + UPnP / NAT-PMP support [OFF] + + + + + Reporting IP address %1 to trackers... + + + + + Local Peer Discovery support [ON] + + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Kan ikke dekode torrent filen: '%1' + + + + This file is either corrupted or this isn't a torrent. + Denne fil er enten fejlbehæftet eller ikke en torrent. + + + + Error: The torrent %1 does not contain any file. + + + + + Note: new trackers were added to the existing torrent. + + + + + Note: new URL seeds were added to the existing torrent. + + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>blev blokeret af dit IP filter</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>blev bandlyst pga. fejlbehæftede stykker</i> + + + + The network interface defined is invalid: %1 + + + + + Trying any other network interface available instead. + + + + + Listening on IP address %1 on network interface %2... + + + + + Failed to listen on network interface %1 + + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekursiv download af filen %1 indlejret i torrent %2 + + + + + Unable to decode %1 torrent file. + Kan ikke dekode %1 torrent fil. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + + + + + Error: Failed to parse the provided IP filter. + + + + + Torrent name: %1 + + + + + Torrent size: %1 + + + + + Save path: %1 + + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + + + + + Thank you for using qBittorrent. + + + + + [qBittorrent] %1 has finished downloading + + + + + An I/O error occured, '%1' paused. + + + + + + Reason: %1 + + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port mapping fejlede, besked: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port mapping lykkedes, besked: %1 + + + + File sizes mismatch for torrent %1, pausing it. + + + + + Fast resume data was rejected for torrent %1, checking again... + Der blev fundet fejl i data for hurtig genstart af torrent %1, tjekker igen... + + + + Url seed lookup failed for url: %1, message: %2 + Url seed lookup fejlede for url: %1, besked: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Downloader '%1', vent venligst... + + + + RSS + + + Search + Søg + + + + New subscription + Ny abonnement + + + + + + Mark items read + Maker som læst + + + + Update all + Opdater alle + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + + + + Article title + Artiklens titel + + + + + Update all feeds + Opdater alle feeds + + + + + Delete + Slet + + + + RSS Downloader... + + + + + Settings... + + + + + Rename... + + + + + Rename + Omdøb + + + + + Update + Opdater + + + + New subscription... + + + + + Download torrent + + + + + Open news URL + Åben nyheds URL + + + + Copy feed URL + Kopier feed URL + + + + New folder... + + + + + Manage cookies... + + + + + Refresh RSS streams + Opdater RSS streams + + + + RSSImp + + + Please type a rss stream url + Indtast venligst en rss stream url + + + + Stream URL: + + + + + + Are you sure? -- qBittorrent + Er du sikker? -- qBittorrent + + + + + &Yes + &Ja + + + + + &No + &Nej + + + + Please choose a folder name + Vælg venligst et mappenavn + + + + Folder name: + Mappenavn: + + + + New folder + Ny mappe + + + + Overwrite attempt + Forsøg på overskrivning + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Cant see what the "item" is for at the end. Not in danish or english + Du kan ikke overskrive %1. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Denne rss feed er allerede på listen. + + + + Are you sure you want to delete these elements from the list? + Er du sikker på at du vil slette disse elementer fra listen? + + + + Are you sure you want to delete this element from the list? + Er du sikker på at du vil slette dette elementer fra listen? + + + + Please choose a new name for this RSS feed + Vælg venligst et nyt navn til denne RSS feed + + + + New feed name: + Nyt feed navn: + + + + Name already in use + Navn allerede i brug + + + + This name is already used by another item, please choose another one. + Dette navn er allerede i brug et andet sted, vælg venligst et andet navn. + + + + Date: + Dato: + + + + Author: + Forfatter: + + + + Unread + Ulæst + + + + RssArticle + + No description available + Ingen beskrivelse tilgængelig + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Henter automatisk %1 torrent fra %2 RSS feed... + + + + RssItem + + No description available + Ingen beskrivelse tilgængelig + + + + RssSettings + + RSS feeds refresh interval: + RSS feeds opdaterings interval: + + + minutes + minutter + + + Maximum number of articles per feed: + Maksimalt antal artikler per feed: + + + + RssSettingsDlg + + + RSS Reader Settings + + + + + RSS feeds refresh interval: + RSS feeds opdaterings interval: + + + + minutes + minutter + + + + Maximum number of articles per feed: + Maksimalt antal artikler per feed: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Henter automatisk %1 torrent fra %2 RSS feed... + + + + ScanFoldersModel + + + Watched Folder + + + + + Download here + + + + + SearchCategories + + + All categories + Alle kategorier + + + + Movies + Film + + + + TV shows + TV udsendelser + + + + Music + Musik + + + + Games + Spil + + + + Anime + Anime + + + + Software + Programmer + + + + Pictures + Billeder + + + + Books + Bøger + + + + SearchEngine + + + Empty search pattern + Tomt søge kriterie + + + + Please type a search pattern first + Indtast venligst et søge kriterie først + + + + + Results + Resultater + + + + Searching... + Søger... + + + + Cut + Klip + + + + Copy + Kopier + + + + Paste + Indsæt + + + + Clear field + Ryd felt + + + + Clear completion history + Ryd historik + + + + Confirmation + + + + + Are you sure you want to clear the history? + + + + + + + Search + Søg + + + + Missing Python Interpreter + + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + + + + + Search Engine + Søgemaskine + + + + + Search has finished + Søgningen er færdig + + + + An error occured during search... + Der opstod en fejl under søgningen... + + + + + Search aborted + Søgning afbrudt + + + + Download error + + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + + + + + Search returned no results + Søgningen gav intet resultat + + + + Results + i.e: Search results + Resultater + + + + + Unknown + Ukendt + + + + SearchTab + + + Name + i.e: file name + Navn + + + + Size + i.e: file size + Størrelse + + + + Seeders + i.e: Number of full sources + Seedere + + + + Leechers + i.e: Number of partial sources + Leechere + + + + Search engine + Søgemaskine + + + + ShutdownConfirmDlg + + + Shutdown confirmation + + + + + SpeedLimitDialog + + + KiB/s + KB/s + + + + StatusBar + + + + Connection status: + Forbindelses status: + + + + + No direct connections. This may indicate network configuration problems. + Ingen direkte forbindelser. Dette kan indikere et problem med konfigurationen af netværket. + + + + + DHT: %1 nodes + + + + + qBittorrent needs to be restarted + + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + + + + + + Connection Status: + Forbindelses Status: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + + + + + Online + Online + + + + + %1/s + Per second + + + + + Click to switch to alternative speed limits + + + + + Click to switch to regular speed limits + + + + + Global Download Speed Limit + Global begrænsning af downloadhastighed + + + + Global Upload Speed Limit + Global begrænsning af upload hastighed + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Vælg en mappe der skal tilføjes til denne torrent + + + + Select a file to add to the torrent + Vælg en fil der skal tilføjes til denne torrent + + + Please type an announce URL + Indtast venligst en announce URL + + + Please type a web seed url + Indtast venligst en web seed url + + + + No input path set + Der er ikke sat nogen sti til input + + + + Please type an input path first + Indtast venligst en input sti først + + + + Select destination torrent file + Vælg destinations torrent fil + + + + Torrent Files + + + + + + + Torrent creation + Torrent oprettelse + + + + Torrent creation was unsuccessful, reason: %1 + Oprettelse af torrent lykkedes ikke, begrundelse: %1 + + + + Created torrent file is invalid. It won't be added to download list. + Den oprettede torrent fil er ugyldig. Den vil ikke blive tilføjet til download listen. + + + + Torrent was created successfully: + Torrent blev oprettet succesfuldt: + + + + TorrentFilesModel + + + Name + Navn + + + + Size + Størrelse + + + + Progress + Hentet + + + + Priority + Prioritet + + + + TorrentImportDlg + + + Torrent Import + + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + + + + + Torrent file to import: + + + + + + ... + ... + + + + Content location: + + + + + Skip the data checking stage and start seeding immediately + + + + + Import + + + + + Torrent file to import + + + + + Torrent files (*.torrent) + + + + + %1 Files + %1 is a file extension (e.g. PDF) + + + + + Please provide the location of %1 + %1 is a file name + + + + + Please point to the location of the torrent: %1 + + + + + Invalid torrent file + + + + + This is not a valid torrent file. + + + + + TorrentModel + + + Name + i.e: torrent name + Navn + + + + Size + i.e: torrent size + Størrelse + + + + Done + % Done + Færdig + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + + Seeds + i.e. full sources (often untranslated) + + + + + Peers + i.e. partial sources (often untranslated) + + + + + Down Speed + i.e: Download speed + + + + + Up Speed + i.e: Upload speed + + + + + Ratio + Share ratio + + + + + ETA + i.e: Estimated Time of Arrival / Time left + Tid Tilbage + + + + Label + + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + + + + + Tracker + + + + + Down Limit + i.e: Download limit + + + + + Up Limit + i.e: Upload limit + + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + + + + + Amount left + Amount of data left to download (e.g. in MB) + + + + + Time Active + Time (duration) the torrent is active (not paused) + + + + + TrackerList + + + URL + + + + + Status + Status + + + + Peers + + + + + Message + Besked + + + + [DHT] + + + + + [PeX] + + + + + [LSD] + + + + + + + + + Working + Arbejder + + + + + + Disabled + Frakoblet + + + + This torrent is private + Denne torrent er privat + + + + Updating... + Opdaterer... + + + + + Not working + Arbejder ikke + + + + + Not contacted yet + Ikke kontaktet endnu + + + + Add a new tracker... + + + + + Remove tracker + + + + + Force reannounce + + + + + TrackersAdditionDlg + + + Trackers addition dialog + Tilføjelse af ny tracker + + + + List of trackers to add (one per line): + Liste med trackere der skal tilføjes (en per linje): + + + + µTorrent compatible list URL: + + + + + I/O Error + I/O Fejl + + + + Error while trying to open the downloaded file. + + + + + No change + + + + + No additional trackers were found. + + + + + Download error + + + + + The trackers list could not be downloaded, reason: %1 + + + + + TransferListDelegate + + + Downloading + Downloader + + + + Paused + Pauset + + + + Queued + i.e. torrent is queued + Sat i kø + + + + Seeding + Torrent is complete and in upload-only mode + Seeder + + + + Stalled + Torrent is waiting for download to begin + Gået i stå + + + + Checking + Torrent local data is being checked + Tjekker + + + + /s + /second (.i.e per second) + + + + + KiB/s + KiB/second (.i.e per second) + KB/s + + + + Seeded for %1 + e.g. Seeded for 3m10s + + + + + TransferListFiltersWidget + + + + All + Alle + + + + + Downloading + Downloader + + + + + Completed + Færdig + + + + + Paused + Pauset + + + + + Active + Aktiv + + + + + Inactive + Inaktiv + + + + + All labels + + + + + + Unlabeled + + + + + Remove label + + + + + Add label... + + + + + Resume torrents + + + + + Pause torrents + + + + + Delete torrents + + + + + New Label + + + + + Label: + + + + + Invalid label name + + + + + Please don't use any special characters in the label name. + + + + + TransferListWidget + + Down Speed + i.e: Download speed + Down Hastighed + + + Up Speed + i.e: Upload speed + Up Hastighed + + + ETA + i.e: Estimated Time of Arrival / Time left + Tid Tilbage + + + + Column visibility + Kolonne synlighed + + + Name + i.e: torrent name + Navn + + + Size + i.e: torrent size + Størrelse + + + Done + % Done + Færdig + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + + Label + + + + + Choose save path + Gem til denne mappe + + + Save path creation error + Fejl ved oprettelse af mappe + + + Could not create the save path + Kunne ikke oprette mappe svarende til den indtastede sti + + + + Torrent Download Speed Limiting + Begrænsning af Torrent Download Hastighed + + + + Torrent Upload Speed Limiting + Begrænsning af Torrent Upload Hastighed + + + + New Label + + + + + Label: + + + + + Invalid label name + + + + + Please don't use any special characters in the label name. + + + + + Rename + Omdøb + + + + New name: + + + + + Resume + Resume/start the torrent + + + + + Pause + Pause the torrent + Pause + + + + Delete + Delete the torrent + Slet + + + + Preview file... + + + + + Limit share ratio... + + + + + Limit upload rate... + + + + + Limit download rate... + + + + + Priority + Prioritet + + + + Open destination folder + Åben destinationsmappe + + + + Move up + i.e. move up in the queue + + + + + Move down + i.e. Move down in the queue + + + + + Move to top + i.e. Move to top of the queue + + + + + Move to bottom + i.e. Move to bottom of the queue + + + + + Set location... + + + + + Force recheck + Tvungen tjek + + + + Copy magnet link + Kopier magnet link + + + + Super seeding mode + Super seeding tilstand + + + + Rename... + + + + + Download in sequential order + Downlad i rækkefølge + + + + Download first and last piece first + Download første og sidste stykke først + + + + New... + New label... + + + + + Reset + Reset label + + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + + + + + Use global ratio limit + + + + + + + buttonGroup + + + + + Set no ratio limit + + + + + Set ratio limit to + + + + + UsageDisplay + + + Usage: + + + + + displays program version + + + + + disable splash screen + + + + + displays this help message + + + + + changes the webui port (current: %1) + + + + + [files or urls]: downloads the torrents passed by the user (optional) + + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Jeg vil gerne takke disse personer, som meldte sig frivilligt til at oversætte qBittorrent: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Kontakt mig venligst hvis du kunne tænke dig og oversætte qBittorrent til dit eget sprog. + + + + addPeerDialog + + + Peer addition + Peer tilføjelse + + + + IP + IP + + + + Port + Port + + + + addTorrentDialog + + + Torrent addition dialog + Tilføj ny torrent + + + + Save path: + Gem i: + + + + ... + ... + + + + Torrent size: + Torrent størrelse: + + + + + Unknown + Ukendt + + + + Free disk space: + Ledig disk plads: + + + + Label: + + + + + Torrent content: + Indhold af torrent: + + + + Select All + + + + + Select None + + + + + Download in sequential order (slower but good for previewing) + Download i fra start til slut (langsommere, men godt for smugkig) + + + + Skip file checking and start seeding immediately + Spring filtjek over og påbegynd seed med det samme + + + + Normal + Normal + + + + + Do not download + + + + + Add to download list in paused state + Tilføj til download listen som sat på pause + + + + Add + Tilføj + + + + Cancel + Annuller + + + + High + Høj + + + + Maximum + Maksimal + + + + authentication + + + + Tracker authentication + Godkendelse af tracker + + + + Tracker: + Tracker: + + + + Login + Login + + + + Username: + Brugernavn: + + + + Password: + Kodeord: + + + + Log in + Log på + + + + Cancel + Annuller + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Bekræft sletning - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Er du sikker på at du vil slette de valgte torrent fra listen? + + + + Remember choice + + + + + Also delete the files on the hard disk + + + + + createTorrentDialog + + + Cancel + Annuller + + + + Torrent Creation Tool + Værktøj: Opret torrent + + + + Torrent file creation + Torrent fil oprettelse + + + + Add file + Tilføj fil + + + + Add folder + Tilføj mappe + + + Comment (optional): + Kommentar (ikke påkrævet): + + + Web seeds urls (optional): + Web seeds url'er(Ikke påkrævet): + + + + File or folder to add to the torrent: + Fil eller mappe der skal tilføjes til denne torrent: + + + + Tracker URLs: + + + + + Web seeds urls: + + + + + Comment: + Kommentar: + + + + Piece size: + Piece størrelse: + + + + 32 KiB + + + + + 64 KiB + + + + + 128 KiB + + + + + 256 KiB + + + + + 512 KiB + + + + + 1 MiB + + + + + 2 MiB + + + + + 4 MiB + + + + + Auto + + + + + Private (won't be distributed on DHT network if enabled) + Privat (vil ikke blive distribueret på DHT netværket hvis dette er slået til) + + + + Start seeding after creation + Start seed efter oprettelse + + + + Create and save... + Opret og gem... + + + + Progress: + Fremgang: + + + + createtorrent + + Select destination torrent file + Vælg destinations torrent fil + + + Torrent Files + Torrent FIler + + + No input path set + Der er ikke sat nogen sti til input + + + Please type an input path first + Indtast venligst en input sti først + + + Torrent creation + Torrent oprettelse + + + Torrent was created successfully: + Torrent blev oprettet succesfuldt: + + + Select a folder to add to the torrent + Vælg en mappe der skal tilføjes til denne torrent + + + Please type an announce URL + Indtast venligst en announce URL + + + Torrent creation was unsuccessful, reason: %1 + Oprettelse af torrent lykkedes ikke, begrundelse: %1 + + + Please type a web seed url + Indtast venligst en web seed url + + + Select a file to add to the torrent + Vælg en fil der skal tilføjes til denne torrent + + + Created torrent file is invalid. It won't be added to download list. + Den oprettede torrent fil er ugyldig. Den vil ikke blive tilføjet til download listen. + + + + downloadFromURL + + Download Torrents from URLs + Hent torrents fra URL(er) + + + Only one URL per line + Kun en URL per linje + + + + Add torrent links + + + + + Both HTTP and Magnet links are supported + + + + + Download + Hent + + + + Cancel + Annuller + + + + Download from urls + Hent fra url(er) + + + + No URL entered + Der er ikke indtastet nogen URL + + + + Please type at least one URL. + Indtast venligst mindst en URL. + + + + downloadThread + + I/O Error + I/O Fejl + + + The remote host name was not found (invalid hostname) + Remote hostname blev ikke funder (ugyldigt hostname) + + + The operation was canceled + Handlingen blev annulleret + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Servern lukkede forbindelsen for tidligt, før hele svaret var modtaget og behandlet + + + The connection to the remote server timed out + Forbindelsen til serveren fik time-out + + + SSL/TLS handshake failed + SSL/TLS handshake mislykkedes + + + The remote server refused the connection + Serveren nægtede at oprette forbindelse + + + The connection to the proxy server was refused + Der blev nægtet at oprette forbindelse til proxy-serveren + + + The proxy server closed the connection prematurely + Proxy--serveren lukkede forbindelsen for tidligt + + + The proxy host name was not found + Proxy hostname ikke fundet + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Forbindelsen til proxy fik timeout eller også nåede proxy ikke at svare i tide + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Denne proxy kræve autenticering for at acceptere anmodningen, men tog ikke imod nogen af de credentials den blev tilbudt + + + The access to the remote content was denied (401) + Adgang til indholdet blev nægtet (401) + + + The operation requested on the remote content is not permitted + Handlingen der bliver efterspurgt på det fjerne indhold er ikke tilladt + + + The remote content was not found at the server (404) + Indholdet blev ikke fundet på serveren (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Denne server kræve autenticering for at vise indholdet, men tog ikke imod nogen af de credentials den blev tilbudt + + + The Network Access API cannot honor the request because the protocol is not known + Network Access API kan ikke udføre forespørgslen fordi protokollen ikke kan genkendes + + + The requested operation is invalid for this protocol + Den anmodede handling er ugyldig for denne protokol + + + An unknown network-related error was detected + En ukendt netværksrelateret fejl blev fundet + + + An unknown proxy-related error was detected + En ukendt proxyrelateret fejl blev fundet + + + An unknown error related to the remote content was detected + En ukendt fejl relateret til indholdet blev fundet + + + A breakdown in protocol was detected + Et nedbrud i protokollen blev fundet + + + Unknown error + Ukendt fejl + + + + engineSelect + + + Search plugins + Søge plugins + + + + Installed search engines: + Indstallerede søgemaskiner: + + + + Name + Navn + + + + Url + + + + + + Enabled + Slået til + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + + Install a new one + Indstaller en ny + + + + Check for updates + Tjek for opdateringer + + + + Close + Luk + + + Enable + Slå til + + + Disable + Slå fra + + + + Uninstall + Afinstaller + + + + engineSelectDlg + + + Uninstall warning + Afindstallations advarsel + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Visse plugins kunne ikke afindstalleres fordi de er indkluderet i qBittorrent +Du kan kun afindstallere dem du selv har indstalleret +Disse plugins blev dog koble fra. + + + + Uninstall success + Afindstallationen lykkedes + + + + Select search plugins + Vælg søge plugin + + + + qBittorrent search plugins + qBittorrent søge plugins + + + + + + + + Search plugin install + Søge plugin indstallation + + + + + + Yes + Ja + + + + + + + No + Nej + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + En nyere version af %1 søgemaskine plugin er allerede indstalleret. + + + + + + + Search plugin update + Søge plugin opdatering + + + + + Sorry, update server is temporarily unavailable. + Beklager, opdaterings-serveren er midlertidigt utilgængelig. + + + + All your plugins are already up to date. + Alle dine plugins er af nyeste udgave. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 søgemaskine plugin kunne ikke opdateres, beholder gammel version. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 søgemaskine plugin kunne ikke indstalleres. + + + + All selected plugins were uninstalled successfully + Afindstallationen af alle valgte plugins lykkedes + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 søgemaskine plugin blev opdateret. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Indstallationen af %1 søgemaskine plugin lykkedes. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Beklager, %1 søgemaskine plugin kunne ikk indstalleres. + + + + New search engine plugin URL + Ny søgemaskine plugin URL + + + + URL: + + + + + misc + + + B + bytes + B + + + + KiB + kibibytes (1024 bytes) + KB + + + + MiB + mebibytes (1024 kibibytes) + MB + + + + GiB + gibibytes (1024 mibibytes) + GB + + + + TiB + tebibytes (1024 gibibytes) + TB + + + + + + + + + Unknown + Ukendt + + + + %1h %2m + e.g: 3hours 5minutes + + + + + %1d %2h + e.g: 2days 10hours + + + + + Unknown + Unknown (size) + Ukendt + + + + qBittorrent will shutdown the computer now because all downloads are complete. + + + + + < 1m + < 1 minute + < 1 m + + + + %1m + e.g: 10minutes + %1m + + + + options_imp + + + + + + Choose a save directory + Vælg en standart mappe + + + + Add directory to scan + + + + + Folder is already being watched. + + + + + Folder does not exist. + + + + + Folder is not readable. + + + + + Failure + + + + + Failed to add Scan Folder '%1': %2 + + + + + + Choose export directory + + + + + + Choose an ip filter file + Vælg en ip filter fil + + + + + Filters + Filtre + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + + + + + Failed to parse the provided IP filter + + + + + Successfully refreshed + + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + + pluginSourceDlg + + + Plugin source + Plugin kilde + + + + Search plugin source: + Søgemaskine plugin kilde: + + + + Local file + Lokal fil + + + + Web link + Web link + + + + preview + + + Preview selection + Smugkig valgte + + + + File preview + Smugkig + + + + The following files support previewing, <br>please select one of them: + De følgende filer kan smugkigges, <br>vælg venligst en af dem: + + + + Preview + Smugkig + + + + Cancel + Annuller + + + + previewSelect + + Preview impossible + Smugkig ikke muligt + + + Sorry, we can't preview this file + Beklager, denne fil kan ikke smugkigges + + + Name + Navn + + + Size + Størrelse + + + Progress + Hentet + + + + search_engine + + + + Search + Søg + + + + Status: + Status: + + + + Stopped + Stoppet + + + + Download + + + + + Go to description page + + + + + Search engines... + Søgemskiner... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + Kan ikke dekode torrent filen: + + + + + + Choose save path + Gem til denne mappe + + + + Unable to decode magnet link: + + + + + Magnet Link + + + + + Rename... + + + + + Rename the file + + + + + New name: + + + + + + The file could not be renamed + + + + + This file name contains forbidden characters, please choose a different one. + + + + + + This name is already in use in this folder. Please use a different name. + + + + + The folder could not be renamed + + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 tilbage efter torrent dowload) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 mere er krævet for at foretage download) + + + + Empty save path + Ingen mappe + + + + Please enter a save path + Vælg venligst en mappe som der skal hentes til + + + + Save path creation error + Fejl ved oprettelse af mappe + + + + Could not create the save path + Kunne ikke oprette mappe svarende til den indtastede sti + + + + Invalid label name + + + + + Please don't use any special characters in the label name. + + + + + Seeding mode error + Seeding mode fejl + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Du har valgt at springer over filtjek. Dog synes lokale filer ikke at findes i den nuværende destinationsmappe. Slå venligst denne feature fra eller opdater stien der gemmes til. + + + + Invalid file selection + Valg af filer ugyldigt + + + + You must select at least one file in the torrent + Du skal vælge mindst en fil per torrent + + + + Priority + Prioritet + + + diff --git a/src/lang/qbittorrent_de.qm b/src/lang/qbittorrent_de.qm new file mode 100644 index 0000000000000000000000000000000000000000..61461e17b43cf2b756141e3a4daa3c2fd292f25a GIT binary patch literal 107063 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 literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_de.ts b/src/lang/qbittorrent_de.ts new file mode 100644 index 000000000..19063287f --- /dev/null +++ b/src/lang/qbittorrent_de.ts @@ -0,0 +1,6610 @@ + + + + + AboutDlg + + + About qBittorrent + Über qBittorrent + + + + About + Info + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Ein Bittorrent Client programmiert in C++, basierend auf dem Qt4 Toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">und libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent auf Freenode</span></p></body></html> + + + + Author + Autor + + + + Name: + Name: + + + + Country: + Land: + + + + E-mail: + E-mail: + + + + Christophe Dumez + Christophe Dumez + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + + France + Frankreich + + + + Translation + Übersetzung + + + + License + Lizenz + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + + chris@qbittorrent.org + + + + + Thanks to + Dank an + + + + AdvancedSettings + + Property + Eigenschaft + + + Value + Wert + + + + Disk write cache size + Größe des Plattencache zum schreiben + + + + MiB + + + + + Setting + + + + + Value + Value set for this setting + Wert + + + + Outgoing ports (Min) [0: Disabled] + Ausgehende Ports (Min) [0: Deaktiviert] + + + + Outgoing ports (Max) [0: Disabled] + Ausgehende Ports (Max) [0: Deaktiviert] + + + + Ignore transfer limits on local network + Transferlimits im lokalen Netzwerk ignorieren + + + + Exchange trackers with other peers + + + + Include TCP/IP overhead in transfer limits + TCP/IP Overhead in Transferlimits einbeziehen + + + + Recheck torrents on completion + Torrents nach Abschluss der Übertragung erneut prüfen + + + + Transfer list refresh interval + Intervall zum Auffrischen der Transfer-Liste + + + + ms + milliseconds + + + + + Resolve peer countries (GeoIP) + Herkunftsländer der Peers auflösen (GeoIP) + + + + Resolve peer host names + Hostnamen der Peers auflösen + + + + Maximum number of half-open connections [0: Disabled] + Maximale Anzahl halboffener Verbindungen [0: Deaktiviert] + + + + Strict super seeding + Striktes Super Seeding + + + + Network Interface (requires restart) + Netzwerk Interface (Neustart benötigt) + + + + Any interface + i.e. Any network interface + Beliebiges Interface + + + + IP Address to report to trackers (requires restart) + IP Adresse die bei Trackern angegeben werden soll (Neustart benötigtr) + + + + Display program on-screen notifications + Benachrichtigungen auf dem Bildschirm anzeigen + + + Display program notification balloons + Zeige Benachrichtigungssprechblasen + + + + Enable embedded tracker + Eingebetteten Tracker aktivieren + + + + Embedded tracker port + Port des eingebetteten Trackers + + + + Check for software updates + Auf Software-Updates prüfen + + + + Use system icon theme + System-Icon-Theme benutzen + + + + Confirm torrent deletion + Löschen des Torrents bestätigen + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Automatisierter RSS Downloader + + + + Enable the automated RSS downloader + Automatisierten RSS Downloader aktivieren + + + + Download rules + Downloadregeln + + + + Rule definition + Regeldefinition + + + + Must contain: + Enthält: + + + + Must not contain: + Enthält nicht: + + + + Use regular expressions + + + + + Import... + Import... + + + + Export... + Export... + + + + ... + ... + + + + Assign label: + Label zuweisen: + + + + Save to a different directory + In ein anderes Verzeicnis speichern + + + + Save to: + Speichern in: + + + + Apply rule to feeds: + Regeln auf Feeds anwenden: + + + + Matching RSS articles + Übereinstimmende RSS Artikel + + + + New rule name + Neuer Regelname + + + + Please type the name of the new download rule. + Bitte geben Sie einen neuen Namen für die Downloadregel ein. + + + + + Rule name conflict + Namenskonflikt + + + + + A rule with this name already exists, please choose another name. + Eine Regel mit diesem Namen existiert bereits, bitte wählen SIe einen anderen Namen. + + + + Are you sure you want to remove the download rule named %1? + Sind Sie sicher, daß Sie die Downloadregel '%1' entfernen möchten? + + + + Are you sure you want to remove the selected download rules? + Sind Sie sicher, daß Sie die ausgewählten Downloadregeln entfernen möchten? + + + + Rule deletion confirmation + Löschen der Regel bestätigen + + + + Destination directory + Zielverzeichnis + + + + Invalid action + Ungültige Aktion + + + + The list is empty, there is nothing to export. + Die Liste ist leer, es gibt nichts zu exportieren. + + + + Where would you like to save the list? + Wohin möchten Sie die Liste speichern? + + + + Rules list (*.rssrules) + Regelliste (*.rssrules) + + + + I/O Error + I/O Fehler + + + + Failed to create the destination file + Fehler beim Erstellen des Zielverzeichnisses + + + + Please point to the RSS download rules file + Bitte geben Sie die RSS-Downloadregeldatei an + + + + Rules list (*.rssrules *.filters) + Regel-Liste (*.rssrules *.filters) + + + + Import Error + Fehler beim Import + + + + Failed to import the selected rules file + Import der ausgewählten Regeldatei fehlgeschlagen + + + + Add new rule... + Neue Regel hinzufügen... + + + + Delete rule + Regel löschen + + + + Rename rule... + Regel umbenennen... + + + + Delete selected rules + Ausgewählte Regeln löschen + + + + Rule renaming + Regelumbenennung + + + + Please type the new rule name + Bitte geben Sie einen neuen Namen für die Regel ein + + + + Regex mode: use Perl-like regular expressions + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 hat das gesetzte maximale Verhältnis erreicht. + + + Removing torrent %1... + Entferne Torrent %1... + + + Pausing torrent %1... + Pausiere Torret %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent lauscht auf Port: TCP/%1 + + + UPnP support [ON] + UPNP Unterstützung [EIN] + + + UPnP support [OFF] + UPnP Unterstützung [AUS] + + + NAT-PMP support [ON] + NAT-PMP Unterstützung [EIN] + + + NAT-PMP support [OFF] + NAT-PMP Unterstützung [AUS] + + + HTTP user agent is %1 + HTTP Benutzerprogramm ist %1 + + + Using a disk cache size of %1 MiB + Verwende eine Plattencachegröße von %1 MiB + + + DHT support [ON], port: UDP/%1 + DHT Unterstützung [EIN], Port: UDP/%1 + + + DHT support [OFF] + DHT Unterstützung [AUS] + + + PeX support [ON] + PeX Unterstützung [EIN] + + + PeX support [OFF] + PeX Unterstützung [AUS] + + + Restart is required to toggle PeX support + Neustart erforderlich um PeX Unterstützung umzuschalten + + + Local Peer Discovery [ON] + Lokale Peer Auffindung [EIN] + + + Local Peer Discovery support [OFF] + Unterstützung für Lokale Peer Auffindung [AUS] + + + Encryption support [ON] + Verschlüsselung Unterstützung [EIN] + + + Encryption support [FORCED] + Unterstützung für Verschlüsselung [Erzwungen] + + + Encryption support [OFF] + Verschlüsselungs-Unterstützung [AUS] + + + The Web UI is listening on port %1 + Das Webinterface lauscht auf Port %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Web User Interface Fehler - Web UI Port '%1' ist nicht erreichbar + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' wurde von der Transfer-Liste und von der Festplatte entfernt. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' wurde von der Transfer-Liste entfernt. + + + '%1' is not a valid magnet URI. + '%1' ist keine gültige Magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' befindet sich bereits in der Download-Liste. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' wird fortgesetzt. (Schnelles Fortsetzen) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' wurde der Download-Liste hinzugefügt. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Konnte Torrent-Datei nicht dekodieren: '%1' + + + This file is either corrupted or this isn't a torrent. + Diese Datei ist entweder fehlerhaft oder kein Torrent. + + + Note: new trackers were added to the existing torrent. + Bemerkung: Dem Torrent wurde ein neuer Tracker hinzugefügt. + + + Note: new URL seeds were added to the existing torrent. + Bemerkung: Dem Torrent wurden neue URL-Seeds hinzugefügt. + + + Error: The torrent %1 does not contain any file. + Fehler: Der Torret %1 enthält keineDateien. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>wurde aufgrund Ihrer IP Filter geblockt</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>wurde aufgrund von beschädigten Teilen gebannt</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekursiver Download von Datei %1, eingebettet in Torrent %2 + + + Unable to decode %1 torrent file. + Konnte Torrent-Datei %1 nicht dekodieren. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port Mapping Fehler, Fehlermeldung: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port Mapping Fehler, Meldung: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Fast-Resume Daten für den Torrent %1 wurden zurückgewiesen, prüfe erneut... + + + Reason: %1 + Begründung: %1 + + + An I/O error occured, '%1' paused. + Ein I/O Fehler ist aufgetreten, '%1' angehalten. + + + File sizes mismatch for torrent %1, pausing it. + Diskrepanz bei der Dateigröße des Torrent %1, Torrent wird angehalten. + + + Url seed lookup failed for url: %1, message: %2 + URL Seed Lookup für die URL '%1' ist fehlgeschlagen, Begründung: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Lade '%1', bitte warten... + + + + ConsoleDlg + + qBittorrent log viewer + qBittorrent Logbetrachter + + + General + Allgemein + + + Blocked IPs + Geblockte IP's + + + + CookiesDlg + + + Cookies management + Cookie Verwaltung + + + + Key + As in Key/Value pair + Schlüssel + + + + Value + As in Key/Value pair + Wert + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Gängige Schlüssel für Cookies sind: '%1', '%2'. +Sie sollten diese Information aus den Voreinstellungen Ihres Webbrowsers erhalten. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + + + + + Dynamic DNS error: Invalid username/password. + + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: Your username was blocked due to abuse. + + + + + Dynamic DNS error: supplied domain name is invalid. + + + + + Dynamic DNS error: supplied username is too short. + + + + + Dynamic DNS error: supplied password is too short. + + + + + DownloadThread + + + + I/O Error + I/O Fehler + + + + The remote host name was not found (invalid hostname) + Der Hostname konnte nicht gefunden werden (ungültiger Hostname) + + + + The operation was canceled + Die Operation wurde abgebrochen + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Der Server hat die Verbindung beendet bevor die gesamte Antwort empfangen und verarbeitet werden konnte + + + + The connection to the remote server timed out + Zeitüberschreitung bei der Verbindung mit dem Server + + + + SSL/TLS handshake failed + SSL/TLS Handshake fehlgeschlagen + + + + The remote server refused the connection + Der Server hat die Verbindung verweigert + + + + The connection to the proxy server was refused + Die Verbindung zum Proxy-Server wurde verweigert + + + + The proxy server closed the connection prematurely + Der Proxy-Server hat die Verbindung vorzeitig beendet + + + + The proxy host name was not found + Der Proxy-Hostname wurde nicht gefunden + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Zeitüberschreitung beim Verbindungsaufbau mit dem Proxy oder der Proxy hat nicht in angemessener Zeit auf die Anfrage reagiert + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Der Proxy benötigt Authentifizierung hat jedoch keine der angebotenen Zugangsdaten akzeptiert + + + + The access to the remote content was denied (401) + Der Zugriff auf den Inhalt wurde verweigert (401) + + + + The operation requested on the remote content is not permitted + Die Operation ist nicht erlaubt + + + + The remote content was not found at the server (404) + Der Inhalte wurde auf dem Server nicht gefunden (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Der Server verlangt Authentifizierung, aber die angebotenen Zugangsdaten wurden nicht akzeptiert + + + + The Network Access API cannot honor the request because the protocol is not known + Die Network-Access-API konnte die Anfrage nicht bearbeiten, unbekanntes Protokoll + + + + The requested operation is invalid for this protocol + Die angeforderte Operation ist ungütlig für dieses Protokoll + + + + An unknown network-related error was detected + Ein unbekannter Netzwerk-Fehler ist aufgetreten + + + + An unknown proxy-related error was detected + Ein unbekannter Proxy-Fehler ist aufgetreten + + + + An unknown error related to the remote content was detected + Unbekannter Fehler in Zusammenhang mit dem Inhalt ist aufgetreten + + + + A breakdown in protocol was detected + Es ist eine Störung im Protokoll aufgetreten + + + + Unknown error + Unbekannter Fehler + + + + EventManager + + + + Working + Funktioniert + + + + Updating... + Aktualisiere... + + + + + Not working + Funktioniert nicht + + + + + Not contacted yet + Noch nicht kontaktiert + + + + + this session + Diese Session + + + + + /s + /second (i.e. per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + Geseeded seit %1 + + + + %1 max + e.g. 10 max + %1 max + + + + + %1/s + e.g. 120 KiB/s + %1/Sekunde + + + + ExecutionLog + + + General + Allgemein + + + + Blocked IPs + Geblockte IPs + + + + FeedDownloader + + RSS Feed downloader + RSS-Feed-Downloader + + + RSS feed: + RSS-Feed: + + + Feed name + Feed-Name + + + Automatically download torrents from this feed + Torrents von diesem Feed automatisch laden + + + Download filters + Download-Filter + + + Filters: + Filter: + + + Filter settings + Filter-Einstellungen + + + Matches: + Übereinstimmungen: + + + Does not match: + Stimmt nicht überein: + + + Destination folder: + Zielverzeichnis: + + + ... + ... + + + Filter testing + Teste Filter + + + Torrent title: + Torrent-Titel: + + + Result: + Ergebnis: + + + Test + Test + + + Import... + Import... + + + Export... + Export... + + + Rename filter + Filter umbenennen + + + Remove filter + Filter löschen + + + Add filter + Filter hinzufügen + + + + FeedDownloaderDlg + + New filter + Neuer Filter + + + Please choose a name for this filter + Bitte wählen Sie einen Namen für diesen Filter + + + Filter name: + Filter-Name: + + + Invalid filter name + Ungültiger Filter-Name + + + The filter name cannot be left empty. + Der Filter-Name darf nicht leer sein. + + + This filter name is already in use. + Dieser Filter-Name wird bereits verwendet. + + + Choose save path + Wählen Sie den Speicher-Pfad + + + Filter testing error + Fehler beim testen des Filters + + + Please specify a test torrent name. + Bitte geben Sie einen Torrent-Namen zum testen ein. + + + matches + stimmt überein + + + does not match + stimmt nicht überein + + + Select file to import + Wählen Sie eine Datei für den Import + + + Filters Files + Filter-Dateien + + + Import successful + Import erfolgreich + + + Filters import was successful. + Filter wurden erfolgreich importiert. + + + Import failure + Fehler beim Import + + + Filters could not be imported due to an I/O error. + Filter konnte nicht importiert werden aufgrund eines I/O Fehlers. + + + Select destination file + Zieldatei auswählen + + + Export successful + Export erfolgreich + + + Filters export was successful. + Filter wurden erfolgreich exportiert. + + + Export failure + Fehler beim Export + + + Filters could not be exported due to an I/O error. + Filter konnte nicht exportiert werden aufgrund eines I/O Fehlers. + + + + FeedList + + Unread + Ungelesen + + + + FeedListWidget + + + RSS feeds + RSS-Feeds + + + + Unread + Ungelesen + + + + GUI + + qBittorrent + qBittorrent + + + Open Torrent Files + Öffne Torrent-Dateien + + + Torrent Files + Torrent-Dateien + + + Transfers + Übertragungen + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + DL Geschwindigkeit: %1 KB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + UP Geschwindigkeit: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 vollständig heruntergeladen. + + + I/O Error + i.e: Input/Output Error + I/O Error + + + Search + Suche + + + Torrent file association + Verbindung zu Torrent Datei + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent ist nicht die Standard Applikation um Torrent Dateien oder Magnet Links zu öffnen. Möchten Sie Torrent Dateien und Magnet Links immer mit qBittorent öffnen? + + + RSS + RSS + + + Transfers (%1) + Übertragungen (%1) + + + Download completion + Beendigung des Download + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Ein I/O Fehler ist aufegtreten für die Torrent Datei %1. Ursache: %2 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Recursive download confirmation + Rekursiven Downlaod bestätigen + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Der Torrent %1 enthält Torrent Dateien, möchten Sie mit dem Download fortfahren? + + + A newer version is available + Eine neuere Version ist erhältlich + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Eine neuere Version von qBittorrent ist auf Sourceforge erhätlich. Möchten Sie qBittorent auf die Version %1 aktualisieren? + + + Impossible to update qBittorrent + Aktuialisierung von qBittorrent nicht möglich + + + qBittorrent failed to update, reason: %1 + qBittorrent konnte nicht aktualisiert werden, Begründung: %1 + + + Exiting qBittorrent + Beende qBittorrent + + + Always + Immer + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + URL Download Fehler + + + Couldn't download file at url: %1, reason: %2. + Konnte Datei von URL: %1 nicht laden, Begründung: %2. + + + Ctrl+F + shortcut to switch to search tab + Strg+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Yes + Ja + + + No + Nein + + + Never + Niemals + + + Global Upload Speed Limit + Globale UL-Rate + + + Global Download Speed Limit + Globale DL-Rate + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Zur Zeit werden Dateien übertragen. +Sind Sie sicher, daß sie qBittorrent beenden möchten? + + + Options were saved successfully. + Optionen wurden erfolgreich gespeichert. + + + + GeoIP + + Australia + Australien + + + Argentina + Argentinien + + + Austria + Österreich + + + United Arab Emirates + Vereinigte Arabische Emirate + + + Brazil + Brasilien + + + Bulgaria + Bulgarien + + + Belarus + Weißrussland + + + Belgium + Belgien + + + Bosnia + Bosniene + + + Canada + Kanada + + + Czech Republic + Tschechische Republik + + + China + China + + + Costa Rica + Costa Rica + + + Switzerland + Schweiz + + + Germany + Deutschland + + + Denmark + Dänemark + + + Algeria + Algerien + + + Spain + Spanien + + + Egypt + Ägypten + + + Finland + Finnland + + + France + Frankreich + + + United Kingdom + Vereinigtes Königreich + + + Greece + Griechenland + + + Georgia + Georgien + + + Hungary + Ungarn + + + Croatia + Kroatien + + + Italy + Italien + + + India + Indien + + + Israel + Israel + + + Ireland + Irland + + + Iceland + Island + + + Indonesia + Indonesien + + + South Korea + Südkorea + + + Luxembourg + Luxemburg + + + Serbia + Serbien + + + Morocco + Marokko + + + Netherlands + Niederlande + + + Norway + Norwegen + + + New Zealand + Neu Seeland + + + Portugal + Portugal + + + Poland + Polen + + + Philippines + Philippinen + + + Russia + Russland + + + Romania + Romänien + + + France (Reunion Island) + Frankreich (Reunion) + + + Saudi Arabia + Saudi Arabien + + + Sweden + Schweden + + + Slovakia + Slovakei + + + Singapore + Singapur + + + Slovenia + Slovenien + + + Turkey + Türkei + + + South Africa + Südafrika + + + + HeadlessLoader + + + Information + + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Um qBittorrent zu steuern benutzen Sie bitte das Webinterface unter http://localhost:%1 + + + + The Web UI administrator user name is: %1 + Benutzername des Webinterface-Administrators: %1 + + + + The Web UI administrator password is still the default one: %1 + Das Passwort des Webinterface-Administrators ist immer noch die Standardeinstellung: %1 + + + + This is a security risk, please consider changing your password from program preferences. + Dies ist eine Sicherheitslücke, bitte ändern Sie das Passwort über die Programmvoreinstellungen. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + Ihre IP Adresse wurde nach zu vielen fehlerhaften Authentisierungversuchen gebannt. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + How are we supposed to translate this? Do you want the initial letter of a translation of the hint you gave in the developer comments? Are there going to be any tooltips that will help the user understand the abbreviation? + + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + see comment on D: %1/s - T: %2 + + + + + HttpServer + + + File + Datei + + + + Edit + Bearbeiten + + + + Help + Hilfe + + + Delete from HD + Von der Festplatte löschen + + + + Download Torrents from their URL or Magnet link + Lade Torrents von URL oder Magnet-Link + + + + Only one link per line + Nur ein Link pro Zeile + + + + Download local torrent + Lade lokalen Torrent + + + + Torrent files were correctly added to download list. + Torrents wurden der Download-Liste erfolgreich hinzugefügt. + + + + Point to torrent file + Zeige auf Torrent Datei + + + + Download + + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Sind Sie sicher, daß Sie die ausgewählten Torrents von der Transfer-Liste und der Festplatte entfernen möchten? + + + + Download rate limit must be greater than 0 or disabled. + Begrenzung der Downloadrate muss größer als 0 sein oder deaktiviert werden. + + + + Upload rate limit must be greater than 0 or disabled. + Begrenzung der Uploadrate muss größer als 0 sein oder deaktiviert werden. + + + + Maximum number of connections limit must be greater than 0 or disabled. + Maximale Anzahl der Verbindungen muss größer als 0 sein oder deaktiviert werden. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Maximale Anzahl der Verbindungen pro Torrent muss größer als 0 sein oder deaktiviert werden. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Maximale Anzahle der Upload-Slots muss größer als 0 sein oder deaktiviert werden. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Konnte Programmeinstellungen nicht speichern, qBittorrent ist vermutlich nicht erreichbar. + + + + Language + Sprache + + + + Downloaded + Is the file downloaded or not? + Runtergeladen + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Der Port für eingehende Verbindungen muss grösser als 1024 und kleiner als 65535 sein. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Der Port für das Webinterface muss grösser als 1024 und kleiner als 65535 sein. + + + + The Web UI username must be at least 3 characters long. + Der Benutzername für das Webinterface muss mindestens 3 Zeichen lang sein. + + + + The Web UI password must be at least 3 characters long. + Das Passwort für das Webinterface muss mindestens 3 Zeichen lang sein. + + + + Save + Speichern + + + + qBittorrent client is not reachable + qBittorrent-Client ist nicht erreichbar + + + + HTTP Server + + + + + The following parameters are supported: + + + + + Torrent path + + + + + Torrent name + + + + + LegalNotice + + + Legal Notice + Rechtshinweis + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent ist ein Filesharing Programm. Sobald ein Torrent bei Ihnen läuft, stellen Sie den Inhalt auch anderen zur Verfügung. Selbstverständlich geschieht das Teilen jeglicher Inhalte auf Ihre eigene Verantwortung. + +Wahrscheinlich haben wir Ihnen hiermit nichts Neues erzählt und werden Sie auch nicht wieder darauf hinweisen. + + + + Press %1 key to accept and continue... + Zum bestätigen und fortfahren bitte %1-Taste drücken... + + + + Legal notice + Rechtshinweis + + + + Cancel + Abbrechen + + + + I Agree + Ich stimme zu + + + + LineEdit + + + Clear the text + Text löschen + + + + MainWindow + + + &Edit + &Bearbeiten + + + + &Help + &Hilfe + + + + &Tools + &Werkzeuge + + + + &File + &Datei + + + + &View + &Ansicht + + + &Add File... + &Datei hinzufügen... + + + E&xit + Beenden + + + + &Options... + &Optionen... + + + Add &URL... + &URL hinzufügen... + + + + Torrent &creator + Torrent &Erschaffer + + + + Set upload limit... + Upload Limit setzen... + + + + Set download limit... + Download Limit setzen... + + + Shutdown qBittorrent when downloads complete + qBittorent beenden wenn Downloads vollständig sind + + + + &About + &Über + + + + &Pause + &Anhalten + + + + &Delete + &Löschen + + + + P&ause All + A&lle anhalten + + + + &Resume + &Fortsetzen + + + + &Add torrent file... + Torrent-Datei &hinzufügen... + + + + + Exit + Beenden + + + + R&esume All + Alle forts&etzen + + + + Visit &Website + &Website aufrufen + + + + Auto-Shutdown on downloads completion + Automatisches herunterfahren wenn Dowloads vollständig sind + + + + Add &link to torrent... + &Link zu Torrent hinzufügen... + + + + Report a &bug + &Bug melden + + + + &Documentation + &Dokumentation + + + + Set global download limit... + Globales Downlaod Limit setzen... + + + + Set global upload limit... + Globals Upload Limit setzen... + + + &Log viewer... + &Log Betrachter... + + + Log viewer + Log Betrachter + + + Shutdown computer when downloads complete + Computer herunterfahren wenn Dowloads vollständig sind + + + + + Lock qBittorrent + qBittorrent sperren + + + + Ctrl+L + + + + + Import existing torrent... + Existierendes Torrent importieren... + + + + Import torrent... + Torrent importieren... + + + + Donate money + Spenden + + + + If you like qBittorrent, please donate! + Bitte spenden Sie wenn Ihnen qBittorrent gefällt! + + + + Execution &Log + Ausführungs-&Log + + + + + Execution Log + Ausführungs-Log + + + + Exit qBittorrent + Beende qBittorrent + + + + Suspend system + System anhalten + + + + Shutdown system + System herunterfahren + + + + Disabled + Deaktiviert + + + + + Alternative speed limits + Alternative Geschwindigkeitsbegrenzung + + + + &RSS reader + &RSS Reader + + + + Search &engine + Such&maschine + + + + Top &tool bar + Obere Werk&zeugleiste + + + + Display top tool bar + Zeige obere Werkzeugleiste + + + + &Speed in title bar + &Geschwindigkeit in der Titelleiste + + + + Show transfer speed in title bar + Übertragungsgeschwindigkeit in der Titelleiste anzeigen + + + Preview file + Vorschau Datei + + + Clear log + Log löschen + + + + Decrease priority + Verringere Priorität + + + + Increase priority + Erhöhe Prorität + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + Passwort setzen... + + + + Transfers + Übertragungen + + + + Torrent file association + Assoziation zur Torrent Datei + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent ist nicht die Standardapplikation um Torrent Dateien oder Magnet Links zu öffnen. +Möchten Sie Torrent Dateien und Magnet Links immer mit qBittorent öffnen? + + + + + + UI lock password + Passwort um das User Interface zu sperren + + + + + + Please type the UI lock password: + Bitte geben Sie das Passwort für das User Interface ein: + + + + The password should contain at least 3 characters + Das Passwort sollte aus mindestens drei Zeichen bestehen + + + + Password update + Passwort aktualisieren + + + + The UI lock password has been successfully updated + Das Passwort zum sperren des User Interface wurde erfolgreich aktualisiert + + + + RSS + RSS + + + + Search + Suche + + + + Transfers (%1) + + + + + Download completion + Download beendigen + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 wurde heruntergeladen. + + + + I/O Error + i.e: Input/Output Error + I/O Fehler + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Im Torrent %1 ist einI/O Fehler aufgetreten. Ursache: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Strg+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Rekursiven Download bestätigen + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Der Torrent %1 enthält weitere Torrent Dateien, möchten Sie diese herunterladen? + + + + + Yes + Ja + + + + + No + Nein + + + + Never + Niemals + + + + Url download error + Fehler beim Laden der URL + + + + Couldn't download file at url: %1, reason: %2. + Konnte Datei von URL: %1 nicht laden, Begründung: %2. + + + + Global Upload Speed Limit + Globale Begrenzung der Uploadgeschwindigkeit + + + + Global Download Speed Limit + Globale Begrenzung der Downloadgeschwindigkeit + + + + + Invalid password + Ungültiges Passwort + + + + The password is invalid + Das Passwort ist ungültig + + + + Exiting qBittorrent + Beende qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Zur Zeit werden Dateien übertragen. +Sind Sie sicher, daß sie qBittorrent beenden möchten? + + + + Always + Immer + + + + Open Torrent Files + Öffne Torrent-Dateien + + + + Torrent Files + Torrent-Dateien + + + + Options were saved successfully. + Einstellungen wurden erfolgreich gespeichert. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Downloadgeschwindigkeit: %1 KB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Uploadgeschwindigkeit: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + + + + + A newer version is available + Eine neuere Version ist erhältlich + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Eine neuere Version von qBittorrent ist auf Sourceforge erhätlich. Möchten Sie qBittorent auf die Version %1 aktualisieren? + + + + Impossible to update qBittorrent + Aktuialisierung von qBittorrent nicht möglich + + + + qBittorrent failed to update, reason: %1 + qBittorrent konnte nicht aktualisiert werden, Begründung: %1 + + + + PeerAdditionDlg + + + Invalid IP + Ungültige IP + + + + The IP you provided is invalid. + Die angegebene IP ist ungültig. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + + + + + Connection + Verbindung + + + + Client + i.e.: Client application + + + + + Progress + i.e: % downloaded + Fortschritt + + + + Down Speed + i.e: Download speed + DL-Rate + + + + Up Speed + i.e: Upload speed + UL-Rate + + + + Downloaded + i.e: total data downloaded + Runtergeladen + + + + Uploaded + i.e: total data uploaded + Hochgeladen + + + + Add a new peer... + Füge einen neuen Peer hinzu... + + + + Copy IP + IP kopieren + + + + Limit download rate... + Downloadrate begrenzen... + + + + Limit upload rate... + Uploadrate begrenzen... + + + + Ban peer permanently + Peer dauerhaft bannen + + + + + Peer addition + Peer hinzufügen + + + + The peer was added to this torrent. + Der Peer wurde diesem Torrent hinzugefügt. + + + + The peer could not be added to this torrent. + Der Peer konnte diesem Torrent nicht hinzugefügt werden. + + + + Are you sure? -- qBittorrent + Sind Sie sicher? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Sind Sie sicher, daß Sie die ausgewählten Peers dauferhaft bannen möchten? + + + + &Yes + &Ja + + + + &No + &Nein + + + + Manually banning peer %1... + Peer %1 von Hand bannen... + + + + Upload rate limiting + Begrenzung der Uploadrate + + + + Download rate limiting + Begrenzung der Downloadrate + + + + Preferences + + + Downloads + + + + + Connection + Verbindung + + + + Web UI + Webinterface + + + Language: + Sprache: + + + + (Requires restart) + (Neustart benötigt) + + + Visual style: + Visueller Stil: + + + Transfer list + Transferliste + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Abwechselnde Reihenfarben verwenden + + + + Tray icon style: + + + + + Normal + Normal + + + + Monochrome (Dark theme) + + + + + Monochrome (Light theme) + + + + File system + Datei System + + + + Copy .torrent files to: + .torrent Datei kopieren nach: + + + + This server requires a secure connection (SSL) + + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + + + + + Listening Port + + + + + Connections Limits + + + + + Proxy Server + + + + + Otherwise, the proxy server is only used for tracker connections + + + + + Use proxy for peer connections + + + + + Global Rate Limits + + + + + Apply rate limit to uTP connections + + + + + Apply rate limit to transport overhead + + + + + Alternative Global Rate Limits + + + + + Schedule the use of alternative rate limits + + + + + Enable Local Peer Discovery to find more peers + Lokale Peer Auffindung aktivieren um mehr peers zu finden + + + + Encryption mode: + Verschlüsselungsmodus: + + + + Prefer encryption + Verschlüsselung bevorzugen + + + + Require encryption + Verschlüsselung verlangen + + + + Disable encryption + Verschlüsselng deaktiviere + + + Torrent queueing + Torrent Warteschlangen + + + + Maximum active downloads: + Maximal aktive Downloads: + + + + Maximum active uploads: + Maximal aktive Uploads: + + + + Maximum active torrents: + Maximal aktive Torrents: + + + + When adding a torrent + Sobald ein Torrent hinzugefügt wird + + + Visual Appearance + Visuelles Erscheinungsbild + + + + Action on double-click + Aktion bei Doppelklick + + + + Downloading torrents: + Lade Torrents: + + + Start / Stop + Start / Stop + + + + + Open destination folder + Zielverzeichnis öffnen + + + + Completed torrents: + Abgeschlossene Torrents: + + + + Desktop + Screibtisch + + + + Show splash screen on start up + Splash Screen beim Start zeigen + + + + Start qBittorrent minimized + qBittorrent minimiert starten + + + Show qBittorrent icon in notification area + qBittorrent Icon im Benachrichtigungsbereich zeigen + + + + Minimize qBittorrent to notification area + qBittorrent in den Benachrichtigungsbereich minimieren + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + qBittorrent in den Benachrichtigungsbereich schliessen + + + + Display torrent content and some options + Zeige Inhalt des Torrent und einige Optionen + + + Listening port + Port auf dem gelauscht wird + + + + Port used for incoming connections: + Port für eingehende Verbindungen: + + + + Random + Zufällig + + + Enable UPnP port mapping + UPnP Port Mapping aktivieren + + + Enable NAT-PMP port mapping + NAP-PMP Port Mapping aktivieren + + + Connections limit + Verbindungsbeschränkung + + + + Global maximum number of connections: + Global maximale Anzahl der Verbindungen: + + + + Maximum number of connections per torrent: + Maximale Anzahl der Verbindungen pro Torrent: + + + + Maximum number of upload slots per torrent: + Maximale Anzahl Upload-Slots pro Torrent: + + + + + Upload: + + + + + + Download: + + + + + + + + KiB/s + + + + Bittorrent features + Bittorrent Funktionen + + + Enable DHT network (decentralized) + DHT Netzwerk aktivieren (dezentralisiert) + + + Use a different port for DHT and Bittorrent + Unterschiedliche Ports für DHT und Bittorrent verwenden + + + + DHT port: + DHT Port: + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Peers mit kompatiblen Bittorrent Clients austauchen (µTorrent, Vuze, ...) + + + Enable Peer Exchange / PeX (requires restart) + Peer Exchange / PeX aktivieren (erfordert Neustart) + + + Enable Local Peer Discovery + Lokale Peer Auffindung aktivieren + + + Enabled + Aktiviert + + + Forced + Erzwungen + + + Disabled + Deaktiviert + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP Kommunikation (Tracker, Web-Seeds, Suchmaschine) + + + + Host: + + + + Peer Communications + Peer Kommunikation + + + + SOCKS4 + + + + + Type: + Typ: + + + + + Options + Optionen + + + + + Behavior + Verhalten + + + + Speed + Geschwindigkeit + + + + Advanced + Fortgeschritten + + + + User Interface Language: + + + + + Transfer List + + + + + + No action + Keine Aktion + + + + Append .!qB extension to incomplete files + + + + + Remove folder + Verzeichnis entfernen + + + Global speed limits + Globale Geschwindigkeitsbegrenzung + + + Alternative global speed limits + Alternative globale Geschwindigkeitsbegrenzung + + + + to + time1 to time2 + bis + + + + Do not start the download automatically + The torrent will be added to download list in pause state + Download nicht automatisch starten + + + User Interface + Benutzerschnittstelle + + + + BitTorrent + + + + + Language + Sprache + + + + + Start / Stop Torrent + + + + Use monochrome system tray icon (requires restart) + Monochrome Systemtray-Icons verwenden (Neustart benötigt) + + + + Ask for program exit confirmation + Beenden bestätigen + + + + Show qBittorrent in notification area + + + + + Power Management + + + + + Inhibit system sleep when torrents are active + Das System davon abhalten in den Schlafmodus zu gehen, wenn noch Torrents aktiv sind + + + + Hard Disk + + + + + Save files to location: + Datei an diesem Ort speichern: + + + + Append the label of the torrent to the save path + Label des Torrents an den Speicherpfad anhängen + + + + Pre-allocate disk space for all files + Allen Dateien Speicherplatz im vorhinein zuweisen + + + + Keep incomplete torrents in: + Unvollständige Torrents speichern in: + + + Append .!qB extension to incomplete files' names + Die Dateienung .!qb an unvollständige Dateinamen anhängen + + + + Automatically add torrents from: + Dateien mit der Endung .torrent aus diesem Verzeichnis automatisch hinzufügen: + + + + Add folder... + Verzeichnis hinzufügen... + + + + Email notification upon download completion + Email Benachrichtigung wenn Download vollständig ist + + + + Destination email: + Zieladresse: + + + + SMTP server: + SMTP Server: + + + + Run an external program on torrent completion + Externes Programm ausführen wenn Torrent vollständig ist + + + Use %f to pass the torrent path in parameters + Verwenden Sie %f um den Torrentpfad als Parameter zu übergeben + + + + Use UPnP / NAT-PMP port forwarding from my router + UPnP / NAT-PMP Port Wieterleitung meines Routers verwenden + + + Proxy server + Proxyserver + + + + IP Filtering + + + + + Reload the filter + Filter neu laden + + + Schedule the use of alternative speed limits + Benutzung von alternativen Geschwindigkeitsbegrenzungen einteilen + + + + from + from (time1 to time2) + von + + + + When: + Wann: + + + + Every day + Jeden Tag + + + + Week days + Wochentage + + + + Week ends + Wochenenden + + + + Privacy + Privatsphäre + + + + Enable DHT (decentralized network) to find more peers + DHT (dezentralisiertes Netzwerk) aktivieren um mehr Peers zu finden + + + + Use a different port for DHT and BitTorrent + Unterschiedliche Ports für DHT und BitTorrent verwenden + + + + Enable Peer Exchange (PeX) to find more peers + Peer Exchange (PeX) aktivieren um mehr Peers zu finden + + + + Look for peers on your local network + Nach Peers im lokalen Netzwek suchen + + + + Torrent Queueing + + + + + Share Ratio Limiting + + + + + Use UPnP / NAT-PMP to forward the port from my router + + + + + Use HTTPS instead of HTTP + + + + + Import SSL Certificate + + + + + Import SSL Key + + + + + Certificate: + + + + + Key: + + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + Bypass authentication for localhost + Authentifizierung für localhost umgehen + + + + Update my dynamic domain name + + + + + Service: + + + + + Register + + + + + Domain name: + + + + Protocol encryption: + Protokoll-Verschlüsselung: + + + Share ratio limiting + Shareverhältnis Begrenzung + + + + Seed torrents until their ratio reaches + Torrents seeden bis diese Verhältnis erreicht wurde + + + + then + dann + + + + Pause them + Anhalten + + + + Remove them + Entfernen + + + + (None) + (Keine) + + + + HTTP + + + + + + Port: + + + + + + + Authentication + Authentifizierung + + + + + + + Username: + Benutzername: + + + + + + + Password: + Passwort: + + + + Enable bandwidth management (uTP) + + + + + Enable Web User Interface (Remote control) + Webuser-Interface einschalten (Fernbedienung) + + + + SOCKS5 + + + + + Filter path (.dat, .p2p, .p2b): + Pfad zur Filterdatei (.dat, .p2p, p2b): + + + + PreviewSelect + + + Name + + + + + Size + Größe + + + + Progress + Fortschritt + + + + + + Preview impossible + Vorschau nicht möglich + + + + + + Sorry, we can't preview this file + Bedauere, es kann keine Vorschau für diese Datei erstellen werden + + + + ProgramUpdater + + Could not create the file %1 + Die Datei %1 konnte nicht erstellt werden + + + Failed to download the update at %1 + %1 is an URL + Dowload des Update von %1 fehlgeschlagen + + + + PropListDelegate + + + + Normal + Normal (priority) + Normal + + + + + High + High (priority) + Hoch + + + + Mixed + Mixed (priorities + Gemischt + + + + Not downloaded + Nicht heruntergeladen + + + + + Maximum + Maximum (priority) + Maximum + + + + PropTabBar + + + General + Allgemein + + + + Trackers + Tracker + + + + Peers + + + + + HTTP Sources + HTTP Quellen + + + + Content + Inhalt + + + Files + Dateien + + + + PropertiesWidget + + + Save path: + Speicher-Pfad: + + + + Torrent hash: + Torrent Prüfsumme: + + + + Comment: + Kommentar: + + + + Share ratio: + Share Verhältnis: + + + + + Downloaded: + Runtergeladen: + + + + Availability: + Erreichbarkeit: + + + + Transfer + Übertragungen + + + + Uploaded: + Hochgeladen: + + + + Wasted: + Verworfen: + + + + Time active: + Time (duration) the torrent is active (not paused) + Aktiv seit: + + + + Pieces size: + Größe der Teile: + + + + Torrent content: + Inhalt des Torrent: + + + + Select All + Alle Auswählen + + + + Select None + Keine Auswählen + + + + + Do not download + Nicht herunterladen + + + + UP limit: + UL-Limit: + + + + DL limit: + DL-Limit: + + + Time elapsed: + Zeitverlauf: + + + + Connections: + Verbindungen: + + + + Reannounce in: + Bekanngeben in: + + + + Information + + + + + Created on: + Erstellt am: + + + General + Allgemein + + + Trackers + Tracker + + + URL seeds + URL Seeds + + + Files + Dateien + + + + Priority + Priorität + + + + Normal + Normal + + + + Maximum + Maximum + + + + High + Hoch + + + + + this session + diese Sitzung + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Geseeded seit %1 + + + + %1 max + e.g. 10 max + + + + + + I/O Error + + + + + This file does not exist yet. + Diese Datei existiert noch nicht. + + + + This folder does not exist yet. + Dieses Verzeichnis existiert noch nicht. + + + + Rename... + Umbenennen... + + + + Rename the file + Datei umbenennen + + + + New name: + Neuer Name: + + + + + The file could not be renamed + Die Datei konnte nicht umbenannt werden + + + + This file name contains forbidden characters, please choose a different one. + Der Dateiname enthält ungültige Zeichen, bitte einen anderen wählen. + + + + + This name is already in use in this folder. Please use a different name. + Der Dateiname wird in diesem Verzeichnis bereits verwendet. Bitte anderen wählen. + + + + The folder could not be renamed + Das Verzeichnis konnte nicht umbenannt werden + + + + New url seed + New HTTP source + Neuer URL Seed + + + + New url seed: + Neuer URL Seed: + + + + qBittorrent + + + + + This url seed is already in the list. + Dieser URL Seed befindet sich bereits in der Liste. + + + + + Choose save path + Wählen Sie den Speicher-Pfad + + + Save path creation error + Fehler beim Erstellen des Speicher-Pfades + + + Could not create the save path + Speicher-Pfad konnte nicht erstellt werden + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 hat das gesetzte maximale Verhältnis erreicht. + + + + Removing torrent %1... + Entferne Torrent %1... + + + + Pausing torrent %1... + Torrent %1 anhalten... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent lauscht auf Port: TCP/%1 + + + UPnP support [ON] + UPNP Unterstützung [EIN] + + + UPnP support [OFF] + UPnP Unterstützung [AUS] + + + NAT-PMP support [ON] + NAT-PMP Unterstützung [EIN] + + + NAT-PMP support [OFF] + NAT-PMP Unterstützung [AUS] + + + + HTTP user agent is %1 + HTTP Benutzerschnittstelle ist %1 + + + Using a disk cache size of %1 MiB + Verwende eine Plattencachegröße von %1 MiB + + + + DHT support [ON], port: UDP/%1 + DHT Unterstützung [EIN], Port: UDP/%1 + + + + + DHT support [OFF] + DHT Unterstützung [AUS] + + + + PeX support [ON] + PeX Unterstützung [EIN] + + + + PeX support [OFF] + PeX Unterstützung [AUS] + + + + Restart is required to toggle PeX support + Neustart erforderlich um PeX Unterstützung umzuschalten + + + Local Peer Discovery [ON] + Lokale Peers finden [EIN] + + + + Local Peer Discovery support [OFF] + Lokale Peers finden [AUS] + + + + Encryption support [ON] + Verschlüsselung [EIN] + + + + Encryption support [FORCED] + Verschlüsselung [Erzwungen] + + + + Encryption support [OFF] + Verschlüsselung [AUS] + + + + Embedded Tracker [ON] + Eingebetter Tracker [EIN] + + + + Failed to start the embedded tracker! + Starten des eingebetteten Trackers fehlgeschlagen! + + + + Embedded Tracker [OFF] + Eingebetter Tracker [AUS] + + + + The Web UI is listening on port %1 + Das Webinterface lauscht auf Port %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Fehler im Webinterface - Webinterface konnte nicht an Port %1 gebunden werden + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' wurde von der Transferliste und von der Festplatte entfernt. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' wurde von der Transferliste entfernt. + + + + '%1' is not a valid magnet URI. + '%1' ist keine gültige Magnet URI. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' befindet sich bereits in der Downloadliste. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' fortgesetzt. (Schnelles Fortsetzen) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' der Downloadliste hinzugefügt. + + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP Unterstützung [EIN] + + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP Unterstützung [AUS] + + + + Reporting IP address %1 to trackers... + IP Adresse %1 dem Tracker melden... + + + + Local Peer Discovery support [ON] + Lokale Peers finden [EIN] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Konnte Torrentdatei nicht dekodieren: '%1' + + + + This file is either corrupted or this isn't a torrent. + Diese Datei ist entweder fehlerhaft oder kein Torrent. + + + + Error: The torrent %1 does not contain any file. + Fehler: Der Torret %1 enthält keine Dateien. + + + + Note: new trackers were added to the existing torrent. + Bemerkung: Dem Torrent wurden neue Tracker hinzugefügt. + + + + Note: new URL seeds were added to the existing torrent. + Bemerkung: Dem Torrent wurden neue URL-Seeds hinzugefügt. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>wurde aufgrund Ihrer IP Filter geblockt</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>wurde aufgrund von beschädigten Teilen gebannt</i> + + + + The network interface defined is invalid: %1 + Das angegeben Netzwerkinterface ist ungültig: %1 + + + + Trying any other network interface available instead. + Versuche stattdessen ein anderes verfügbares Netzwerkinterface. + + + + Listening on IP address %1 on network interface %2... + Lausche unter der IP Adresse %1 auf Netzwerkinterface %2... + + + + Failed to listen on network interface %1 + An Netzwerkinterface %1 lauschen fehlgeschlagen + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekursiver Download von Datei %1, eingebettet in Torrent %2 + + + + + Unable to decode %1 torrent file. + Konnte Torrentdatei %1 nicht dekodieren. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Der Computer wird in 15 Sekunden in den Schlafmodus wechseln... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Der Computer wird in 15 Sekunden ausgeschaltet... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent wird in 15 Sekunden beendet... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + IP-Filter erfolgreich geparsed: %1 Regeln wurden angewandt. + + + + Error: Failed to parse the provided IP filter. + Fehler: IP-Filter konnte nicht geparsed werden. + + + + Torrent name: %1 + Name des Torrent: %1 + + + + Torrent size: %1 + Größe des Torrent: %1 + + + + Save path: %1 + Speicherpfad: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Der Torrent wurde in %1 heruntergeladen. + + + + Thank you for using qBittorrent. + Danke, daß Sie qBittorrent benutzen. + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 vollständig heruntergeladen + + + + An I/O error occured, '%1' paused. + Ein I/O Fehler ist aufgetreten, '%1' angehalten. + + + + + Reason: %1 + Begründung: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Portmappingfehler, Fehlermeldung: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Portmapping erfolgreich, Meldung: %1 + + + + File sizes mismatch for torrent %1, pausing it. + Dateigrößen des Torrent %1 stimmen nicht überein, wird angehalten. + + + + Fast resume data was rejected for torrent %1, checking again... + Fast-Resume des Torrent %1 wurde zurückgewiesen, prüfe erneut... + + + + Url seed lookup failed for url: %1, message: %2 + URL Seed Lookup für die URL '%1' ist fehlgeschlagen, Begründung: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Lade '%1', bitte warten... + + + + RSS + + + Search + Suche + + + + New subscription + Neues Abonnement + + + + + + Mark items read + Markiere Einträge als gelesen + + + + Update all + Aktualisiere alle + + + + RSS Downloader... + + + + + Settings... + Einstellungen... + + + Feed URL + Feed-URL + + + + Rename... + Umbenennen... + + + + + Update + Aktualisieren + + + RSS feed downloader... + RSS-Feed-Downloader... + + + + New folder... + Neuer Ordner... + + + + Manage cookies... + Cookies verwalten... + + + RSS feeds + RSS-Feeds + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(Doppelklick zum downloaden)</span></p></body></html> + + + Article title + Artikeltitel + + + + New subscription... + Neues Abonnement... + + + + + Update all feeds + Aktualisiere alle Feeds + + + + + Delete + Löschen + + + + Rename + Umbenennen + + + + Download torrent + Lade Torrent + + + + Open news URL + Öffne News-URL + + + + Copy feed URL + Kopiere Feed-URL + + + + Refresh RSS streams + Aktualisiere RSS Streams + + + + RSSImp + + + Please type a rss stream url + Bitte eine RSS Stream Adresse eingeben + + + + Stream URL: + Stream URL: + + + + + Are you sure? -- qBittorrent + Sind Sie sicher? -- qBittorrent + + + + + &Yes + &Ja + + + + + &No + &Nein + + + + Please choose a folder name + Bitte wählen Sie einen Verzeichnisnamen + + + + Folder name: + Verzeichnisname: + + + + New folder + Neues Verzeichnis + + + + Overwrite attempt + Versuche zu überschreiben + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Eintrag %1 kann nicht überschrieben werden. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Dieser RSS-Feed ist bereits in der Liste. + + + + Are you sure you want to delete these elements from the list? + Sind Sie sicher, daß Sie diese Elemente von der Liste entfernen möchten? + + + + Are you sure you want to delete this element from the list? + Sind Sie sicher, daß Sie dieses Element von der Liste entfernen möchten? + + + + Please choose a new name for this RSS feed + Bitte wählen Sie einen neuen Namen für diesen RSS-Feed + + + + New feed name: + Neuer Feed-Name: + + + + Name already in use + Name wird bereits verwendet + + + + This name is already used by another item, please choose another one. + Dieser Name wird bereits von einem anderen Eintrag verwendet, bitte wählen Sie einen anderen Namen. + + + + Date: + Datum: + + + + Author: + Autor: + + + + Unread + Ungelesen + + + + RssArticle + + No description available + Keine Beschreibung vorhanden + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Lade Torrent %1 automatisch von RSS-Feed %2... + + + + RssItem + + No description available + Keine Beschreibung vorhanden + + + + RssSettings + + RSS Reader Settings + RSS Reader Einstellungen + + + RSS feeds refresh interval: + Aktualisierungsintervall für RSS Feeds: + + + minutes + Minuten + + + Maximum number of articles per feed: + Maximale Anzahl Artikel pro Feed: + + + + RssSettingsDlg + + + RSS Reader Settings + Einstellungen für RSS Reader + + + + RSS feeds refresh interval: + Aktualisierungsintervall für RSS Feeds: + + + + minutes + Minuten + + + + Maximum number of articles per feed: + Maximale Anzahl der Artikel pro Feed: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Automatisches laden des Torrent %1 von RSS-Feed %2... + + + + ScanFoldersModel + + + Watched Folder + Beobachtetes Verzeichnis + + + + Download here + Hier herunterladen + + + + SearchCategories + + + All categories + Alle Kategorien + + + + Movies + Filme + + + + TV shows + Fernsehsendungen + + + + Music + Musik + + + + Games + Spiele + + + + Anime + Anime + + + + Software + Software + + + + Pictures + Bilder + + + + Books + Bücher + + + + SearchEngine + + + Empty search pattern + Leere Suchanfrage + + + + Please type a search pattern first + Bitte geben Sie zuerst eine Suchanfrage ein + + + + + Results + Ergebnisse + + + + Searching... + Suche... + + + + Cut + Ausschneiden + + + + Copy + Kopieren + + + + Paste + Einfügen + + + + Clear field + Feld leeren + + + + Clear completion history + Vervollständigungshistorie löschen + + + + Confirmation + Bestätigen + + + + Are you sure you want to clear the history? + Möchten Sie die Historie wirklich leeren? + + + + + + Search + Suche + + + + Missing Python Interpreter + Fehlender Python Interpreter + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x wird benötigt um die Suchmaschine zu benutzen aber es scheint nicht installiert zu sein. Möchten Sie es jetzt installieren? + + + + Search Engine + Suchmaschine + + + + + Search has finished + Suche abgeschlossen + + + + An error occured during search... + Während der Suche ist ein Fehler aufgetreten ... + + + + + Search aborted + Suche abgebrochen + + + + Download error + Downloadfehler + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Python Einrichtung konnte nicht heruntergeladen werden, Begründung: %1. Bitte installieren Sie manuell. + + + + Search returned no results + Suche lieferte keine Ergebnisse + + + + Results + i.e: Search results + Ergebnisse + + + + + Unknown + Unbekannt + + + + SearchTab + + + Name + i.e: file name + Dateiname + + + + Size + i.e: file size + Dateigrösse + + + + Seeders + i.e: Number of full sources + Seeder + + + + Leechers + i.e: Number of partial sources + Leecher + + + + Search engine + Suchmaschine + + + + ShutdownConfirmDlg + + + Shutdown confirmation + Herunterfahren bestätigen + + + + SpeedLimitDialog + + + KiB/s + + + + + StatusBar + + + + Connection status: + Verbindungs-Status: + + + + + No direct connections. This may indicate network configuration problems. + Keine direkten Verbindungen. Möglicherweise gibt es Probleme mit Ihrer Netzwerkkonfiguration. + + + + + DHT: %1 nodes + DHT: %1 Nodes + + + + qBittorrent needs to be restarted + qBittorrent benötigt Neustart + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent wurde soeben aktualisiert. Änderungen werden erst nach einem Neustart effektiv. + + + + + Connection Status: + Verbindungs-Status: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Offline. In den meisten Fällen bedeutet das, dass qBittorrent nicht auf dem angegebenen Port für eingehende Verbindungen lauschen kann. + + + + Online + Online + + + + + %1/s + Per second + %1/s + + + + Click to switch to alternative speed limits + Klicken um zu den alternative Geschwindigkeitsbegrenzungen zu wechseln + + + + Click to switch to regular speed limits + Klick um zu den regulären Geschwindigkeitsbegrenzungen zu wechseln + + + Click to disable alternative speed limits + Klicken um alternative Geschwindigkeitsbegrenzungen zu deaktivieren + + + Click to enable alternative speed limits + Klicken um alternative Geschwindigkeitsbegrenzungen zu aktivieren + + + + Global Download Speed Limit + Begrenzung der globalen DL-Rate + + + + Global Upload Speed Limit + Begrenzung der globalen UL-Rate + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Wählen Sie einen Ordner um ihn dem Torrent hinzuzufügen + + + + Select a file to add to the torrent + Wählen Sie einen Datei um sie dem Torrent hinzuzufügen + + + Please type an announce URL + Bitte Announce URL eingeben + + + Announce URL: + Tracker URL + Announce URL: + + + Please type a web seed url + Bitte Web Seed URL eingeben + + + Web seed URL: + Web Seed URL: + + + + No input path set + Kein Eingabepfad gesetzt + + + + Please type an input path first + Bitte geben Sie zuerst einen Eingabepfad an + + + + Select destination torrent file + Torrent Datei als Ziel auswählen + + + + Torrent Files + Torrent Dateien + + + + + + Torrent creation + Erstellung des Torrent + + + + Torrent creation was unsuccessful, reason: %1 + Erstellung des Torrent war nicht erfolgreich. Begründung: %1 + + + + Created torrent file is invalid. It won't be added to download list. + Die erstellte Torrentdatei ist ungültig. Sie wird nicht der Donwloadliste hinzugefügt. + + + + Torrent was created successfully: + Torrent erfolgreich erstellt: + + + + TorrentFilesModel + + + Name + Name + + + + Size + Größe + + + + Progress + Fortschritt + + + + Priority + Priorität + + + + TorrentImportDlg + + + Torrent Import + + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Dieser Assistent wird Ihnen helfen einen Torrent, den Sie bereits heruntergeladen haben über qBittorrent zu verteilen. + + + + Torrent file to import: + Zu importierende Torrent Datei: + + + + + ... + ... + + + + Content location: + Speicherstelle des Inhalts: + + + + Skip the data checking stage and start seeding immediately + Uberprüfung der Daten überspringen und sofort mit dem seeden beginnen + + + + Import + + + + + Torrent file to import + Zu importierende Torrent Datei + + + + Torrent files (*.torrent) + Torrent Dateien (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + %1-Dateien + + + + Please provide the location of %1 + %1 is a file name + Bitte geben Sie die Speicherstelle von %1 an + + + + Please point to the location of the torrent: %1 + Bitte geben Sie die Speicherstelle des Torrent an: %1 + + + + Invalid torrent file + Ungültige Torrent Datei + + + + This is not a valid torrent file. + Dies ist keine gültige Torrrent Datei. + + + + TorrentModel + + + Name + i.e: torrent name + + + + + Size + i.e: torrent size + Größe + + + + Done + % Done + Fertig + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + + Seeds + i.e. full sources (often untranslated) + + + + + Peers + i.e. partial sources (often untranslated) + + + + + Down Speed + i.e: Download speed + Downloadgeschwindigkeit + + + + Up Speed + i.e: Upload speed + Uploadgeschwindigkeit + + + + Ratio + Share ratio + Verhältnis + + + + ETA + i.e: Estimated Time of Arrival / Time left + voraussichtliche Dauer + + + + Label + + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Hinzugefügt am + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Abgeschlossen am + + + + Tracker + + + + + Down Limit + i.e: Download limit + Downloadbegrenzung + + + + Up Limit + i.e: Upload limit + Uploadbegrenzung + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Heruntergeladen + + + + Amount left + Amount of data left to download (e.g. in MB) + Verbleibend + + + + Time Active + Time (duration) the torrent is active (not paused) + Aktiv seit + + + + TrackerList + + + URL + + + + + Status + + + + + Peers + + + + + Message + Meldung + + + + [DHT] + + + + + [PeX] + + + + + [LSD] + + + + + + + + + Working + Funktioniert + + + + + + Disabled + Deaktiviert + + + + This torrent is private + Dieser Torrent ist privat + + + + Updating... + Aktualisiere... + + + + + Not working + Funktioniert nicht + + + + + Not contacted yet + Noch nicht kontakiert + + + + Add a new tracker... + Neuen Tracker hinzufügen... + + + + Remove tracker + Tracker entfernen + + + + Force reannounce + Bekanntgebung forcieren + + + + TrackersAdditionDlg + + + Trackers addition dialog + Dialog zum Hinzufügen eines Trackers + + + + List of trackers to add (one per line): + Liste der hinzuzufügenden Tracker (einer pro Zeile): + + + + µTorrent compatible list URL: + µTorrent kompatible Listen URL: + + + + I/O Error + I/O Fehler + + + + Error while trying to open the downloaded file. + Beim Versuch die heruntergeladenen datei zu öffnen ist ein Fehler aufgetreten. + + + + No change + Keine Veränderung + + + + No additional trackers were found. + Es wurden keine zusätzlichen Tracker gefunden. + + + + Download error + Downloadfehler + + + + The trackers list could not be downloaded, reason: %1 + Die Trackerliste konnte nicht geladen werden. Begründung: %1 + + + + TransferListDelegate + + + Downloading + Lade + + + + Paused + Angehalten + + + + Queued + i.e. torrent is queued + Eingereiht + + + + Seeding + Torrent is complete and in upload-only mode + Seede + + + + Stalled + Torrent is waiting for download to begin + Angehalten + + + + Checking + Torrent local data is being checked + Überprüfe + + + + /s + /second (.i.e per second) + + + + + KiB/s + KiB/second (.i.e per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + Geseeded seit %1 + + + + TransferListFiltersWidget + + + + All + Alle + + + + + Downloading + Lade + + + + + Completed + Vollständig + + + + + Paused + Angehalten + + + + + Active + Aktiv + + + + + Inactive + Inaktiv + + + + + All labels + Alle Label + + + + + Unlabeled + Ohne Label + + + + Remove label + Label entfernen + + + + Add label... + Label hinzufügen... + + + + Resume torrents + Torrent fortsetzen + + + + Pause torrents + Torrent anhalten + + + + Delete torrents + Torrent löschen + + + + New Label + Neues Label + + + + Label: + + + + + Invalid label name + Ungültiger Labelname + + + + Please don't use any special characters in the label name. + Bitte keine Sonderzeichen im Labelname verwenden. + + + + TransferListWidget + + Down Speed + i.e: Download speed + DL-Rate + + + Up Speed + i.e: Upload speed + UL-Rate + + + ETA + i.e: Estimated Time of Arrival / Time left + voraussichtliche Dauer + + + + Column visibility + Sichtbarkeit der Spalten + + + Name + i.e: torrent name + Name + + + Size + i.e: torrent size + Größe + + + Done + % Done + Fertig + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + Ratio + Share ratio + Verhältnis + + + + Label + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Hinzugefügt am + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Vervollständigt am + + + Down Limit + i.e: Download limit + Download Begrenzung + + + Up Limit + i.e: Upload limit + Upload Begrenzung + + + + Choose save path + Speicherort auswählen + + + Save path creation error + Fehler beim erstellen des Speicherortes + + + Could not create the save path + Speicherort konnte nicht erstellt werden + + + + Torrent Download Speed Limiting + Begrenzung der Torrent-DL-Rate + + + + Torrent Upload Speed Limiting + Begrenzung der Torrent-UL-Rate + + + + New Label + Neues Label + + + + Label: + + + + + Invalid label name + Ungültiger Labelname + + + + Please don't use any special characters in the label name. + Bitte keine Sonderzeichen im Labelname verwenden. + + + + Rename + Umbenennen + + + + New name: + Neuer Name: + + + + Resume + Resume/start the torrent + Fortsetzen + + + + Pause + Pause the torrent + Anhalten + + + + Delete + Delete the torrent + Löschen + + + + Preview file... + Datei vorschauen... + + + + Limit share ratio... + Shareverhältnis begrenzen... + + + + Limit upload rate... + Uploadrate begrenzen... + + + + Limit download rate... + Downlaodrate begrenzen... + + + + Priority + Priorität + + + + Open destination folder + Zielverzeichniss öffnen + + + + Move up + i.e. move up in the queue + Nach oben bewegen + + + + Move down + i.e. Move down in the queue + Nach unten bewegen + + + + Move to top + i.e. Move to top of the queue + An den Anfang + + + + Move to bottom + i.e. Move to bottom of the queue + An das Ende + + + + Set location... + Ort setzen... + + + + Force recheck + Erzwinge erneute Überprüfung + + + + Copy magnet link + Kopiere Magnet-Link + + + + Super seeding mode + Super-Seeding-Modus + + + + Rename... + Umbenennen... + + + + Download in sequential order + Der Reihe nach downloaden + + + + Download first and last piece first + Erste und letzte Teile zuerst laden + + + + New... + New label... + Neu... + + + + Reset + Reset label + Zurücksetzen + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Begrenzung des Torrent Upload/Download Verhältnisses + + + + Use global ratio limit + Globale Begrenzung für das Verhältnis verwenden + + + + + + buttonGroup + Schaltegruppe + + + + Set no ratio limit + Keine Begrenzung für das Verhältnis verwenden + + + + Set ratio limit to + Begrenzung für das Verhältnis setzen + + + + UsageDisplay + + + Usage: + Verwendung: + + + + displays program version + zeigt die Programmversion + + + + disable splash screen + deaktiviere Splash Screen + + + + displays this help message + zeigt diese Hilfsausgabe + + + + changes the webui port (current: %1) + verändert den Webinterface Port (momentan: %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [Dateien oder URLs]: lädt vom Benutzer übergebene Torrents (optional) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Ich möchte folgenden freiwilligen Übersetzern danken: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Bitte kontaktieren Sie mich, falls Sie qBittorrent in Ihre Sprache übersetzen wollen. + + + + addPeerDialog + + + Peer addition + Hinzufügen eines Peers + + + + IP + + + + + Port + + + + + addTorrentDialog + + + Torrent addition dialog + Dialog zum Hinzufügen eines Torrent + + + + Save path: + Speicher-Pfad: + + + + ... + ... + + + + Torrent size: + Torrent-Größe: + + + + + Unknown + Unbekannt + + + + Free disk space: + Freier Festplattenspeicher: + + + + Label: + + + + + Torrent content: + Torrent Inhalt: + + + + Select All + Alle Auswählen + + + + Select None + Keine Auswählen + + + + Download in sequential order (slower but good for previewing) + Der Reihe nach laden (langsamer, aber besser zum Vorschauen) + + + + Skip file checking and start seeding immediately + Überspringe das Überprüfen der Datei und direkt mit dem Seeden beginnen + + + + + Do not download + Nicht herunterladen + + + + Add to download list in paused state + Der Download Liste im Pause-Modus hinzufügen + + + + Add + Hinzufügen + + + + Cancel + Abbrechen + + + + Normal + Normal + + + + High + Hoch + + + + Maximum + Maximum + + + + authentication + + + + Tracker authentication + Tracker Authentifizierung + + + + Tracker: + Tracker: + + + + Login + Login + + + + Username: + Benutzername: + + + + Password: + Kennwort: + + + + Log in + Einloggen + + + + Cancel + Abbrechen + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Löschen bestätigen - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Sind Sie sicher, daß Sie die ausgewählten Torrents von der Transfer-Liste entfernen möchten? + + + + Remember choice + Entscheidung merken + + + + Also delete the files on the hard disk + Datei auch von der Festplatte löschen + + + + createTorrentDialog + + + Cancel + Abbrechen + + + + Torrent Creation Tool + Torrenterstellungs Werkzeug + + + + Torrent file creation + Torrent-Datei Erstellung + + + Announce urls (trackers): + Announce URLs (Tracker): + + + Comment (optional): + Kommentar (optional): + + + Web seeds urls (optional): + Web Seeds URLs (optional): + + + + File or folder to add to the torrent: + Datei oder Ordner die dem Torrent hinzugefügt werden: + + + + Add file + Datei hinzufügen + + + + Add folder + Verzeichnis hinzufügen + + + + Tracker URLs: + + + + + Web seeds urls: + Web Seeds URLs: + + + + Comment: + Kommentar: + + + + Piece size: + Größe der Stücke: + + + + 32 KiB + + + + + 64 KiB + + + + + 128 KiB + + + + + 256 KiB + + + + + 512 KiB + + + + + 1 MiB + + + + + 2 MiB + + + + + 4 MiB + + + + + Auto + Automatisch + + + + Private (won't be distributed on DHT network if enabled) + Privat (wird nicht an das DHT Netzwerk verteilt) + + + + Start seeding after creation + Beginne Seeding nach Erstellung + + + + Create and save... + Erstellen und speichern... + + + + Progress: + Fortschritt: + + + + createtorrent + + Select destination torrent file + Ziel-Torrent Datei auswählen + + + Torrent Files + Torrent Dateien + + + No input path set + Kein Eingangs-Pfad gesetzt + + + Please type an input path first + Bitte geben Sie zuerst einen Eingangspfad an + + + Torrent creation + Torrent Erstellung + + + Torrent was created successfully: + Torrent erfolgreich erstellt: + + + Select a folder to add to the torrent + Ordner wählen um ihn dem Torrent hinzuzufügen + + + Please type an announce URL + Bitte Announce URL eingeben + + + Torrent creation was unsuccessful, reason: %1 + Torrent Erstellung nicht erfolgreich, Grund: %1 + + + Announce URL: + Tracker URL + Announce URL: + + + Please type a web seed url + Bitte Web Seed URL eingeben + + + Web seed URL: + Web Seed URL: + + + Select a file to add to the torrent + Datei wählen um sie dem Torrent hinzuzufügen + + + Created torrent file is invalid. It won't be added to download list. + Die erstellte Torrent-Datei ist ungültig. Sie wird nicht der Donwload-Liste hinzugefügt. + + + + downloadFromURL + + Download Torrents from URLs + Torrents von URLs laden + + + Only one URL per line + Nur eine URL pro Zeile + + + + Add torrent links + Torrent-Links hinzufügen + + + + Both HTTP and Magnet links are supported + HTTP und Magnet-Links werden unterstützt + + + + Download + Lade + + + + Cancel + Abbrechen + + + + Download from urls + Von URLs laden + + + + No URL entered + Keine URL eingegeben + + + + Please type at least one URL. + Bitte geben Sie mindestens eine URL an. + + + + downloadThread + + I/O Error + I/O Fehler + + + The remote host name was not found (invalid hostname) + Der entfernte Hostname konnte nicht gefunden werden (ungültiger Hostname) + + + The operation was canceled + Die Operation wurde abgebrochen + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Der entfernte Server hat die Verbindung beendet bevor die gesamte Antwort empfangen und verarbeitet werden konnte + + + The connection to the remote server timed out + Zeitüberschreitung bei der Verbindung mit dem entfernten Server + + + SSL/TLS handshake failed + SSL/TLS Handshake fehlgeschlagen + + + The remote server refused the connection + Der entfernte Server hat die Verbindung verweigert + + + The connection to the proxy server was refused + Die Verbindung zum Proxy-Server wurde verweigert + + + The proxy server closed the connection prematurely + Der Proxy-Server hat die Verbindung vorzeitig beendet + + + The proxy host name was not found + Der Proxy-Hostname wurde nicht gefunden + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Zeitüberschreitung beim Verbindungsaufbau mit dem Proxy oder der Proxy hat nicht in angemessener Zeit auf Anfrage reagiert + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Der Proxy benötigt Authentifizierung um die Anfrage zu bearbeiten und hat keine der angebotenen Zugangsdaten akzeptiert + + + The access to the remote content was denied (401) + Der Zugriff auf den entfernten Inhalt wurde verweigert (401) + + + The operation requested on the remote content is not permitted + Die angeforderte Operation auf den entfernten Inhalt ist nicht erlaubt + + + The remote content was not found at the server (404) + Der entfernte Inhalte wurde auf dem Server nicht gefunden (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Der entfernte Server benötigt Authentifizierung um den Inhalt auszuliefern, aber die angebotenen Zugangsdaten wurden nicht akzeptiert + + + The Network Access API cannot honor the request because the protocol is not known + Die Network-Access-API konnte die Anfrage nicht bearbeiten, unbekanntes Protokoll + + + The requested operation is invalid for this protocol + Die angeforderte Operation ist ungütlig für dieses Protokoll + + + An unknown network-related error was detected + Ein unbekannter Netzwerk-Fehler ist aufgetreten + + + An unknown proxy-related error was detected + Ein unbekannter Proxy-Fehler ist aufgetreten + + + An unknown error related to the remote content was detected + Unbekannter Fehler in Verbindung mit dem entfernten Inhalt ist aufgetreten + + + A breakdown in protocol was detected + Eine Störung im Protokoll ist aufgetreten + + + Unknown error + Unbekannter Fehler + + + + engineSelect + + + Search plugins + Suchplugins + + + + Installed search engines: + Installierte Suchmaschinen: + + + + Name + Name + + + + Url + URL + + + + + Enabled + Aktiviert + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Sie können neue Suchmaschinen Plugins hier herunterladen: <a href="http:plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Intalliere ein neue + + + + Check for updates + Auf Updates prüfen + + + + Close + Schließen + + + Enable + Aktivieren + + + Disable + Deaktivieren + + + + Uninstall + Deinstallieren + + + + engineSelectDlg + + + Uninstall warning + Deinstallations Warnung + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Einige Plugins konnten nicht deinstalliert werden, da sie ein fester Bestandteil von qBitttorrent sind. + Nur Plugins, die sie selber installiert haben können wieder entfernt werden. +Die Plugins wurden jedoch deaktiviert. + + + + Uninstall success + Deinstallation erfolgreich + + + + Select search plugins + Wähle Suchplugin + + + + qBittorrent search plugins + qBittorrent Suchplugins + + + + + + + + Search plugin install + Suchplugin installieren + + + + + + Yes + Ja + + + + + + + No + Nein + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Eine neuere Version des Suchmaschinen Plugins %1 ist bereits installiert. + + + + + + + Search plugin update + Such-Plugin update + + + + + Sorry, update server is temporarily unavailable. + Update Server vorübergehend nicht erreichbar. + + + + All your plugins are already up to date. + Alle Plugins sind auf dem neuesten Stand. + + + + All selected plugins were uninstalled successfully + Alle ausgewählten Plugins wurden erfolgreich deinstalliert + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 Suchmaschinen Plugin konnte nich aktualisiert werden, behalte alte Version. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 Suchmaschinen Plugin konnte nicht installiert werden. + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 Suchmaschinen Plugin wurder erfolgreich geupdated. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1 Suchmaschinen Plugin wurde erfolgreich installiert. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Installation des Suchmaschinen Plugins %1 fehlgeschlagen. + + + + New search engine plugin URL + Neue Suchmaschinen Plugin URL + + + + URL: + URL: + + + + misc + + + B + bytes + B + + + + KiB + kibibytes (1024 bytes) + KB + + + + MiB + mebibytes (1024 kibibytes) + MB + + + + GiB + gibibytes (1024 mibibytes) + GB + + + + TiB + tebibytes (1024 gibibytes) + TB + + + + %1h %2m + e.g: 3hours 5minutes + + + + + %1d %2h + e.g: 2days 10hours + %1t %2h + + + + + + + + + Unknown + Unbekannt + + + + Unknown + Unknown (size) + Unbekannt + + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent wird den Computer jetzt herunterfahren, da alle Downloads vollständig sind. + + + + < 1m + < 1 minute + < 1 Minute + + + + %1m + e.g: 10minutes + %1 Min + + + + options_imp + + + + + + Choose a save directory + Verzeichnis zum Speichern auswählen + + + + Add directory to scan + Verzeichnis zum Scannen hinzufügen + + + + Folder is already being watched. + Verzeichnis wird bereits beobachtet. + + + + Folder does not exist. + Verzeichnis existiert nicht. + + + + Folder is not readable. + Verzeichnis kann nicht gelesen werden. + + + + Failure + Fehler + + + + Failed to add Scan Folder '%1': %2 + Konnte Scan-Verzeichnis '%1' nicht hinzufügen: %2 + + + + + Choose export directory + Export-Verzeichnis wählen + + + + + Choose an ip filter file + IP-Filter-Datei wählen + + + + + Filters + Filter + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + Fehler beim parsen + + + + Failed to parse the provided IP filter + Fehler beim parsen der IP-Filter + + + + Successfully refreshed + Erfolgreich aktualisiert + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + Succesfully refreshed + Erfolgreich aktualisiert + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + IP-Filter erfolgreich geparsed: %1 Regeln wurden angewandt. + + + + pluginSourceDlg + + + Plugin source + Plugin Quelle + + + + Search plugin source: + Such Plugin Quelle: + + + + Local file + Lokale Datei + + + + Web link + Web Link + + + + preview + + + Preview selection + Vorschau Auswahl + + + + File preview + Datei vorschauen + + + + The following files support previewing, <br>please select one of them: + Die folgenden Dateien unterstützen Vorschau, <br>bitte wählen Sie eine: + + + + Preview + Vorschau + + + + Cancel + Abbrechen + + + + previewSelect + + Preview impossible + Vorschau unmöglich + + + Sorry, we can't preview this file + Bedauere, wir können keine Vorschau für diese Datei erstellen + + + Name + Name + + + Size + Größe + + + Progress + Fortschritt + + + + search_engine + + + + Search + Suche + + + + Status: + Status: + + + + Stopped + Angehalten + + + + Download + Lade + + + + Go to description page + Zur Beschreibungsseite wechseln + + + + Search engines... + Suchmaschinen... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + Torrent Datei kann nicht dekodiert werden: + + + + + + Choose save path + Wählen Sie den Speicher-Pfad + + + + Unable to decode magnet link: + Magnet-Link konnte nicht dekodiert werden: + + + + Magnet Link + Magnet-Link + + + + Rename... + Umbenennen... + + + + Rename the file + Datei umbenennen + + + + New name: + Neuer Name: + + + + + The file could not be renamed + Die Datei konnte nicht umbenannt werden + + + + This file name contains forbidden characters, please choose a different one. + Der Dateiname enthält ungültige Zeichen, bitte einen anderen wählen. + + + + + This name is already in use in this folder. Please use a different name. + Der Dateiname wird in diesem Verzeichnis bereits verwendet. Bitte anderen wählen. + + + + The folder could not be renamed + Das Verzeichnis konnte nicht umbenannt werden + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 übrig nachdem der Torrent geladen wurde) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 mehr benötigt u die Datei downloaden zu können) + + + + Empty save path + Leerer Speicher-Pfad + + + + Please enter a save path + Bitte geben Sie einen Speicher-Pfad ein + + + + Save path creation error + Fehler beim erstellen des Speicher-Pfades + + + + Could not create the save path + Speicher-Pfad konnte nicht erstellt werden + + + + Invalid label name + Ungültiger Labelname + + + + Please don't use any special characters in the label name. + Bitte keine Sonderzeichen im Labelname verwenden. + + + + Seeding mode error + Seeding-Modus-Fehler + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Sie haben sich entschlossen das Überprüfen der Dateien zu überspringen. Lokale Dateien scheinen jedoch im aktuellen Zielverzeichnis nicht zu existieren. Bitte deaktivieren Sie diese Eigenschaft oder aktualisieren Sie den Speicherpfad. + + + + Invalid file selection + Ungültige Datei Auswahl + + + + You must select at least one file in the torrent + Sie müssen mindestens eine Datei aus dem Torrent selektieren + + + + Priority + Priorität + + + diff --git a/src/lang/qbittorrent_el.qm b/src/lang/qbittorrent_el.qm new file mode 100644 index 0000000000000000000000000000000000000000..c15f0783333f394065f99a26d180adacc5d5d3d1 GIT binary patch literal 124844 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 + + + + AboutDlg + + + About qBittorrent + Σχετικά με το qBittorrent + + + + About + Σχετικά + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Ένας πελάτης Bittorrent προγραμματισμένος στη C++, βασιζόμενος στο Qt4 Toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Αρχική Σελίδα:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Φόρουμ:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + Author + Δημιουργός + + + + Name: + Όνομα: + + + + Country: + Χώρα: + + + + E-mail: + Διεύθυνση ηλ.ταχυδρομείου: + + + + Christophe Dumez + Christophe Dumez + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Ένας εξελιγμένος πελάτης BitTorrent, προγραμματισμένος σε C++, βασισμένος στο Qt4 Toolkit και το libtorrent-rasterbar.<br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Αρχική Σελίδα:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Φόρουμ:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + France + Γαλλία + + + + Translation + Μετάφραση + + + + License + Άδεια + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + + chris@qbittorrent.org + + + + + Thanks to + Ευχαριστώ + + + + AdvancedSettings + + Property + Ιδιότητα + + + Value + Translated as characteristics due to context + Χαρακτηριστικά + + + + Disk write cache size + Προσωρινή μνήμη εγγραφής στο δίσκο + + + + MiB + MiB + + + + Outgoing ports (Min) [0: Disabled] + Εξωτερικές θύρες (Ελάχιστο) [0: Απενεργοποιημένες] + + + + Outgoing ports (Max) [0: Disabled] + Εξωτερικές θύρες (Μέγιστο) [0: Απενεργοποιημένες] + + + + Recheck torrents on completion + Επανέλεγχος των τόρεντ όταν ολοκληρώνονται + + + + Transfer list refresh interval + Ρυθμός ανανέωσης λίστας μεταφορών + + + + ms + milliseconds + ms + + + + Setting + Ρύθμιση + + + + Value + Value set for this setting + Τιμή + + + + Resolve peer countries (GeoIP) + Ανεύρεση χωρών διασυνδέσεων (GeoIP) + + + + Resolve peer host names + Ανεύρεση ονομάτων φορέων διασυνδέσεων + + + + Maximum number of half-open connections [0: Disabled] + Μέγιστος αριθμός συνδέσεων που αναμένουν απόκριση [0: Απενεργοποιημένο] + + + + Strict super seeding + Αυστηρή λειτουργία ενισχυμένου διαμοιράσματος + + + + Network Interface (requires restart) + Δικτυακό interface (απαιτεί επανεκκίνηση) + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + Οποιοδήποτε interface + + + + IP Address to report to trackers (requires restart) + Η διεύθυνση IP να δίνει αναφορά στους ιχνηλάτες (απαιτεί επανεκκίνηση) + + + + Display program on-screen notifications + Εμφάνιση ειδοποιήσεων προγράμματος + + + Display program notification balloons + Εμφάνιση μπαλονιών ειδοποιήσεων προγράμματος + + + + Enable embedded tracker + Ενεργοποίηση ενσωματομένου ιχνηλάτη + + + + Embedded tracker port + Θύρα ενσωματομένου ιχνηλάτη + + + + Check for software updates + Έλεγχος για αναβαθμίσεις + + + + Use system icon theme + ? + Χρήση θέματος συστήματος + + + + Confirm torrent deletion + Επιβεβαίωση διαγραφής τόρεντ + + + + Ignore transfer limits on local network + Αγνόησε τα όρια ταχύτητας μεταφορών στο τοπικό δίκτυο + + + Include TCP/IP overhead in transfer limits + Να συμπεριληφθεί το περιθώριο TCP/IP στα όρια μεταφορών + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Αυτόματο RSS Downloader + + + + Enable the automated RSS downloader + Ενεργοποίηση του αυτοόματου RSS downloader + + + + Download rules + Κανόνες κατεβάσματος + + + + Rule definition + Ορισμός κανόνα + + + + Must contain: + Να περιέχει: + + + + Must not contain: + Να μην περιέχει: + + + + Use regular expressions + Χρήση απλών εκφράσεων + + + + Import... + Εισαγωγή... + + + + Export... + Εξαγωγή... + + + + ... + ... + + + + Assign label: + Ορισμός ετικέτας: + + + + Save to a different directory + Αποθήκευση σε διαφορετική κατηγορία + + + + Save to: + Αποθήκευση σε: + + + + Apply rule to feeds: + Εφαρμογή κανόνα στις τροφοδοσίες: + + + + Matching RSS articles + Άρθρα RSS που αντιστοιχούν + + + + New rule name + Όνομα νέου κανόνα + + + + Please type the name of the new download rule. + Παρακαλώ εισάγετε το όνομα του νέου κανόνα κατεβασμάτων. + + + + + Rule name conflict + Εμπλοκή. + Εμπλοκή ονόματος κανόνα + + + + + A rule with this name already exists, please choose another name. + Υπάρχει ήδη κανόνας με αυτό το όνομα, παρακαλώ επιλέξτε ένα άλλο. + + + + Are you sure you want to remove the download rule named %1? + Είστε σίγουρος οτι θέλετε να αφαιρέσετε τον κανόνα κατεβασμάτων %1? + + + + Are you sure you want to remove the selected download rules? + Είστε σίγουρος οτι θέλετε να αφαιρέσετε τους επιλεγμένους κανόνες κατεβασμάτων? + + + + Rule deletion confirmation + Επιβεβαίωση διαγραφής κανόνα + + + + Destination directory + Φάκελος προορισμού + + + + Invalid action + Άκυρη επιλογή + + + + The list is empty, there is nothing to export. + Η λίστα είναι άδεια, δεν υπάρχει τίποτα προς εξαγωγή. + + + + Where would you like to save the list? + Πού θα θέλατε να αποθηκεύσετε τη λίστα? + + + + Rules list (*.rssrules) + Λίστα κανόνων (*.rssrules) + + + + I/O Error + Σφάλμα I/O + + + + Failed to create the destination file + Αποτυχία δημιουργίας του αρχείου προορισμού + + + + Please point to the RSS download rules file + Παρακαλώ επιλέξτε το αρχείο κανόνων κατεβασμάτων RSS + + + + Rules list (*.rssrules *.filters) + Λίστες κανόνων (*.rssrules *.filters) + + + + Import Error + Σφάλμα Εισαγωγής + + + + Failed to import the selected rules file + Αποτυχία εισαγωγής του επιλεγμένου αρχείου κανόνων + + + + Add new rule... + Προσθήκη νέου κανόνα... + + + + Delete rule + Διαγραφή κανόνα + + + + Rename rule... + Μετονομασία κανόνα... + + + + Delete selected rules + Διαγραφή επιλεγμένων κανόνων + + + + Rule renaming + Μετονομασία κανόνα + + + + Please type the new rule name + Παρακαλώ εισάγετε το νέο όνομα του κανόνα + + + + Regex mode: use Perl-like regular expressions + Λειτουργία Regex: χρήση εκφράσεων τύπου Perl + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Λειτουργία ελεύθερης αναζήτησης: μπορείτε να χρησιμοποιήσετε<ul><li>? για κάθε ένα χαρακτήρα</li><li>* για να ταιριάξετε από μηδέν έως και πολλούς χαρακτήρες</li><li>τα κενά μετρώνται σαν να γίνεται χρήση του AND</li></ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Λειτουργία ελεύθερης αναζήτησης: μπορείτε να χρησιμοποιήσετε<ul><li>? για κάθε ένα χαρακτήρα</li><li>* για να ταιριάξετε από μηδέν έως και πολλούς χαρακτήρες</li><li>|χρησιμοποιείται ως OR</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + Το %1 έφτασε στη μέγιστη αναλογία που θέσατε. + + + Removing torrent %1... + Αφαίρεση του τόρεντ %1... + + + Pausing torrent %1... + Παύση του τόρεντ %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + Το qBittorrent χρησιμοποιεί τη θύρα: TCP/%1 + + + UPnP support [ON] + Υποστήριξη UPnP [ΝΑΙ] + + + UPnP support [OFF] + Υποστήριξη UPnP [ΟΧΙ] + + + NAT-PMP support [ON] + Υποστήριξη NAT-PMP [NAI] + + + NAT-PMP support [OFF] + Υποστήριξη NAT-PMP [OXI] + + + HTTP user agent is %1 + Η εφαρμογή HTTP σας είναι %1 + + + Using a disk cache size of %1 MiB + Χρησιμοποιείται προσωρινή μνήμη δίσκου, %1 MiB + + + DHT support [ON], port: UDP/%1 + Υποστήριξη DHT [NAI], θύρα: UDP/%1 + + + DHT support [OFF] + Υποστήριξη DHT [ΟΧΙ] + + + PeX support [ON] + Υποστήριξη PeX [ΝΑΙ] + + + PeX support [OFF] + Υποστήριξη PeX [ΟΧΙ] + + + Restart is required to toggle PeX support + Απαιτείται επανεκκίνηση για να αλλάξουν οι ρυθμίσεις PeX + + + Local Peer Discovery [ON] + Ανακάλυψη Τοπικών Συνδέσεων [ΝΑΙ] + + + Local Peer Discovery support [OFF] + Ανακάλυψη Τοπικών Συνδέσεων [ΟΧΙ] + + + Encryption support [ON] + Υποστήριξη κρυπτογράφησης [ΝΑΙ] + + + Encryption support [FORCED] + Υποστήριξη κρυπτογράφησης [ΕΞΑΝΑΓΚΑΣΤΜΕΝΗ] + + + Encryption support [OFF] + Υποστήριξη κρυπτογράφησης [ΟΧΙ] + + + The Web UI is listening on port %1 + Το Web UI χρησιμοποιεί τη θύρα %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Σφάλμα Web User Interface - Αδύνατο να συνδεθεί το Web UI στην θύρα %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + To '%1' αφαιρέθηκε από την λίστα ληφθέντων και τον σκληρό δίσκο. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + Το '%1' αφαιρέθηκε από την λίστα ληφθέντων. + + + '%1' is not a valid magnet URI. + Το '%1' δεν είναι ένα έγκυρο magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + Το '%1' είναι ήδη στη λίστα των λαμβανόμενων. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + Το '%1' ξανάρχισε. (γρήγορη επανασύνδεση) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + Το '%1' προστέθηκε στη λίστα των λαμβανόμενων. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Αδύνατο να αποκωδικοποιηθεί το αρχείο torrent: '%1' + + + This file is either corrupted or this isn't a torrent. + Το αρχείο είναι είτε κατεστραμμένο ή δεν είναι torrent. + + + Note: new trackers were added to the existing torrent. + Σημείωση: νέοι trackers προστέθηκαν στο υπάρχον torrent. + + + Note: new URL seeds were added to the existing torrent. + Σημείωση: νέοι διαμοιραστές μέσω URL προστέθηκαν στο ήδη υπάρχον torrent. + + + Error: The torrent %1 does not contain any file. + Σφάλμα: Το τόρεντ %1 δεν περιέχει κανένα αρχείο. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>μπλοκαρίστηκε εξαιτίας του φίλτρου IP σας</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>απαγορεύτηκε εξαιτίας κατεστραμμένων κομματιών</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Προγραμματισμένο κατέβασμα του αρχείου %1,που βρίσκεται στο torrent %2 + + + Unable to decode %1 torrent file. + Αδύνατο να αποκωδικοποιηθεί το αρχείο torrent %1. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Σφάλμα χαρτογράφησης θυρών, μήνυμα: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Χαρτογράφηση θυρών επιτυχής, μήνυμα: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Γρήγορη επανεκκίνηση αρχείων απορρίφθηκε για το torrent %1, γίνεται επανέλεγχος... + + + Reason: %1 + Αιτία: %1 + + + An I/O error occured, '%1' paused. + Ένα σφάλμα I/O προέκυψε, το '%1' είναι σε παύση. + + + File sizes mismatch for torrent %1, pausing it. + Τα μεγέθη των αρχείων δεν είναι σε αντιστοιχία για το τόρεντ %1, γίνεται παύση. + + + Url seed lookup failed for url: %1, message: %2 + Αποτυχία ελέγχου url διαμοιρασμού για το url: %1, μήνυμα: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Κατέβασμα του '%1', παρακαλώ περιμένετε... + + + + ConsoleDlg + + qBittorrent log viewer + Καταγραφή γεγονότων στο qBittorrent + + + General + Γενικά + + + Blocked IPs + Μποκαρισμένες IP + + + + CookiesDlg + + + Cookies management + Διαχείριση cookies + + + + Key + As in Key/Value pair + Κλειδί + + + + Value + As in Key/Value pair + Χαρακτηριστικά + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Συνήθη κλειδιά για τα cookies είναι : '%1', '%2'. +Μπορείτε να βρείτε αυτές τις πληροφορίες από τις προτιμήσεις του περιηγητή σας. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + Το δυναμικό DNS σας έχει ανανεωθεί επιτυχώς. + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Σφάλμα δυναμικού DNS: Η υπηρεσία δεν είναι προσωρινά διαθέσιμη, θα γίνει επανάληψη σε 30 λεπτά. + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Σφάλμα δυναμικού DNS: το hostname που δώσατε δεν υπάρχει σε αυτό τον λογαριασμό. + + + + Dynamic DNS error: Invalid username/password. + Σφάλμα δυναμικού DNS: Λάθος όνομα χρήστη/κωδικός. + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Σφάλμα δυναμικού DNS: Το qBittorrent είναι στη μαύρη λίστα της υπηρεσίας, παρακαλώ αναφέρατε το σφάλμα στο http://bugs.qbittorrent.org. + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Σφάλμα δυναμικού DNS: Το %1 δεν έγινε αποδεκτό, παρακαλώ αναφέρατε το σφάλμα στο http://bugs.qbittorrent.org. + + + + Dynamic DNS error: Your username was blocked due to abuse. + Σφάλμα δυναμικού DNS: Το όνομα χρήστη σας έχει αποκλειστεί λόγω κατάχρησης. + + + + Dynamic DNS error: supplied domain name is invalid. + Σφάλμα δυναμικού DNS: Το domain name που δώσατε είναι άκυρο. + + + + Dynamic DNS error: supplied username is too short. + Σφάλμα δυναμικού DNS: Το όνομα χρήστη που δώσατε είναι πολύ μικρό. + + + + Dynamic DNS error: supplied password is too short. + Σφάλμα δυναμικού DNS: Ο κωδικός που δώσατε είναι πολύ μικρός. + + + + DownloadThread + + + + I/O Error + Σφάλμα I/O + + + + The remote host name was not found (invalid hostname) + Ο απομακρυσμένος διακομιστής δεν βρέθηκε (άκυρο όνομα διακομιστή) + + + + The operation was canceled + Η διαδικασία ακυρώθηκε + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Ο απομακρυσμένος εξυπηρετητής διέκοψε την σύνδεση πρόωρα, προτού η πλήρης απάντηση γίνει ληπτή και επεξεργασθεί + + + + The connection to the remote server timed out + Η σύνδεση προς τον απομακρυσμένο εξυπηρετητή έληξε + + + + SSL/TLS handshake failed + SSL/TLS σύνδεση απέτυχε + + + + The remote server refused the connection + Ο απομακρυσμένος εξυπηρετητής αρνήθηκε τη σύνδεση + + + + The connection to the proxy server was refused + Η σύνδεση προς τον διακομιστή proxy δεν έγινε δεκτή + + + + The proxy server closed the connection prematurely + Ο διακομιστής proxy έκλεισε την σύνδεση πρόωρα + + + + The proxy host name was not found + Το όνομα του διακομιστή proxy δεν βρέθηκε + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Η σύνδεση προς τον εξυπηρετητή proxy έληξε ή ο proxy δεν αποκρίθηκε εγκαίρως στο σταλθέν αίτημα + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Ο proxy απαιτεί πιστοποίηση για να δεχθεί την αίτηση αλλά δεν δέχθηκε καμία πιστοποίηση + + + + The access to the remote content was denied (401) + Η πρόσβαση στο απομακρυσμένο περιεχόμενο δεν έγινε δεκτή (401) + + + + The operation requested on the remote content is not permitted + Η λειτουργία που ζητήσατε στο αποκαρυσμένο περιεχόμενο δεν επιτρέπεται + + + + The remote content was not found at the server (404) + Το απομακρυσμένο περιεχόμενο δεν βρέθηκε στον διακομιστή (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Ο απομακρυσμένος διακομιστής απαιτεί πιστοποίηση για να δεχθεί την αίτηση αλλά δεν δέχθηκε καμία πιστοποίηση + + + + The Network Access API cannot honor the request because the protocol is not known + Το API Δικτύου δεν μπόρεσε να εκπληρώσει το αίτημα επειδή το πρωτόκολλο είναι άγνωστο + + + + The requested operation is invalid for this protocol + Η ζητηθείσα λειτουργία είναι άκυρη για αυτό το πρωτόκολλο + + + + An unknown network-related error was detected + Ένα άγνωστο σφάλμα δικτύου βρέθηκε + + + + An unknown proxy-related error was detected + Ένα άγνωστο σφάλμα του proxy βρέθηκε + + + + An unknown error related to the remote content was detected + Βρέθηκε ένα άγνωστο σφάλμα στο απομακρυσμένο περιεχόμενο + + + + A breakdown in protocol was detected + Εντοπίστηκε διακοπή στο πρωτόκολλο + + + + Unknown error + Άγνωστο σφάλμα + + + + EventManager + + + + Working + Σε λειτουργία + + + + Updating... + Ανανέωση... + + + + + Not working + Ανενεργό + + + + + Not contacted yet + Δεν επικοινώνησε ακόμα + + + + + this session + αυτή η συνεδρία + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Διαμοιράστηκε για %1 + + + + %1 max + e.g. 10 max + μέγιστο %1 + + + + + %1/s + e.g. 120 KiB/s + %1 /s + + + + ExecutionLog + + Form + Μορφή + + + + General + Γενικά + + + + Blocked IPs + Μποκαρισμένες IP + + + + FeedDownloader + + RSS Feed downloader + Κατέβασμα παροχών RSS + + + RSS feed: + Παροχή RSS: + + + Feed name + Όνομα παροχής + + + Automatically download torrents from this feed + Αυτόματη λήψη torrent από αυτήν την παροχή + + + Download filters + Φίλτρο ληφθέντων + + + Filters: + Φίλτρα: + + + Filter settings + Ρυθμίσεις φίλτρου + + + Matches: + Αντιστοιχίες: + + + Does not match: + Δεν αντιστοιχεί: + + + Destination folder: + Φάκελος προορισμού: + + + ... + ... + + + Filter testing + Δοκιμή φίλτρου + + + Torrent title: + Τίτλος torrent: + + + Result: + Αποτέλεσμα: + + + Test + Δοκιμή + + + Import... + Εισαγωγή... + + + Export... + Εξαγωγή... + + + Rename filter + Μετονομασία φίλτρου + + + Remove filter + Αφαίρεση φίλτρου + + + Add filter + Προσθήκη φίλτρου + + + + FeedDownloaderDlg + + New filter + Νέο φίλτρο + + + Please choose a name for this filter + Παρακαλώ επιλέξτε ένα όνομα για αυτό το φίλτρο + + + Filter name: + Όνομα φίλτρου: + + + Invalid filter name + Άκυρο όνομα φίλτρου + + + The filter name cannot be left empty. + Το όνομα του φίλτρου δεν μπορεί να μείνει κενό. + + + This filter name is already in use. + Αυτό το όνομα φίλτρου ήδη χρησιμοποιείται. + + + Choose save path + Επιλέξτε διαδρομή αποθήκευσης + + + Filter testing error + Σφάλμα δοκιμής φίλτρου + + + Please specify a test torrent name. + Παρακαλώ διευκρινήστε ένα δοκιμαστικό όνομα torrent. + + + matches + αντιστοιχίες + + + does not match + δεν αντιστοιχεί + + + Select file to import + Επιλέξτε αρχείο για είσαγωγή + + + Filters Files + Αρχεία Φίλτρων + + + Import successful + Επιτυχής εισαγωγή + + + Filters import was successful. + Η εισαγωγή των φίλτρων ήταν επιτυχής. + + + Import failure + Σφάλμα εισαγωγής + + + Filters could not be imported due to an I/O error. + Τα φίλτρα δεν ήταν δυνατό να εισαχθούν εξαιτίας ενός σφάλματος I/O. + + + Select destination file + Επιλογή αρχείου προορισμού + + + Export successful + Εξαγωγή επιτυχής + + + Filters export was successful. + Η εξαγωγή των φίλτρων ήταν επιτυχής. + + + Export failure + Αποτυχία εξαγωγής + + + Filters could not be exported due to an I/O error. + Τα φίλτρα δεν ήταν δυνατό να εξαχθούν εξαιτίας ενός σφάλματος I/O. + + + + FeedList + + Unread + Μη διαβασμένα + + + + FeedListWidget + + + RSS feeds + Παροχές RSS + + + + Unread + Μη διαβασμένα + + + + GUI + + Open Torrent Files + Άνοιγμα Αρχείων torrent + + + Torrent Files + Αρχεία torrent + + + qBittorrent + qBittorrent + + + Transfers + Μεταφορές + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Ταχύτητα Λήψης: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Ταχύτητα Αποστολής: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Έχει τελειώσει η λήψη του '%1'. + + + I/O Error + i.e: Input/Output Error + I/O Σφάλμα + + + Search + Εύρεση + + + Torrent file association + Συσχετισμός με αρχεία τόρεντ + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + Το qBittorrent δεν είναι η προεπιλεγμένη εφαρμογή για το άνοιγμα αρχείων torrent και Magnet link. +Θέλετε να συσχετίσετε το qBittorrent με τα αρχεία τόρεντ και Magnet link? + + + RSS + RSS + + + Transfers (%1) + Μεταφορές (%1) + + + Download completion + Ολοκλήρωση λήψης + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Ένα σφάλμα I/O προέκυψε για το torrent %1 + Αιτία: %2 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Recursive download confirmation + Επιβεβαίωση σχετικού (recursive) κατεβάσματος + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Το τόρεντ %1 περιέχει άλλα αρχεία τόρεντ, θέλετε να συνεχίσετε και να τα κατεβάσετε? + + + A newer version is available + Μια νεότερη έκδοση είναι διαθέσιμη + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Μια νεότερη έκδοση του qBittorrent είναι διαθέσιμη στο Sourceforge. +Θα θέλατε να αναβαθμίσετε το QBittorrent στην έκδοση %1? + + + Impossible to update qBittorrent + Αδυναμία ανανέωσης του qBittorrent + + + qBittorrent failed to update, reason: %1 + Το qBittorrent απέτυχε να κάνει ανανέωση, αιτία: %1 + + + Exiting qBittorrent + Έξοδος από το qBittorrent + + + Always + Πάντα + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Κάτ.: %2/s, Αν.: %3/s) + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Σφάλμα λήψης url + + + Couldn't download file at url: %1, reason: %2. + Αδυναμία λήψης αρχείου από το url: %1,αιτία: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Yes + Ναι + + + No + Όχι + + + Never + Ποτέ + + + Global Upload Speed Limit + Συνολικό Όριο Ταχύτητας Αποστολής + + + Global Download Speed Limit + Συνολικό Όριο Ταχύτητας Λήψης + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Μερικά αρχεία μεταφέρονται τώρα. +Είστε σίγουρος πως θέλετε να κλείσετε το qBittorrent? + + + Options were saved successfully. + Οι επιλογές αποθηκεύτηκαν επιτυχώς. + + + + GeoIP + + Australia + Αυστραλία + + + Argentina + Αργεντινή + + + Austria + Αυστρία + + + United Arab Emirates + Ηνωμένα Αραβικά Εμιράτα + + + Brazil + Βραζιλία + + + Bulgaria + Βουλγαρία + + + Belarus + Λευκορωσία + + + Belgium + Βέλγιο + + + Bosnia + Βοσνία + + + Canada + Καναδάς + + + Czech Republic + Τσεχική Δημοκρατία + + + China + Κίνα + + + Costa Rica + Κόστα Ρίκα + + + Switzerland + Ελβετία + + + Germany + Γερμανία + + + Denmark + Δανία + + + Algeria + Αλγερία + + + Spain + Ισπανία + + + Egypt + Αίγυπτος + + + Finland + Φινλανδία + + + France + Γαλλία + + + United Kingdom + Ηνωμένο Βασίλειο + + + Greece + Ελλάδα + + + Georgia + Γεωργία + + + Hungary + Ουγγαρία + + + Croatia + Κροατία + + + Italy + Ιταλία + + + India + Ινδία + + + Israel + Ισραήλ + + + Ireland + Ιρλανδία + + + Iceland + Ισλανδία + + + Indonesia + Ινδονησία + + + Japan + Ιαπωνία + + + South Korea + Νότιος Κορέα + + + Luxembourg + Λουξεμβούργο + + + Malaysia + Μαλαισία + + + Mexico + Μεξικό + + + Serbia + Σερβία + + + Morocco + Μαρόκο + + + Netherlands + Ολλανδία + + + Norway + Νορβηγία + + + New Zealand + Νέα Ζηλανδία + + + Portugal + Πορτογαλία + + + Poland + Πολωνία + + + Pakistan + Πακιστάν + + + Philippines + Φιλιππίνες + + + Russia + Ρωσσία + + + Romania + Ρουμανία + + + France (Reunion Island) + Γαλλία (Νήσοι Ρεϊνιόν) + + + Saudi Arabia + Σαουδική Αραβία + + + Sweden + Σουηδία + + + Slovakia + Σλοβακία + + + Singapore + Σιγκαπούρη + + + Slovenia + Σλοβενία + + + Taiwan + Ταϊβάν + + + Turkey + Τουρκία + + + Thailand + Ταϊλάνδη + + + USA + ΗΠΑ + + + Ukraine + Ουκρανία + + + South Africa + Νότιος Αφρική + + + + HeadlessLoader + + + Information + Πληροφορίες + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Για να ελέγχετε το qBittorrent, χρησιμοποιείστε το Web UI στο http://localhost:%1 + + + + The Web UI administrator user name is: %1 + Το όνομα χρήστη διαχειριστή Web UI είναι: %1 + + + + The Web UI administrator password is still the default one: %1 + Ο κωδικός πρόσβασης διαχειριστή είναι ακόμα ο προκαθορισμένος: %1 + + + + This is a security risk, please consider changing your password from program preferences. + Αυτό είναι ένα ρίσκο ασφαλείας, παρακαλώ σκεφτείτε να αλλάξετε τον κωδικό από τις ρυθμίσεις προγράμματος. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + Η IP διεύθυνσή σας έχει απαγορευτεί μετά από πολλές αποτυχημένες προσπάθειες ταυτοποίησης. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Λήψ: %1 B/s - Μετ: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Απ: %1 B/s - Μετ: %2 + + + + HttpServer + + + File + Αρχείο + + + + Edit + Επεξεργασία + + + + Help + Βοήθεια + + + Delete from HD + Διαγραφή από τον σκληρό δίσκο + + + + Download Torrents from their URL or Magnet link + Κατέβασμα torrent από το URL τους ή από το Magnet link τους + + + + Only one link per line + Μόνο ένα URL ανά γραμμή + + + + Download local torrent + Κατέβασμα τοπικού torrent + + + + Torrent files were correctly added to download list. + Τα αρχεία torrent προστέθηκαν επιτυχώς στη λίστα ληφθέντων. + + + + Point to torrent file + Προσπέλαση στο αρχείο torrent + + + + Download + Κατέβασμα + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Είστε σίγουρος οτι θέλετε να διαγράψετε τα συγκεκριμένα torrent από την λίστα μεταφορών και το σκληρό δίσκο? + + + + Download rate limit must be greater than 0 or disabled. + Το όριο λήψης πρέπει να είναι μεγαλύτερο του 0 ή απενεργοποιημένο. + + + + Upload rate limit must be greater than 0 or disabled. + Το όριο αποστολής πρέπει να είναι μεγαλύτερο του 0 ή απενεργοποιημένο. + + + + Maximum number of connections limit must be greater than 0 or disabled. + Ο μέγιστος αριθμός συνδέσεων πρέπει να είναι μεγαλύτερος του 0 ή απενεργοποιημένος. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Ο μέγιστος αριθμός συνδέσεων ανά torrent πρέπει να είναι μεγαλύτερος του 0 ή απενεργοποιημένος. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Ο μέγιστος αριθμός θυρίδων ανεβάσματος ανά torrent πρέπει να είναι μεγαλύτερος του 0 ή απενεργοποιημένος. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Αδύνατο να αλλάξουν οι προτιμήσεις, το qBittorrent είναι πιθανότατα απρόσιτο. + + + + Language + Γλώσσα + + + + Downloaded + Is the file downloaded or not? + Κατεβασμένο + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Η θύρα που χρησιμοποιείται για εισερχόμενες συνδέσεις πρέπει να είναι μεγαλύτερη από την 1024 και μικρότερη από την 65535. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Η θύρα που χρησιμοποιείται για το Web UI πρέπει να είναι μεγαλύτερη από την 1024 και μικρότερη από την 65535. + + + + The Web UI username must be at least 3 characters long. + Το όνομα χρήστη του Web UI πρέπει να έχει μήκος τουλάχιστο 3 χαρακτήρες. + + + + The Web UI password must be at least 3 characters long. + Ο κωδικός του Web UI πρέπει να έχει μήκος τουλάχιστο 3 χαρακτήρες. + + + + Save + Αποθήκευση + + + + qBittorrent client is not reachable + + + + + HTTP Server + Διακομιστής HTTP + + + + The following parameters are supported: + Οι παρακάτω παράμετροι υποστηρίζονται: + + + + Torrent path + Διαδρομή τόρεντ + + + + Torrent name + Όνομα τόρεντ + + + + LegalNotice + + + Legal Notice + Gonna look it up a bit... maybe just "ειδοποίηση" + Νομική Ειδοποίηση + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + Το qbittorrent είναι ένα πρόγραμμα διαμοιρασμού αρχείων. Όταν χρησιμοποιείτε ένα τόρεντ, τα στοιχεία του θα γίνονται διαθέσιμα για άλλους χρήστες υπό τη μορφή ανεβάσματος. Οποιοδήποτε περιεχόμενο μοιράζεστε είναι δική σας ευθύνη. + +Δεν θα υπάρξουν άλλες υπενθυμίσεις. + + + + Press %1 key to accept and continue... + Πατήστε το %1 για αποδοχή και συνέχεις... + + + + Legal notice + Νομική Ειδοποίηση + + + + Cancel + Ακύρωση + + + + I Agree + Συμφωνώ + + + + LineEdit + + + Clear the text + Εκκαθάριση κειμένου + + + + MainWindow + + + &Edit + &Αλλαγή + + + + &Tools + &Eργαλεία + + + + &File + &Αρχείο + + + + &Help + &Βοήθεια + + + + &View + &Προβολή + + + &Add File... + &Προσθήκη Αρχείου... + + + E&xit + Έ&ξοδος + + + + &Options... + &Ρυθμίσεις... + + + Add &URL... + Προσθήκη &URL... + + + + Torrent &creator + Δημιουργός &τόρεντ + + + + Set upload limit... + Ρύθμιση ορίου αποστολής... + + + + Set download limit... + Ρύθμιση ορίου λήψης... + + + + &About + &Σχετικά + + + + &Pause + &Παύση + + + + &Delete + &Διαγραφή + + + + P&ause All + Π&αύση Όλων + + + + &Resume + &Συνέχιση + + + + &Add torrent file... + &Προσθήκη αρχείου τόρεντ... + + + + + Exit + Έξοδος + + + + R&esume All + Σ&υνέχιση Όλων + + + + Visit &Website + Επίσκεψη &Ιστοσελίδας + + + + Auto-Shutdown on downloads completion + Αυτόματος τερματισμός λειτουργίας μετά την ολοκλήρωση των κατεβασμάτων + + + + Add &link to torrent... + Προσθήκη &συνδέσμου στο τόρεντ... + + + + Report a &bug + Αναφορά &Σφάλματος + + + + &Documentation + &Έγγραφα + + + + Set global download limit... + Ρύθμιση συνολικού ορίου λήψης... + + + + Set global upload limit... + Ρύθμιση συνολικού ορίου αποστολής... + + + + Exit qBittorrent + Έξοδος από το qBittorrent + + + + Suspend system + Αναστολή λειτουργίας + + + + Shutdown system + Τερματισμός λειτουργίας συστήματος + + + + Disabled + Απενεργοποιημένο + + + &Log viewer... + &Καταγραφή γεγονότων... + + + Log viewer + Καταγραφή γεγονότων + + + Shutdown computer when downloads complete + Αναστολή λειτουργίας υπολογιστή μετά την ολοκλήρωση των κατεβασμάτων + + + + + Lock qBittorrent + Κλείδωμα του qBittorrent + + + + Ctrl+L + Ctrl+L + + + Shutdown qBittorrent when downloads complete + Έξοδος από το qBittorrent μετά την ολοκλήρωση των κατεβασμάτων + + + + Import existing torrent... + Εξαγωγή υπάρχοντος τόρεντ... + + + + Import torrent... + Εισαγωγή τόρεντ... + + + + Donate money + Κάντε μια δωρεά + + + + If you like qBittorrent, please donate! + Αν σας άρεσε το qBittorrentq, σας παρακαλούμε κάντε μια δωρεά! + + + + Execution &Log + &Αρχείο εκτελεσθέντων + + + + + Execution Log + Αρχείο εκτελεσθέντων + + + + + Alternative speed limits + Εναλλακτικά όρια ταχύτητας + + + + &RSS reader + &RSS αναγβώστης + + + + Search &engine + Μηχανή &αναζήτησης + + + + Top &tool bar + Άνω μπάρα &εργαλείων + + + + Display top tool bar + Εμφάνιση άνω μπάρας εργαλείων + + + + &Speed in title bar + &Ταχύτητα στην μπάρα τίτλου + + + + Show transfer speed in title bar + Ένδειξη ταχύτητας μεταφορών στην μπάρα τίτλου + + + Preview file + Προεπισκόπηση αρχείου + + + Clear log + Εκκαθάριση καταγραφών + + + + Decrease priority + Μείωσε προτεραιότητα + + + + Increase priority + Αύξησε προτεραιότητα + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + Καθορίστε τον κωδικό... + + + + Transfers + Μεταφορές + + + + Torrent file association + Συσχετισμός με αρχεία τόρεντ + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + Το qBittorrent δεν είναι η προεπιλεγμένη εφαρμογή για το άνοιγμα αρχείων τόρεντ και Magnet link. +Θέλετε να συσχετίσετε το qBittorrent με τα αρχεία τόρεντ και Magnet link? + + + + + + UI lock password + Κωδικός κλειδώματος UI + + + + + + Please type the UI lock password: + Παρακαλώ εισάγετε τον κωδικό κλειδώματος του UI: + + + + The password should contain at least 3 characters + Ο κωδικός πρέπει να περιέχει τουλάχιστο 3 χαρακτήρες + + + + Password update + Ανανέωση κωδικού + + + + The UI lock password has been successfully updated + Η ανανέωση του κωδικού για το UI πραγματοποιήθηκε επιτυχώς + + + + RSS + RSS + + + + Search + Αναζήτηση + + + + Transfers (%1) + Μεταφορές (%1) + + + + Download completion + Ολοκλήρωση λήψης + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Έχει τελειώσει η λήψη του '%1'. + + + + I/O Error + i.e: Input/Output Error + Σφάλμα I/O + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Ένα σφάλμα I/O προέκυψε για το torrent %1 + Αιτία: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Επιβεβαίωση σχετικού (recursive) κατεβάσματος + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Το τόρεντ %1 περιέχει άλλα αρχεία τόρεντ, θέλετε να συνεχίσετε και να τα κατεβάσετε? + + + + + Yes + Ναι + + + + + No + Όχι + + + + Never + Ποτέ + + + + Url download error + Σφάλμα λήψης url + + + + Couldn't download file at url: %1, reason: %2. + Αδυναμία λήψης αρχείου από το url: %1,αιτία: %2. + + + + Global Upload Speed Limit + Συνολικό Όριο Ταχύτητας Αποστολής + + + + Global Download Speed Limit + Συνολικό Όριο Ταχύτητας Λήψης + + + + + Invalid password + Άκυρος κωδικός + + + + The password is invalid + Αυτός ο κωδικός είναι άκυρος + + + + Exiting qBittorrent + Έξοδος από το qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Μερικά αρχεία μεταφέρονται τώρα. +Είστε σίγουρος οτι θέλετε να κλείσετε το qBittorrent? + + + + Always + Πάντα + + + + Open Torrent Files + Άνοιγμα Αρχείων torrent + + + + Torrent Files + Αρχεία torrent + + + + Options were saved successfully. + Οι επιλογές αποθηκεύτηκαν επιτυχώς. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Ταχύτητα Λήψης: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Ταχύτητα Αποστολής: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Κάτ.: %2/s, Αν.: %3/s) + + + + A newer version is available + Μια νεότερη έκδοση είναι διαθέσιμη + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Μια νεότερη έκδοση του qBittorrent είναι διαθέσιμη στο Sourceforge. +Θα θέλατε να αναβαθμίσετε το QBittorrent στην έκδοση %1? + + + + Impossible to update qBittorrent + Αδυναμία ανανέωσης του qBittorrent + + + + qBittorrent failed to update, reason: %1 + Το qBittorrent απέτυχε να κάνει ανανέωση, αιτία: %1 + + + + PeerAdditionDlg + + + Invalid IP + Άκυρη IP + + + + The IP you provided is invalid. + Η IP που δώσατε είναι άκυρη. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + IP + + + + Connection + Σύνδεση + + + + Client + i.e.: Client application + Πελάτης + + + + Progress + i.e: % downloaded + Πρόοδος + + + + Down Speed + i.e: Download speed + Ταχύτητα Λήψης + + + + Up Speed + i.e: Upload speed + Ταχύτητα Αποστολής + + + + Downloaded + i.e: total data downloaded + Ληφθέντα + + + + Uploaded + i.e: total data uploaded + Απεσταλμένα + + + + Add a new peer... + Προσθήκη νέας σύνδεσης... + + + + Copy IP + Αντιγραφή IP + + + + Limit download rate... + Όριο ταχύτητας λήψης... + + + + Limit upload rate... + Όριο ταχύτητας αποστολής... + + + + Ban peer permanently + Μόνιμο μπλοκάρισμα σύνδεσης + + + + + Peer addition + Προσθήκη σύνδεσης + + + + The peer was added to this torrent. + Η σύνδεση προστέθηκε σ'αυτό το torrent. + + + + The peer could not be added to this torrent. + Η σύνδεση δεν ήταν δυνατό να προστεθεί σ'αυτό το torrent. + + + + Are you sure? -- qBittorrent + Είστε σίγουρος? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Είστε σίγουρος οτι θέλετε να μπλοκάρετε μόνιμα τις επιλεγμένες συνδέσεις? + + + + &Yes + &Ναι + + + + &No + &Όχι + + + + Manually banning peer %1... + Χειροκίνητο μπλοκάρισμα σύνδεσης %1... + + + + Upload rate limiting + Περιορισμός ορίου αποστολής + + + + Download rate limiting + Περιορισμός ορίου λήψης + + + + Preferences + + UI + User Interface + UI + + + + Downloads + Λήψεις + + + + Connection + Σύνδεση + + + + Speed + Ταχύτητα + + + Bittorrent + Bittorrent + + + Proxy + Proxy + + + + Web UI + Web UI + + + + Advanced + Για προχωρημένους + + + Language: + Γλώσσα: + + + + (Requires restart) + (Απαιτεί επανεκκίνηση) + + + Visual style: + Στυλ: + + + Transfer list + Μεταφορές + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Χρήση εναλασσόμενων χρωμάτων στις σειρές + + + + + Start / Stop Torrent + Έναρξη/Παύση Τόρεντ + + + + + No action + Καμία δράση + + + File system + Σύστημα αρχείων + + + + Copy .torrent files to: + Αντιγραφή .torrent αρχείων στο: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Οι παρακάτω παράμετροι υποστηρίζονται: +<ul> +<li>%f: Διαδρομή τόρεντ</li> +<li>%n: Όνομα τόρεντ</li> +</ul> + + + Torrent queueing + Σειρά torrent + + + + Maximum active downloads: + Μέγιστος αριθμός ενεργών λήψεων: + + + + Maximum active uploads: + Μέγιστος αριθμός ενεργών αποστολών: + + + + Maximum active torrents: + Μέγιστος αριθμός ενεργών τόρεντ: + + + + When adding a torrent + Όταν προστίθεται κάποιο τόρεντ + + + + + Options + Επιλογές + + + Visual Appearance + Εμφάνιση + + + + Action on double-click + Ενέργεια στο διπλό κλικ + + + + Downloading torrents: + Τόρεντ που κατεβαίνουν: + + + Start / Stop + Έναρξη / Παύση + + + + + Open destination folder + Άνοιγμα φακέλου προορισμού + + + + Completed torrents: + Ολοκληρωμένα τόρεντ: + + + + Desktop + Επιφάνεια εργασίας + + + + Show splash screen on start up + Εμφάνιση splash screen κατά την έναρξη + + + + Start qBittorrent minimized + Έναρξη του qBittorrent σε ελαχιστοποίηση + + + Show qBittorrent icon in notification area + Εμφάνιση του εικονιδίου του qBittorrent στην περιοχή των ειδοποιήσεων + + + Use monochrome system tray icon (requires restart) + Χρήση μονόχρωμου εικονιδίου μπάρας εργασιών (απαιτεί επανεκκίνηση) + + + + Minimize qBittorrent to notification area + Ελαχιστοποίηση του qBittorrent στην περιοχή ειδοποιήσεων + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Κλείσιμο του qBittorrent στην περιοχή ειδοποιήσεων + + + + Tray icon style: + Στυλ εικόνας εργασιών + + + + Normal + Κανονικό + + + + Monochrome (Dark theme) + Μονόχρωμο (Dark theme) + + + + Monochrome (Light theme) + Μονόχρωμο (Light theme) + + + + Ask for program exit confirmation + Ερώτηση για επιβεβαίωση εξόδου + + + + User Interface Language: + Γλώσσα User Interface: + + + + Transfer List + Λίστα Μεταφορών + + + + Show qBittorrent in notification area + Εμφάνιση του qBittorrent στην περιοχή ειδοποιήσεων + + + + Power Management + Διαχείριση ενέργειας + + + + Inhibit system sleep when torrents are active + Ακύρωση αναμονής υπολογιστή όταν υπάρχουν ενεργά τόρεντ + + + + Display torrent content and some options + Εμφάνιση περιεχομένων τόρεντ και μερικών ρυθμίσεων + + + + Do not start the download automatically + The torrent will be added to download list in pause state + Μη αυτόματη έναρξη του κατεβάσματος + + + + Hard Disk + Σκληρός Δίσκος + + + + Save files to location: + Αποθήκευση αρχείων στην τοποθεσία: + + + + Append the label of the torrent to the save path + Εγγραφή της ετικέτας του τόρεντ στην διαδρομή αποθήκευσης + + + + Pre-allocate disk space for all files + Αρχική κατάληψη του σκληρού δίσκου για όλα τα αρχεία + + + + Keep incomplete torrents in: + Να μένουν τα μη τελειωμένα τόρεντ στο: + + + Append .!qB extension to incomplete files' names + Να προστίθεται η κατάληψη .!qB στα ονόματα μη τελειωμένων αρχείων + + + + Automatically add torrents from: + Αυτόματη προσθήκη τόρεντ από: + + + + Add folder... + Προσθήκη φακέλου... + + + + Email notification upon download completion + Ειδοποίηση ηλεκτρονικού ταχυδρομείου μετά την ολοκλήρωση του κατεβάσματος + + + + Destination email: + Email προορισμού: + + + + SMTP server: + Διακομιστής SMTP: + + + + This server requires a secure connection (SSL) + Αυτός ο εξυπηρετητής απαιτεί μια ασφαλή σύνδεση (SSL) + + + + Run an external program on torrent completion + Εκτέλεση ενός εξωτερικού προγράμματος κατά την ολοκλήρωση ενός τόρεντ + + + + Otherwise, the proxy server is only used for tracker connections + Ειδάλλως, ο διακομιστής proxy χρησιμοποιείται μόνο για τις συνδέσεις του tracker + + + + Use proxy for peer connections + Χρήση proxy για συνδέσεις διαμοιραστών + + + + Global Rate Limits + Συνολικά Όρια Ταχύτητας + + + + Apply rate limit to uTP connections + Εφαρμογή ποσοστιαίου περιορισμού στις uTP συνδέσεις + + + + Apply rate limit to transport overhead + Εφαρμογή ποσοστιαίου περιορισμού στο σύνολο των μεταφορών + + + + Alternative Global Rate Limits + Συνολικά Εναλλακτικά Όρια Ποσοστών + + + + Schedule the use of alternative rate limits + Προγραμματισμός χρήσης εναλλακτικών ορίων ποσοστών + + + + Use HTTPS instead of HTTP + Χρήση HTTPS αντί για HTTP + + + + Import SSL Certificate + Εισαγωγή Πιστοποιητικού SSL + + + + Import SSL Key + Εισαγωγή Κλειδιού SSL + + + + Certificate: + Πιστοποιητικό: + + + + Key: + Κλειδί: + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Πληροφορίες σχετικά με τα πιστοποιητικά</a> + + + + Update my dynamic domain name + Ανανέωση του δυναμικού domain name μου + + + + Service: + Υπηρεσία: + + + + Register + Εγγραφή + + + + Domain name: + Domain name: + + + Use %f to pass the torrent path in parameters + Χρήση του %f για να περαστεί η διαδρομή του τόρεντ στις παραμέτρους + + + + Use UPnP / NAT-PMP port forwarding from my router + Χρήση UPnP / NAT - PMP port forwarding από το ρούτερ μου + + + Proxy server + Διακομιστής Proxy + + + + Reload the filter + Ανανέωση φίλτρου + + + + Enable bandwidth management (uTP) + Χρήση διαχείρισης εύρους σύνδεσης (uTP) + + + + Privacy + Προσωπικά δεδομένα + + + + Enable DHT (decentralized network) to find more peers + Ενεργοποίηση DHT (αποκεντροποιημένο δίκτυο) για την εύρεση περισσοτέρων διαμοιραστών + + + + Use a different port for DHT and BitTorrent + Χρήση διαφορετικής θύρας για DHT και BitTorrent + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Ανταλλαγή συνδέσεων με συμβατά προγράμματα Bittorrent (μTorrent, Vuze, ...) + + + + Enable Peer Exchange (PeX) to find more peers + Ενεργοποίηση Peer Exchange (PeX) για την εύρεση περισσοτέρων διαμοιραστών + + + + Enable Local Peer Discovery to find more peers + Ενεργοποίηση Ανακάλυψης Νέων Συνδέσεων Δικτύου για την εύρεση περισσοτέρων διαμοιραστών + + + + Encryption mode: + Κατάσταση κρυπτογράφησης: + + + + Prefer encryption + Προτίμησε την κωδικοποίηση + + + + Require encryption + Απαίτησε κωδικοποίηση + + + + Disable encryption + Απενεργοποίησε την κωδικοποίηση + + + Share ratio limiting + Όριο ποσοστού διαμοιρασμού + + + + Seed torrents until their ratio reaches + Διαμοιρασμός τόρεντ μέχρι να φτάσουν σε αναλογία + + + + then + τότε + + + + Pause them + Παύση τους + + + + Remove them + Αφαίρεσή τους + + + + Enable Web User Interface (Remote control) + Ενεργοποίηση Web User Interface (Απομακρυσμένη διαχείριση) + + + + Use UPnP / NAT-PMP to forward the port from my router + Χρήση UPnP / NAT - PMP για την προώθηση της θύρας από το ρούτερ μου + + + + Bypass authentication for localhost + Παράβλεψη αυθεντικότητας για τον localhost + + + Listening port + Επικοινωνία θύρας + + + + Port used for incoming connections: + Θύρα που χρησιμοποιείται για εισερχόμενες συνδέσεις: + + + + Random + Τυχαία + + + Enable UPnP port mapping + Ενεργοποίηση χαρτογράφησης θυρών UPnP + + + Enable NAT-PMP port mapping + Ενεργοποίηση χαρτογράφησης θυρών NAT-PMP + + + Connections limit + Όριο συνδέσεων + + + + Global maximum number of connections: + Συνολικός αριθμός μεγίστων συνδέσεων: + + + + Maximum number of connections per torrent: + Μέγιστος αριθμός συνδέσεων ανά torrent: + + + + Maximum number of upload slots per torrent: + Μέγιστες θυρίδες αποστολής ανά torrent: + + + + + Upload: + Αποστολή: + + + + + Download: + Λήψη: + + + + + + + KiB/s + KiB/s + + + User Interface + User Interface + + + + BitTorrent + Bittorrent + + + Global speed limits + Συνολικό όριο ταχύτητας + + + Alternative global speed limits + Συνολικά εναλλακτικά όρια ταχύτητας + + + + to + time1 to time2 + έως + + + + Every day + Κάθε μέρα + + + + Week days + Καθημερινές μέρες + + + + Week ends + Σαββατοκύριακα + + + Bittorrent features + Λειτουργίες Bittorrent + + + Enable DHT network (decentralized) + Ενεργοποίηση δικτύου DHT (αποκεντροποιημένο) + + + Use a different port for DHT and Bittorrent + Χρήση διαφορετικής θύρας για DHT και Bittorrent + + + + DHT port: + Θύρα DHT: + + + Enable Peer Exchange / PeX (requires restart) + Left as is; We want the user to see PeX later and know what it is ;) + Ενεργοποίηση Peer Exchange / PeX (απαιτεί επανεκκίνηση) + + + Enable Local Peer Discovery + Ενεργοποίηση Ανακάλυψης Νέων Συνδέσεων + + + Enabled + Ενεργοποιημένο + + + Forced + Εξαναγκασμένο + + + Disabled + Απενεργοποιημένο + + + HTTP Communications (trackers, Web seeds, search engine) + Επικοινωνίες HTTP (ιχνηλάτες, διαμοιραστές, μηχανή αναζήτησης) + + + + Host: + Διακομιστής: + + + Peer Communications + Συνδέσεις με χρήστες + + + + SOCKS4 + SOCKS4 + + + + Type: + Είδος: + + + + + Behavior + Συμπεριφορά + + + + Language + Γλώσσα + + + + Append .!qB extension to incomplete files + Προσθήκη της κατάληξης .!qB στα μη ολοκληρωμένα αρχεία + + + + Remove folder + Αφαίρεση φακέλου + + + + Listening Port + Επικοινωνία θύρας + + + + Connections Limits + Όρια συνδέσεων + + + + Proxy Server + Διακομιστής Proxy + + + + IP Filtering + Φιλτράρισμα IP + + + Schedule the use of alternative speed limits + Προγραμματισμός χρήσης εναλλακτικών ορίων ταχύτητας + + + + from + from (time1 to time2) + από-έως + + + + When: + Όταν: + + + + Look for peers on your local network + Αναζήτηση για διαμοιραστές στο τοπικό σας δίκτυο + + + Protocol encryption: + Κρυπτογράφηση πρωτόκολλου: + + + + (None) + (Κανένα) + + + + HTTP + HTTP + + + + + Port: + Θύρα: + + + + + + Authentication + Πιστοποίηση + + + + + + + Username: + Όνομα χρήστη: + + + + + + + Password: + Κωδικός: + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + Διαδρομή φίλτρου (.dat, .p2p, .p2b): + + + + Torrent Queueing + Σειρά torrent + + + + Share Ratio Limiting + Όριο ποσοστού διαμοιρασμού + + + HTTP Server + Διακομιστής HTTP + + + + PreviewSelect + + + Name + Όνομα + + + + Size + Μέγεθος + + + + Progress + Πρόοδος + + + + + + Preview impossible + Αδύνατη η προεπισκόπηση + + + + + + Sorry, we can't preview this file + Λυπούμαστε, δεν μπορεί να προεσκοπηθεί αυτό το αρχείο + + + + ProgramUpdater + + Could not create the file %1 + Αδυναμία δημιουργίας αρχείου %1 + + + Failed to download the update at %1 + %1 is an URL + Αδυναμία κατεβάσματος της αναβάθμισης στο %1 + + + + PropListDelegate + + + Not downloaded + Δεν έγινε download + + + + + Normal + Normal (priority) + Κανονική + + + + + High + High (priority) + Υψηλή + + + + Mixed + Mixed (priorities + Διάφορες + + + + + Maximum + Maximum (priority) + Μέγιστη + + + + PropTabBar + + + General + Γενικά + + + + Trackers + Ιχνηλάτες + + + + Peers + Συνδέσεις + + + + HTTP Sources + Πηγές HTTP + + + + Content + Περιεχόμενο + + + URL Seeds + Διαμοιραστές URL + + + Files + Αρχεία + + + + PropertiesWidget + + + Save path: + Αποθήκευση σε: + + + + Torrent hash: + torrent hash: + + + + Share ratio: + Ποσοστό διαμοιρασμού: + + + + + Downloaded: + Κατέβηκε: + + + + Availability: + Διαθεσιμότητα: + + + + Transfer + Μεταφορά + + + + Uploaded: + Απεσταλμένα: + + + + Wasted: + Χαμένα: + + + + UP limit: + Όριο Απ.: + + + + DL limit: + Όριο Λήψ.: + + + Time elapsed: + Χρόνος που απομένει: + + + + Connections: + Συνδέσεις: + + + + Time active: + Time (duration) the torrent is active (not paused) + Χρόνος εν ενεργεία: + + + + Reannounce in: + Ανακοίνωση πάλι σε: + + + + Information + Πληροφορίες + + + + Created on: + Δημιουργήθηκε: + + + + Pieces size: + Μέγεθος κομματιών: + + + + Comment: + Σχόλιο: + + + + Torrent content: + Περιεχόμενο torrent: + + + + Select All + Επιλογή Όλων + + + + Select None + Αποεπιλογή Όλων + + + + + Do not download + Να μην γίνει download + + + General + Γενικά + + + Trackers + Ιχνηλάτες + + + Peers + Συνδέσεις + + + URL seeds + Διαμοιραστές URL + + + Files + Αρχεία + + + + Priority + Προτεραιότητα + + + + Normal + Κανονική + + + + Maximum + Μέγιστη + + + + High + Υψηλή + + + + + this session + τρέχουσα συνεδρία + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Διαμοιράστηκε για %1 + + + + %1 max + e.g. 10 max + μέγιστο %1 + + + + + I/O Error + I/O Σφάλμα + + + + This file does not exist yet. + Αυτό το αρχείο δεν υπάρχει ακόμα. + + + + This folder does not exist yet. + Αυτός ο φάκελος δεν υπάρχει ακόμα. + + + + Rename... + Μετονομασία... + + + + Rename the file + Μετονομασία αρχείου + + + + New name: + Νέο όνομα: + + + + + The file could not be renamed + Αυτό το αρχείο δεν είναι δυνατό να μετονομαστεί + + + + This file name contains forbidden characters, please choose a different one. + Αυτό το όνομα αρχείου περιέχει απαγορευμένους χαρακτήρες, παρακαλώ επιλέξτε ένα διαφορετικό. + + + + + This name is already in use in this folder. Please use a different name. + Αυτό το όνομα ήδη χρησιμοποιείται σ'αυτό το φάκελο. Παρακαλώ επιλέξτε ένα άλλο. + + + + The folder could not be renamed + Αυτός ο φάκελος δεν είναι δυνατό να μετονομαστεί + + + + New url seed + New HTTP source + Νέο url διαμοιρασμού + + + + New url seed: + Νέο url διαμοιρασμού: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Αυτό το url διαμοιρασμού είναι ήδη στη λίστα. + + + + + Choose save path + Επιλέξτε διαδρομή αποθήκευσης + + + Save path creation error + Σφάλμα δημιουργίας διαδρομής αποθήκευσης + + + Could not create the save path + Αδύνατο να δημιουργηθεί η διαδρομή αποθήκευσης + + + + QBtSession + + + + %1 reached the maximum ratio you set. + Το %1 έφτασε στη μέγιστη αναλογία που θέσατε. + + + + Removing torrent %1... + Αφαίρεση του τόρεντ %1... + + + + Pausing torrent %1... + Παύση του τόρεντ %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + Το qBittorrent χρησιμοποιεί τη θύρα: TCP/%1 + + + UPnP support [ON] + Υποστήριξη UPnP [ΝΑΙ] + + + UPnP support [OFF] + Υποστήριξη UPnP [ΟΧΙ] + + + NAT-PMP support [ON] + Υποστήριξη NAT-PMP [NAI] + + + NAT-PMP support [OFF] + Υποστήριξη NAT-PMP [OXI] + + + + HTTP user agent is %1 + Η εφαρμογή HTTP σας είναι %1 + + + Using a disk cache size of %1 MiB + Χρησιμοποιείται προσωρινή μνήμη δίσκου, %1 MiB + + + + DHT support [ON], port: UDP/%1 + Υποστήριξη DHT [NAI], θύρα: UDP/%1 + + + + + DHT support [OFF] + Υποστήριξη DHT [ΟΧΙ] + + + + PeX support [ON] + Υποστήριξη PeX [ΝΑΙ] + + + + PeX support [OFF] + Υποστήριξη PeX [ΟΧΙ] + + + + Restart is required to toggle PeX support + Απαιτείται επανεκκίνηση για να αλλάξουν οι ρυθμίσεις PeX + + + Local Peer Discovery [ON] + Ανακάλυψη Τοπικών Συνδέσεων [ΝΑΙ] + + + + Local Peer Discovery support [OFF] + Ανακάλυψη Τοπικών Συνδέσεων [ΟΧΙ] + + + + Encryption support [ON] + Υποστήριξη κρυπτογράφησης [ΝΑΙ] + + + + Encryption support [FORCED] + Υποστήριξη κρυπτογράφησης [ΕΞΑΝΑΓΚΑΣΜΕΝΗ] + + + + Encryption support [OFF] + Υποστήριξη κρυπτογράφησης [ΟΧΙ] + + + + Embedded Tracker [ON] + Ενσωματομένος Ιχνηλάτης [ΝΑΙ] + + + + Failed to start the embedded tracker! + Αποτυχία έναρξης ενσωματομένου ιχνηλάτη! + + + + Embedded Tracker [OFF] + Ενσωματομένος Ιχνηλάτης [ΟΧΙ] + + + + The Web UI is listening on port %1 + Το Web UI χρησιμοποιεί τη θύρα %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Σφάλμα Web User Interface - Αδύνατο να συνδεθεί το Web UI στην θύρα %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + To '%1' αφαιρέθηκε από την λίστα ληφθέντων και τον σκληρό δίσκο. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + Το '%1' αφαιρέθηκε από την λίστα ληφθέντων. + + + + '%1' is not a valid magnet URI. + Το '%1' δεν είναι ένα έγκυρο magnet URI. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + Το '%1' είναι ήδη στη λίστα των λαμβανόμενων. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + Το '%1' ξανάρχισε. (γρήγορη επανασύνδεση) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + Το '%1' προστέθηκε στη λίστα των λαμβανόμενων. + + + + UPnP / NAT-PMP support [ON] + Υποστήριξη UpnP / NAT-PMP [NAI] + + + + UPnP / NAT-PMP support [OFF] + Υποστήριξη UpnP / NAT-PMP [ΟΧΙ] + + + + Reporting IP address %1 to trackers... + Αναφορά της διεύθυνσης ΙΡ %1 στους ιχνηλάτες... + + + + Local Peer Discovery support [ON] + Ανακάλυψη Τοπικών Συνδέσεων [ΝΑΙ] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Αδύνατο να αποκωδικοποιηθεί το αρχείο torrent: '%1' + + + + This file is either corrupted or this isn't a torrent. + Το αρχείο είναι είτε κατεστραμμένο ή δεν είναι torrent. + + + + Error: The torrent %1 does not contain any file. + Σφάλμα: Το τόρεντ %1 δεν περιέχει κανένα αρχείο. + + + + Note: new trackers were added to the existing torrent. + Σημείωση: νέοι trackers προστέθηκαν στο υπάρχον torrent. + + + + Note: new URL seeds were added to the existing torrent. + Σημείωση: νέοι διαμοιραστές μέσω URL προστέθηκαν στο ήδη υπάρχον torrent. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>μπλοκαρίστηκε εξαιτίας του φίλτρου IP σας</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>απαγορεύτηκε εξαιτίας κατεστραμμένων κομματιών</i> + + + + The network interface defined is invalid: %1 + Το δικτυακό interface που ορίσατε είναι άκυρο: %1 + + + + Trying any other network interface available instead. + Δοκιμή κάθε άλλου δικτυακού interface. + + + + Listening on IP address %1 on network interface %2... + Αναμονή στην διεύθυνση ΙΡ %1 στο interface δικτύου %2... + + + + Failed to listen on network interface %1 + Αποτυχία αναμονής στο interface δικτύου %1 + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Προγραμματισμένο κατέβασμα του αρχείου %1,που βρίσκεται στο torrent %2 + + + + + Unable to decode %1 torrent file. + Αδύνατο να αποκωδικοποιηθεί το αρχείο torrent %1. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Ο υπολογιστής θα τεθεί σε λειτουργία αναμονής εκτός αν το ακυρώσετε στα επόμενα 15 δευτερόλεπτα... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Ο υπολογιστής θα απενεργοποιηθεί εκτός αν το ακυρώσετε στα επόμενα 15 δευτερόλεπτα... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + Το qBittorrent θα κλείσει, εκτός αν το ακυρώσετε στα επόμενα 15 δευτερόλεπτα... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Η ανάγνωση του δοθέντος IP φίλτρου ήταν επιτυχής: %1 κανόνες εφαρμόστηκαν. + + + + Error: Failed to parse the provided IP filter. + Σφάλμα: Αποτυχία ανάγνωσης του δοθέντος φίλτρου IP. + + + + Torrent name: %1 + Όνομα τόρεντ: %1 + + + + Torrent size: %1 + Μέγεθος τόρεντ: %1 + + + + Save path: %1 + Διαδρομή αποθήκευσης: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Το τόρεντ κατέβηκε σε %1. + + + + Thank you for using qBittorrent. + Σας ευχαριστούμε που χρησιμοποιείτε το qBittorrent. + + + + [qBittorrent] %1 has finished downloading + Το κατέβασμα του [qBittorrent] %1 τελείωσε + + + + An I/O error occured, '%1' paused. + Ένα σφάλμα I/O προέκυψε, το '%1' είναι σε παύση. + + + + + Reason: %1 + Αιτία: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Σφάλμα χαρτογράφησης θυρών, μήνυμα: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Χαρτογράφηση θυρών επιτυχής, μήνυμα: %1 + + + + File sizes mismatch for torrent %1, pausing it. + Τα μεγέθη των αρχείων δεν είναι σε αντιστοιχία για το τόρεντ %1, γίνεται παύση. + + + + Fast resume data was rejected for torrent %1, checking again... + Γρήγορη επανεκκίνηση αρχείων απορρίφθηκε για το torrent %1, γίνεται επανέλεγχος... + + + + Url seed lookup failed for url: %1, message: %2 + Αποτυχία ελέγχου url διαμοιρασμού για το url: %1, μήνυμα: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Κατέβασμα του '%1', παρακαλώ περιμένετε... + + + + RSS + + + Search + Αναζήτηση + + + + New subscription + Νέα εγγραφή + + + + + + Mark items read + Μαρκάρισμα αντικειμένων ως διαβασμένα + + + + Update all + Ανανέωση όλων + + + + RSS Downloader... + Κατέβασμα RSS... + + + + Settings... + Ρυθμίσεις... + + + RSS feed downloader... + Κατέβασμα παροχών RSS... + + + + New folder... + Νέος φάκελος... + + + + Manage cookies... + Διαχείριση cookies... + + + Feed URL + URL Παροχής + + + + Rename... + Μετονομασία... + + + + + Update + Ανανέωση + + + RSS feeds + Παροχές RSS + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">torrent:</span> <span style=" font-style:italic;">(διπλό κλικ για λήψη)</span></p></body></html> + + + Article title + Τίτλος άρθρου + + + + New subscription... + Νέα εγγραφή... + + + + + Update all feeds + Ανανέωση όλων των παροχών + + + + + Delete + Διαγραφή + + + + Rename + Μετονομασία + + + + Download torrent + Λήψη torrent + + + + Open news URL + Άνοιγμα URL ειδήσεων + + + + Copy feed URL + Αντιγραφή URL παροχής + + + + Refresh RSS streams + Ανανέωση RSS τροφοδοτήσεων + + + + RSSImp + + + Please type a rss stream url + Παρακαλώ εισάγετε ένα url τροφοδοσίας rss + + + + Stream URL: + URL τροφοδοσίας: + + + + + Are you sure? -- qBittorrent + Είστε σίγουρος? -- qBittorrent + + + + + &Yes + &Ναι + + + + + &No + &Όχι + + + + Please choose a folder name + Παρακαλώ επιλέξτε ένα όνομα φακέλου + + + + Folder name: + Όνομα φακέλου: + + + + New folder + Νέος φάκελος + + + + Overwrite attempt + Προσπάθεια επαννεγγραφής + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Δεν προρείτε να επανεγγράψετε το myFolder αντικείμενο. + Δεν μπορείτε να επανεγγράψετε το %1 αντικείμενο. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Αυτή η τροφοδοσία rss είναι ήδη στη λίστα. + + + + Are you sure you want to delete these elements from the list? + Είστε σίγουρος οτι θέλετε να διαγράψετε αυτά τα στοιχεία από τη λίστα? + + + + Are you sure you want to delete this element from the list? + Είστε σίγουρος οτι θέλετε να διαγράψετε αυτό το στοιχείο από τη λίστα? + + + + Please choose a new name for this RSS feed + Παρακαλώ επιλέξτε ένα νέο όνομα για αυτή την παροχή RSS + + + + New feed name: + Νέο όνομα παροχής: + + + + Name already in use + Το όνομα ήδη χρησιμοποιείται + + + + This name is already used by another item, please choose another one. + Αυτό το όνομα ήδη χρησιμοποιείται από ένα άλλο αντικείμενο. Παρακαλώ επιλέξτε ένα άλλο. + + + + Date: + Ημερομηνία: + + + + Author: + Δημιουργός: + + + + Unread + Μη διαβασμένο + + + + RssArticle + + No description available + Δεν υπάρχει διαθέσιμη περιγραφή + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Αυτόματη λήψη του torrent %1 από την παροχή RSS %2... + + + + RssItem + + No description available + Δεν υπάρχει διαθέσιμη περιγραφή + + + + RssSettings + + RSS Reader Settings + Ρυθμίσεις ανάγνωσης RSS + + + RSS feeds refresh interval: + Xρονικό διάστημα ανανέωσης παροχών RSS: + + + minutes + λεπτά + + + Maximum number of articles per feed: + Μέγιστος αριθμός άρθρων ανά τροφοδοσία: + + + + RssSettingsDlg + + + RSS Reader Settings + Ρυθμίσεις Αναγνώστη RSS + + + + RSS feeds refresh interval: + Xρονικό διάστημα ανανέωσης παροχών RSS: + + + + minutes + λεπτά + + + + Maximum number of articles per feed: + Μέγιστος αριθμός άρθρων ανά τροφοδοσία: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Αυτόματη λήψη του torrent %1 από την παροχή RSS %2... + + + + ScanFoldersModel + + + Watched Folder + Φάκελος υπό παρακολούθηση + + + + Download here + Κατέβασμα εδώ + + + + SearchCategories + + + All categories + Όλες οι κατηγορίες + + + + Movies + Ταινίες + + + + TV shows + Τηλεοπτικές σειρές + + + + Music + Μουσική + + + + Games + Παιχνίδια + + + + Anime + Anime + + + + Software + Λογισμικό + + + + Pictures + Εικόνες + + + + Books + Βιβλία + + + + SearchEngine + + + Empty search pattern + Κενό πρότυπο εύρεσης + + + + Please type a search pattern first + Παρακαλώ εισάγετε ένα σχέδιο εύρεσης πρώτα + + + + + Results + Αποτελέσματα + + + + Searching... + Αναζήτηση... + + + + Cut + Αποκοπή + + + + Copy + Αντιγραφή + + + + Paste + Επικόλληση + + + + Clear field + Εκκαθάριση πεδίου + + + + Clear completion history + Εκκαθάριση ιστορικού φόρμας + + + + Confirmation + Επιβεβαίωση + + + + Are you sure you want to clear the history? + Είστε σίγουρος οτι θέλετε να καθαρίσετε το ιστορικό? + + + + + + Search + Αναζήτηση + + + + Missing Python Interpreter + Έλλειψη διερμηνέα Python + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Απαιτείται το Python 2.x. για την μηχανή αναζήτησης,αλλά δεν φαίνεται να είναι εγκατεστημένο. +Θέλετε να το εγκαταστήσετε τώρα? + + + + Search Engine + Μηχανή Αναζήτησης + + + + + Search has finished + Η αναζήτηση τελείωσε + + + + An error occured during search... + Σφάλμα κατά την εύρεση... + + + + + Search aborted + Αναζήτηση διεκόπη + + + + Download error + Σφάλμα κατεβάσματος + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Τα αρχεία εγκατάστασης του Python δεν ήταν δυνατό να κατεβαστούν, αιτία: %1 +Παρακαλώ εγκαταστήστε το χειροκίνητα. + + + + Search returned no results + Η αναζήτηση δεν έφερε αποτελέσματα + + + + Results + i.e: Search results + Αποτελέσματα + + + + + Unknown + Άγνωστο + + + + SearchTab + + + Name + i.e: file name + Όνομα + + + + Size + i.e: file size + Μέγεθος + + + + Seeders + i.e: Number of full sources + Διαμοιραστές + + + + Leechers + i.e: Number of partial sources + Συνδέσεις + + + + Search engine + Μηχανή αναζήτησης + + + + ShutdownConfirmDlg + + + Shutdown confirmation + Επιβεβαίωση απενεργοποίησης + + + + SpeedLimitDialog + + + KiB/s + KiB/s + + + + StatusBar + + + + Connection status: + Κατάσταση σύνδεσης: + + + + + No direct connections. This may indicate network configuration problems. + Χωρίς απευθείας συνδέσεις. Αυτό μπορεί να οφείλεται σε προβλήματα ρυθμίσεων δικτύου. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + Λήψ: %1 B/s - Μετ: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + Απ: %1 B/s - Μετ: %2 + + + + + DHT: %1 nodes + DHT: %1 κόμβοι + + + + qBittorrent needs to be restarted + Το qBittorrent απαιτεί επανεκκίνηση + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + Το qBittorrent μόλις ανανεώθηκε και απαιτεί επανεκκίνηση για να λάβουν χώρα οι αλλαγές. + + + + + Connection Status: + Κατάσταση Σύνδεσης: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Αποσυνδεδεμένο. Αυτό συνήθως σημαίνει οτι το qBittorrent απέτυχε να χρησιμοποιήσει την επιλεγμένη θύρα για εισερχόμενες συνδέσεις. + + + + Online + Συνδεδεμένο + + + + + %1/s + Per second + %1 /s + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Λήψ: %1 B/s - Μετ: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Απ: %1 B/s - Μετ: %2 + + + + Click to switch to alternative speed limits + Κλικ για εναλλαγή προς τα εναλλακτικά όρια ταχύτητας + + + + Click to switch to regular speed limits + Κλικ για εναλλαγή προς τα κανονικά όρια ταχύτητας + + + Click to disable alternative speed limits + Κλικ για απενεργοποίηση εναλλακτικών ορίων ταχύτητας + + + Click to enable alternative speed limits + Κλικ για ενεργοποίηση εναλλακτικών ορίων ταχύτητας + + + + Global Download Speed Limit + Συνολικό Όριο Ταχύτητας Λήψης + + + + Global Upload Speed Limit + Συνολικό Όριο Ταχύτητας Αποστολής + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Επιλέξτε ένα φάκελο για να προστεθεί το τόρεντ + + + + Select a file to add to the torrent + Επιλέξτε ένα αρχείο να προστεθεί στο τόρεντ + + + Please type an announce URL + Παρακαλώ πληκτρολογήστε ένα URL ανακοίνωσης + + + Announce URL: + Tracker URL + URL ιχνηλάτη (ανακοίνωσης): + + + Please type a web seed url + Παρακαλώ πληκτρολογήστε ένα url δικτυακού διαμοιρασμού + + + Web seed URL: + URL δικτυακού διαμοιρασμού: + + + + No input path set + Δεν έχει καθοριστεί διαδρομή εισόδου + + + + Please type an input path first + Παρακαλώ πληκτρολογήστε μία διαδρομή εισόδου πρώτα + + + + Select destination torrent file + Επιλέξτε προορισμό αρχείου τόρεντ + + + + Torrent Files + Αρχεία τόρεντ + + + + + + Torrent creation + Δημιουργία τόρεντ + + + + Torrent creation was unsuccessful, reason: %1 + Η δημιουργία τόρεντ ήταν ανεπιτυχής. αιτία: %1 + + + + Created torrent file is invalid. It won't be added to download list. + Το αρχείο τόρεντ που δημιουργήσατε δεν είναι έγκυρο. Δε θα προστεθεί στη λίστα ληφθέντων. + + + + Torrent was created successfully: + Το τόρεντ δημιουργήθηκε επιτυχώς: + + + + TorrentFilesModel + + + Name + Όνομα + + + + Size + Μέγεθος + + + + Progress + Πρόοδος + + + + Priority + Προτεραιότητα + + + + TorrentImportDlg + + + Torrent Import + Εισαγωγή τόρεντ + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Αυτός ο βοηθός θα σας βοηθήσει να μοιραστείτε με το qBittorrent τα τόρεντ που έχετε ήδη κατεβάσει. + + + + Torrent file to import: + Αρχείο τόρεντ προς εισαγωγή: + + + + + ... + ... + + + + Content location: + Τοποθεσία περιεχομένου: + + + + Skip the data checking stage and start seeding immediately + Προσπέραση του σταδίου ελέγχου δεδομένων και έναρξη διαμοιρασμού απευθείας + + + + Import + Εισαγωγή + + + + Torrent file to import + Αρχείο τόρεντ προς εισαγωγή + + + + Torrent files (*.torrent) + Αρχεία τόρεντ (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 Αρχεία + + + + Please provide the location of %1 + %1 is a file name + Παρακαλώ εισάγετε την τοποθεσία του %1 + + + + Please point to the location of the torrent: %1 + Παρακαλώ εισάγετε την τοποθεσία του τόρεντ: %1 + + + + Invalid torrent file + Άκυρο αρχείο τόρεντ + + + + This is not a valid torrent file. + Αυτό δεν είναι ένα έγκυρο αρχείο τόρεντ. + + + + TorrentModel + + + Name + i.e: torrent name + Όνομα + + + + Size + i.e: torrent size + Μέγεθος + + + + Done + % Done + Έγινε + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Κατάσταση + + + + Seeds + i.e. full sources (often untranslated) + Διαμοιραστές + + + + Peers + i.e. partial sources (often untranslated) + Συνδέσεις + + + + Down Speed + i.e: Download speed + Ταχύτητα Λήψης + + + + Up Speed + i.e: Upload speed + Ταχύτητα Αποστολής + + + + Ratio + Share ratio + Αναλογία + + + + ETA + i.e: Estimated Time of Arrival / Time left + Χρόνος που απομένει + + + + Label + Ετικέτα + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Προστέθηκε στις + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Ολοκληρώθηκε στις + + + + Tracker + Ιχνηλάτης + + + + Down Limit + i.e: Download limit + Όριο Κατεβάσματος + + + + Up Limit + i.e: Upload limit + Όριο ανεβάσματος + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Μέγεθος που κατέβηκε + + + + Amount left + Amount of data left to download (e.g. in MB) + Μέγεθος που απομένει + + + + Time Active + Time (duration) the torrent is active (not paused) + Χρόνος εν ενεργεία + + + + TrackerList + + + URL + URL + + + + Status + Κατάσταση + + + + Peers + Συνδέσεις + + + + Message + Μήνυμα + + + + [DHT] + [DHT] + + + + [PeX] + [PeX] + + + + [LSD] + [LSD] + + + + + + + + Working + Σε λειτουργία + + + + + + Disabled + Απενεργοποιημένο + + + + This torrent is private + Αυτό το torrent είναι προσωπικό + + + + Updating... + Ανανέωση... + + + + + Not working + Δεν λειτουργεί + + + + + Not contacted yet + Δεν επικοινώνησε ακόμα + + + + Add a new tracker... + Προσθήκη νέου ιχνηλάτη... + + + + Remove tracker + Αφαίρεση ιχνηλάτη + + + + Force reannounce + Υποχρεωτική ανακοίνωση ξανά + + + + TrackersAdditionDlg + + + Trackers addition dialog + Παράθυρο προσθήκης ιχνηλατών + + + + List of trackers to add (one per line): + Λίστα ιχνηλατών προς προσθήκη (ένα ανά σειρά): + + + + µTorrent compatible list URL: + Λίστα συμβατών URL με το μtorrent: + + + + I/O Error + Σφάλμα I/O + + + + Error while trying to open the downloaded file. + Σφάλμα κατά την προσπάθεια ανοίγματος του κατεβασμένου αρχείου. + + + + No change + Καμία αλλαγή + + + + No additional trackers were found. + Κανένας πρόσθετος ιχνηλάτης δε βρέθηκε. + + + + Download error + Σφάλμα κατεβάσματος + + + + The trackers list could not be downloaded, reason: %1 + Η λίστα ιχνηλατών δεν ήταν δυνατό να κατέβει, αιτία: %1 + + + + TransferListDelegate + + + Downloading + Λαμβάνει + + + + Paused + Παύση + + + + Queued + i.e. torrent is queued + Σε σειρά + + + + Seeding + Torrent is complete and in upload-only mode + Διαμοιράζει + + + + Stalled + Torrent is waiting for download to begin + Αποτυχία λειτουργίας + + + + Checking + Torrent local data is being checked + Έλεγχος + + + + /s + /second (.i.e per second) + /s + + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Διαμοιράστηκε για %1 + + + + TransferListFiltersWidget + + + + All + Όλα + + + + + Downloading + Λαμβάνει + + + + + Completed + Τελείωσαν + + + + + Paused + Σε Παύση + + + + + Active + Ενεργά + + + + + Inactive + Ανενεργά + + + + + All labels + Όλες οι ετικέτες + + + + + Unlabeled + Χωρίς ετικέτα + + + + Remove label + Αφαίρεση ετικέτας + + + + Add label... + Προσθήκη ετικέτας... + + + + Resume torrents + Συνέχιση των τόρεντ + + + + Pause torrents + Παύση των τόρεντ + + + + Delete torrents + Διαγραφή των τόρεντ + + + + New Label + Νέα Ετικέτα + + + + Label: + Ετικέτα: + + + + Invalid label name + Άκυρο όνομα ετικέτας + + + + Please don't use any special characters in the label name. + Παρακαλώ μην χρισιμοποιείτε ειδικούς χαρακτήρες στο όνομα της ετικέτας. + + + + TransferListWidget + + Down Speed + i.e: Download speed + Ταχύτητα Λήψης + + + Up Speed + i.e: Upload speed + Ταχύτητα Αποστολής + + + ETA + i.e: Estimated Time of Arrival / Time left + Χρόνος που απομένει + + + + Column visibility + Εμφανισημότητα Κολώνας + + + Name + i.e: torrent name + Όνομα + + + Size + i.e: torrent size + Μέγεθος + + + Done + % Done + Έγινε + + + Status + Torrent status (e.g. downloading, seeding, paused) + Κατάσταση + + + Seeds + i.e. full sources (often untranslated) + Διαμοιραστές + + + Peers + i.e. partial sources (often untranslated) + Συνδέσεις + + + Ratio + Share ratio + Αναλογία + + + + Label + Ετικέτα + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Προστέθηκε στις + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Ολοκληρώθηκε στις + + + Down Limit + i.e: Download limit + Όριο Κατεβάσματος + + + Up Limit + i.e: Upload limit + Όριο ανεβάσματος + + + + Choose save path + Επιλέξτε διαδρομή αποθήκευσης + + + Save path creation error + Σφάλμα δημιουργίας διαδρομής αποθήκευσης + + + Could not create the save path + Αδύνατη η δημιουργία διαδρομής αποθήκευσης + + + + Torrent Download Speed Limiting + Περιορισμός Ταχύτητας Λήψης torrent + + + + Torrent Upload Speed Limiting + Περιορισμός Ταχύτητας Αποστολής torrent + + + + New Label + Νέα Ετικέτα + + + + Label: + Ετικέτα: + + + + Invalid label name + Άκυρο όνομα ετικέτας + + + + Please don't use any special characters in the label name. + Παρακαλώ μην χρισιμοποιείτε ειδικούς χαρακτήρες στο όνομα της ετικέτας. + + + + Rename + Μετονομασία + + + + New name: + Νέο όνομα: + + + + Resume + Resume/start the torrent + Συνέχιση + + + + Pause + Pause the torrent + Παύση + + + + Delete + Delete the torrent + Διαγραφή + + + + Preview file... + Προεπισκόπηση αρχείου... + + + + Limit share ratio... + Όριο ποσοστού διαμοιρασμού... + + + + Limit upload rate... + Όριο ταχύτητας αποστολής... + + + + Limit download rate... + Όριο ταχύτητας λήψης... + + + + Priority + Προτεραιότητα + + + + Open destination folder + Άνοιγμα φακέλου προορισμού + + + + Move up + i.e. move up in the queue + Μετακίνηση επάνω + + + + Move down + i.e. Move down in the queue + Μετακίνηση κάτω + + + + Move to top + i.e. Move to top of the queue + Μετακίνηση στην κορυφή + + + + Move to bottom + i.e. Move to bottom of the queue + Μετακίνηση στο τέλος + + + + Set location... + Ρύθμιση τοποθεσίας... + + + + Force recheck + Αναγκαστικός επανέλεγχος + + + + Copy magnet link + Αντιγραφή magnet link + + + + Super seeding mode + Λειτουργία ενισχυμένου διαμοιράσματος + + + + Rename... + Μετονομασία... + + + + Download in sequential order + Κατέβασμα σε συνεχή σειρά + + + + Download first and last piece first + Κατέβασμα πρώτου και τελευταίου κομματιού στην αρχή + + + + New... + New label... + Νέα... + + + + Reset + Reset label + Επαναφορά + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Περιορισμός ποσοστού ανεβάσματος/κατεβάσματος τόρεντ + + + + Use global ratio limit + Χρήση συνολικού ορίου διαμοιράσματος + + + + + + buttonGroup + ? + buttonGroup + + + + Set no ratio limit + Μη ρύθμιση ορίου ποσοστού διαμοιρασμού + + + + Set ratio limit to + Ρύθμιση ορίου ποσοστού διαμοιρασμού σε + + + + UsageDisplay + + + Usage: + Χρήση: + + + + displays program version + προβάλλει την έκδοση του προγράμματος + + + + disable splash screen + απενεργοποίηση του splash screen + + + + displays this help message + εμφάνιση μηνύματος βοήθειας + + + + changes the webui port (current: %1) + αλλάζει την θύρα του webui (τρέχουσα: %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [αρχεία ή url]: κατεβάζει τα περασμένα από το χρήστη τόρεντ (προαιρετικό) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Θα ήθελα να ευχαριστήσω τους παρακάτω που εθελοντικά μετέφρασαν το qBittorrent: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Παρακαλώ επικοινωνήστε μαζί μου αν θα θέλατε να μεταφράσετε το qBittorrent στη δική σας γλώσσα. + + + + addPeerDialog + + + Peer addition + Προσθήκη σύνδεσης + + + + IP + IP + + + + Port + Θύρα + + + + addTorrentDialog + + + Torrent addition dialog + Διάλογος προσθήκης torrent + + + + Save path: + Αποθήκευση σε: + + + + ... + ... + + + + Torrent size: + Μέγεθος torrent: + + + + + Unknown + Άγνωστο + + + + Free disk space: + Ελεύθερος χώρος στο δίσκο: + + + + Label: + Ετικέτα: + + + + Torrent content: + Περιεχόμενο torrent: + + + + Select All + Επιλογή Όλων + + + + Select None + Αποεπιλογή Όλων + + + + Download in sequential order (slower but good for previewing) + Λήψη σε συνεχόμενη σειρά (πιο αργό αλλά καλό για preview) + + + + Skip file checking and start seeding immediately + Παράλειψη ελέγχου αρχείου και απευθείας διαμοιρασμός + + + + + Do not download + Να μην γίνει κατέβασμα + + + + Add to download list in paused state + Προσθήκη στη λίστα ληφθέντων σε κατάσταση παύσης + + + + Add + Προσθήκη + + + + Cancel + Ακύρωση + + + + Normal + Κανονικό + + + + High + Υψηλό + + + + Maximum + Μέγιστο + + + + authentication + + + + Tracker authentication + Πιστοποίηση ιχνηλάτη + + + + Tracker: + Ιχνηλάτης: + + + + Login + Είσοδος + + + + Username: + Όνομα χρήστη: + + + + Password: + Κωδικός: + + + + Log in + Είσοδος + + + + Cancel + Ακύρωση + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Επιβεβαίωση διαγραφής - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Είστε σίγουρος οτι θέλετε να διαγράψετε τα συγκεκριμένα torrent από την λίστα μεταφορών? + + + + Remember choice + Απομνημόνευση επιλογής + + + + Also delete the files on the hard disk + Να διαγραφούν επίσης τα αρχεία στο σκληρό δίσκο + + + + createTorrentDialog + + + Cancel + Ακύρωση + + + + Torrent Creation Tool + Εργαλείο Δημιουργίας torrent + + + + Torrent file creation + Δημιουργία αρχείου torrent + + + Announce urls (trackers): + Url ανακοίνωσης (ιχνηλάτες): + + + Comment (optional): + Σχόλιο (προαιρετικό): + + + Web seeds urls (optional): + Url δικτυακού διαμοιρασμού (προαιρετικά): + + + + File or folder to add to the torrent: + Αρχείο ή φάκελος να προστεθεί στο torrent: + + + + Add file + Προσθήκη αρχείου + + + + Add folder + Προσθήκη φακέλου + + + + Tracker URLs: + URLs Ιχνηλατών: + + + + Web seeds urls: + Urls διαμοιραστών δικτύου: + + + + Comment: + Σχόλιο: + + + + Piece size: + Μέγεθος κομματιού: + + + + 32 KiB + 32 KiB + + + + 64 KiB + 64 KiB + + + + 128 KiB + 128 KiB + + + + 256 KiB + 256 KiB + + + + 512 KiB + 512 KiB + + + + 1 MiB + 1 MiB + + + + 2 MiB + 2 MiB + + + + 4 MiB + 4 MiB + + + + Auto + Αυτόματα + + + + Private (won't be distributed on DHT network if enabled) + Ιδιωτικό (αν ενεργοποιηθεί, δε θα διανεμηθεί σε δίκτυο DHT) + + + + Start seeding after creation + Εκκίνηση διαμοιρασμού μετά τη δημιουργία + + + + Create and save... + Δημιουργία και αποθήκευση... + + + + Progress: + Πρόοδος: + + + + createtorrent + + Select destination torrent file + Επιλέξτε προορισμό αρχείου torrent + + + Torrent Files + Αρχεία torrent + + + No input path set + Δεν έχει καθοριστεί διαδρομή εισόδου + + + Please type an input path first + Παρακαλώ πληκτρολογήστε μία διαδρομή εισόδου πρώτα + + + Torrent creation + Δημιουργία torrent + + + Torrent was created successfully: + Το torrent δημιουργήθηκε επιτυχώς: + + + Select a folder to add to the torrent + Επιλέξτε ένα φάκελο για να προστεθεί το torrent + + + Please type an announce URL + Παρακαλώ πληκτρολογήστε ένα URL ανακοίνωσης + + + Torrent creation was unsuccessful, reason: %1 + Η δημιουργία torrent ήταν ανεπιτυχής. αιτία: %1 + + + Announce URL: + Tracker URL + URL ιχνηλάτη (ανακοίνωσης): + + + Please type a web seed url + Παρακαλώ πληκτρολογήστε ένα url δικτυακού διαμοιρασμού + + + Web seed URL: + URL δικτυακού διαμοιρασμού: + + + Select a file to add to the torrent + Επιλέξτε ένα αρχείο να προστεθεί στο torrent + + + Created torrent file is invalid. It won't be added to download list. + Το αρχείο torrent που δημιουργήσατε δεν είναι έγκυρο. Δε θα προστεθεί στη λίστα ληφθέντων. + + + + downloadFromURL + + Download Torrents from URLs + Λήψη torrent από URL + + + Only one URL per line + Μόνο ένα URL ανα γραμμή + + + + Add torrent links + Προσθήκη συνδέσμων τόρεντ + + + + Both HTTP and Magnet links are supported + Τόσο οι HTTP όσο και οι Magnet σύνδεσμοι υποστηρίζονται + + + + Download + Λήψη + + + + Cancel + Άκυρο + + + + Download from urls + Λήψη από URL + + + + No URL entered + Δεν έχετε εισάγει URL + + + + Please type at least one URL. + Παρακαλώ εισάγετε τουλάχιστο ένα URL. + + + + downloadThread + + I/O Error + Σφάλμα I/O + + + The remote host name was not found (invalid hostname) + Ο απομακρυσμένος διακομιστής δεν βρέθηκε (άκυρο όνομα διακομιστή) + + + The operation was canceled + Η διαδικασία ακυρώθηκε + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Ο απομακρυσμένος εξυπηρετητής διέκοψε την σύνδεση πρόωρα, προτού η πλήρης απάντηση γίνει ληπτή και επεξεργασθεί + + + The connection to the remote server timed out + Η σύνδεση προς τον απομακρυσμένο εξυπηρετητή έληξε + + + SSL/TLS handshake failed + SSL/TLS σύνδεση απέτυχε + + + The remote server refused the connection + Ο απομακρυσμένος εξυπηρετητής αρνήθηκε τη σύνδεση + + + The connection to the proxy server was refused + Η σύνδεση προς τον διακομιστή proxy δεν έγινε δεκτή + + + The proxy server closed the connection prematurely + Ο διακομιστής proxy έκλεισε την σύνδεση πρόωρα + + + The proxy host name was not found + Το όνομα του διακομιστή proxy δεν βρέθηκε + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Η σύνδεση προς τον εξυπηρετητή proxy έληξε ή ο proxy δεν αποκρίθηκε εγκαίρως στο σταλθέν αίτημα + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Ο proxy απαιτεί πιστοποίηση για να δεχθεί την αίτηση αλλά δεν δέχθηκε καμία πιστοποίηση + + + The access to the remote content was denied (401) + Η πρόσβαση στο απομακρυσμένο περιεχόμενο δεν έγινε δεκτή (401) + + + The operation requested on the remote content is not permitted + Η λειτουργία που ζητήσατε στο αποκαρυσμένο περιεχόμενο δεν επιτρέπεται + + + The remote content was not found at the server (404) + Το απομακρυσμένο περιεχόμενο δεν βρέθηκε στον διακομιστή (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Ο απομακρυσμένος διακομιστής απαιτεί πιστοποίηση για να δεχθεί την αίτηση αλλά δεν δέχθηκε καμία πιστοποίηση + + + The Network Access API cannot honor the request because the protocol is not known + Left as is for the moment. + Το API Δικτύου δεν μπόρεσε να εκπληρώσει το αίτημα επειδή το πρωτόκολλο είναι άγνωστο + + + The requested operation is invalid for this protocol + Η ζητηθείσα λειτουργία είναι άκυρη για αυτό το πρωτόκολλο + + + An unknown network-related error was detected + Ένα άγνωστο σφάλμα δικτύου βρέθηκε + + + An unknown proxy-related error was detected + Ένα άγνωστο σφάλμα του proxy βρέθηκε + + + An unknown error related to the remote content was detected + Βρέθηκε ένα άγνωστο σφάλμα στο απομακρυσμένο περιεχόμενο + + + A breakdown in protocol was detected + Εντοπίστηκε διακοπή στο πρωτόκολλο + + + Unknown error + Άγνωστο σφάλμα + + + + engineSelect + + + Search plugins + Plugin αναζήτησης + + + + Installed search engines: + Εγκατεστημένες μηχανές αναζήτησης: + + + + Name + Όνομα + + + + Url + Url + + + + + Enabled + Ενεργοποιημένο + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Μπορείτε να βρείτε νέες μηχανές αναζήτησης εδώ: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Εγκατάσταση ενός καινούριου + + + + Check for updates + Έλεγχος για αναβαθμίσεις + + + + Close + Κλείσιμο + + + Enable + Ενεργοποίηση + + + Disable + Απενεργοποίηση + + + + Uninstall + Απεγκατάσταση + + + + engineSelectDlg + + + Uninstall warning + Προειδοποίηση απεγκατάστασης + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Μερικά plugin δεν μπόρεσαν να απεγκατασταθούν διότι συμπεριλαμβάνονται στο qBittorrent. + Μόνο αυτά που προσθέσατε μόνος σας μπορούν να απεγκατασταθούν. +Ωστόσο, αυτά τα plugin απενεργοποιήθηκαν. + + + + Uninstall success + Επιτυχής απεγκατάσταση + + + + Select search plugins + Επιλέξτε plugin αναζήτησης + + + + qBittorrent search plugins + plugin αναζήτησης του qBittorrent + + + + + + + + Search plugin install + Εγκατάσταση plugin αναζήτησης + + + + + + Yes + Ναι + + + + + + + No + Όχι + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Μια πιο πρόσφατη έκδοση plugin αναζήτησης %1 έχει ήδη εγκατασταθεί. + + + + + + + Search plugin update + Αναβάθμιση plugin αναζήτησης + + + + + Sorry, update server is temporarily unavailable. + Λυπούμαστε, ο εξυπηρετητής αναβάθμισης δεν είναι προσωρινά διαθέσιμος. + + + + All your plugins are already up to date. + Όλα τα plugin σας είναι ήδη αναβαθμισμένα. + + + + All selected plugins were uninstalled successfully + Όλα τα επιλεγμένα plugin απεγκαταστάθηκαν επιτυχώς + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + Το plugin αναζήτησης %1 δεν ήταν δυνατό να αναβαθμιστεί, παραμένει η παλιά έκδοση. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Το plugin αναζήτησης %1 δεν ήταν δυνατό να εγκατασταθεί. + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + Το plugin αναζήτησης %1 αναβαθμίστηκε επιτυχώς. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Το plugin αναζήτησης %1 εγκαταστάθηκε επιτυχώς. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Λυπούμαστε, η εγκατάσταση του plugin αναζήτησης %1 απέτυχε. + + + + New search engine plugin URL + Νέο URL plugin αναζήτησης + + + + URL: + URL: + + + + misc + + + qBittorrent will shutdown the computer now because all downloads are complete. + Το qBittorrent θα απενεργοποιήσει τον υπολογιστή τώρα καθώς έχουν ολοκληρωθεί όλα τα κατεβάσματα. + + + + B + bytes + B + + + + KiB + kibibytes (1024 bytes) + KiB/s + + + + MiB + mebibytes (1024 kibibytes) + MiB + + + + GiB + gibibytes (1024 mibibytes) + GiB + + + + TiB + tebibytes (1024 gibibytes) + TiB + + + + %1h %2m + e.g: 3hours 5minutes + %1ώ %2λ + + + + %1d %2h + e.g: 2days 10hours + %1μ %2ώ + + + + + + + + + Unknown + Άγνωστο + + + + Unknown + Unknown (size) + Άγνωστο + + + + < 1m + < 1 minute + < 1λ + + + + %1m + e.g: 10minutes + %1λ + + + + options_imp + + + + + + Choose a save directory + Επιλέξτε φάκελο αποθήκευσης + + + + Add directory to scan + Προσθήκη κατηγορίας στη σάρωση + + + + Folder is already being watched. + Αυτός ο φάκελος ήδη παρακολουθείται. + + + + Folder does not exist. + Αυτός ο φάκελος δεν υπάρχει. + + + + Folder is not readable. + Αυτός ο φάκελος δεν είναι δυνατό να διαβαστεί. + + + + Failure + Σφάλμα + + + + Failed to add Scan Folder '%1': %2 + Δεν ήταν δυνατό να προστεθεί ο Φάκελος για Σάρωση '%1': %2 + + + + + Choose export directory + Επιλέξτε φάκελο εξαγωγής + + + + + Choose an ip filter file + Επιλέξτε ένα αρχείο φίλτρου ip + + + + + Filters + Φίλτρα + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + Σφάλμα ανάλυσης + + + + Failed to parse the provided IP filter + Αποτυχία ανάγνωσης του δοθέντος φίλτρου IP + + + + Successfully refreshed + Επιτυχής ανανέωση + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + Succesfully refreshed + Επιτυχής ανανέωση + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Η ανάγνωση του δοθέντος IP φίλτρου ήταν επιτυχής: %1 κανόνες εφαρμόστηκαν. + + + + pluginSourceDlg + + + Plugin source + Πηγή plugin + + + + Search plugin source: + Πηγή plugin αναζήτησης: + + + + Local file + Τοπικό αρχείο + + + + Web link + Web σύνδεσμος + + + + preview + + + Preview selection + Προεπισκόπηση επιλογής + + + + File preview + Προεπισκόπηση αρχείου + + + + The following files support previewing, <br>please select one of them: + Τα παρακάτω αρχεία υποστηρίζουν προεπισκόπηση, <br>παρακαλώ επιλέξτε ένα από αυτά: + + + + Preview + Προεπισκόπηση + + + + Cancel + Άκυρο + + + + previewSelect + + Preview impossible + Αδύνατη η προεπισκόπηση + + + Sorry, we can't preview this file + Λυπούμαστε, δεν μπορεί να προεσκοπηθεί αυτό το αρχείο + + + Name + Όνομα + + + Size + Μέγεθος + + + Progress + Πρόοδος + + + + search_engine + + + + Search + Αναζήτηση + + + + Status: + Κατάσταση: + + + + Stopped + Σταμάτησε + + + + Download + Λήψη + + + + Go to description page + Προς τη σελίδα περιγραφής + + + + Search engines... + Μηχανές αναζήτησης... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + Αδύνατο να αποκωδικοποιηθεί το αρχείο torrent: + + + + + + Choose save path + Επιλέξτε διαδρομή αποθήκευσης + + + + Unable to decode magnet link: + Αδύνατο να αποκωδικοποιηθεί το magnet link: + + + + Magnet Link + Magnet Link + + + + Rename... + Μετονομασία... + + + + Rename the file + Μετονομασία αρχείου + + + + New name: + Νέο όνομα: + + + + + The file could not be renamed + Αυτό το αρχείο δεν είναι δυνατό να μετονομαστεί + + + + This file name contains forbidden characters, please choose a different one. + Αυτό το όνομα αρχείου περιέχει απαγορευμένους χαρακτήρες, παρακαλώ επιλέξτε ένα διαφορετικό. + + + + + This name is already in use in this folder. Please use a different name. + Αυτό το όνομα ήδη χρησιμοποιείται σ'αυτό το φάκελο. Παρακαλώ επιλέξτε ένα άλλο. + + + + The folder could not be renamed + Αυτός ο φάκελος δεν είναι δυνατό να μετονομαστεί + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 απομένουν μετά από το λήψη του torrent) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 επιπλέον απαιτούνται για τη λήψη) + + + + Empty save path + Κενή διαδρομή αποθήκευσης + + + + Please enter a save path + Παρακαλώ εισάγετε μία διαδρομή αποθήκευσης + + + + Save path creation error + Σφάλμα δημιουργίας διαδρομής αποθήκευσης + + + + Could not create the save path + Δεν μπόρεσε να δημιουργηθεί η διαδρομή αποθήκευσης + + + + Invalid label name + Άκυρο όνομα ετικέτας + + + + Please don't use any special characters in the label name. + Παρακαλώ μην χρισιμοποιείτε ειδικούς χαρακτήρες στο όνομα της ετικέτας. + + + + Seeding mode error + Σφάλμα λειτουργίας μοιράσματος + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Επιλέξατε προσπέλαση του ελέγχου αρχείων. Ωστόσο, τα τοπικά αρχεία δεν φαίνεται να υπάρχουν στον τρέχον φάκελο προορισμού. Παρακαλούμε απενεργοποιήστε αυτή τη λειτουργία ή ανανεώστε την διαδρομή αποθήκευσης. + + + + Invalid file selection + Άκυρη επιλογή αρχείου + + + + You must select at least one file in the torrent + Πρέπει να επιλέξετε τουλάχιστο ένα αρχείο του torrent + + + + Priority + Προτεραιότητα + + + diff --git a/src/lang/qbittorrent_en.qm b/src/lang/qbittorrent_en.qm new file mode 100644 index 000000000..be651eede --- /dev/null +++ b/src/lang/qbittorrent_en.qm @@ -0,0 +1 @@ + + + + + AboutDlg + + + About qBittorrent + + + + + About + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + + Author + + + + + Name: + + + + + Country: + + + + + E-mail: + + + + + Christophe Dumez + + + + + France + + + + + Translation + + + + + License + + + + + <h3><b>qBittorrent</b></h3> + + + + + chris@qbittorrent.org + + + + + Thanks to + + + + + AdvancedSettings + + + Disk write cache size + + + + + MiB + + + + + Outgoing ports (Min) [0: Disabled] + + + + + Outgoing ports (Max) [0: Disabled] + + + + + Recheck torrents on completion + + + + + Transfer list refresh interval + + + + + ms + milliseconds + + + + + Setting + + + + + Value + Value set for this setting + + + + + Resolve peer countries (GeoIP) + + + + + Resolve peer host names + + + + + Maximum number of half-open connections [0: Disabled] + + + + + Strict super seeding + + + + + Network Interface (requires restart) + + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + + + + + IP Address to report to trackers (requires restart) + + + + + Display program on-screen notifications + + + + + Enable embedded tracker + + + + + Embedded tracker port + + + + + Check for software updates + + + + + Use system icon theme + + + + + Confirm torrent deletion + + + + + Ignore transfer limits on local network + + + + + AutomatedRssDownloader + + + Automated RSS Downloader + + + + + Enable the automated RSS downloader + + + + + Download rules + + + + + Rule definition + + + + + Must contain: + + + + + Must not contain: + + + + + Use regular expressions + + + + + Import... + + + + + Export... + + + + + ... + + + + + Assign label: + + + + + Save to a different directory + + + + + Save to: + + + + + Apply rule to feeds: + + + + + Matching RSS articles + + + + + New rule name + + + + + Please type the name of the new download rule. + + + + + + Rule name conflict + + + + + + A rule with this name already exists, please choose another name. + + + + + Are you sure you want to remove the download rule named %1? + + + + + Are you sure you want to remove the selected download rules? + + + + + Rule deletion confirmation + + + + + Destination directory + + + + + Invalid action + + + + + The list is empty, there is nothing to export. + + + + + Where would you like to save the list? + + + + + Rules list (*.rssrules) + + + + + I/O Error + + + + + Failed to create the destination file + + + + + Please point to the RSS download rules file + + + + + Rules list (*.rssrules *.filters) + + + + + Import Error + + + + + Failed to import the selected rules file + + + + + Add new rule... + + + + + Delete rule + + + + + Rename rule... + + + + + Delete selected rules + + + + + Rule renaming + + + + + Please type the new rule name + + + + + Regex mode: use Perl-like regular expressions + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + + CookiesDlg + + + Cookies management + + + + + Key + As in Key/Value pair + + + + + Value + As in Key/Value pair + + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + + + + + Dynamic DNS error: Invalid username/password. + + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: Your username was blocked due to abuse. + + + + + Dynamic DNS error: supplied domain name is invalid. + + + + + Dynamic DNS error: supplied username is too short. + + + + + Dynamic DNS error: supplied password is too short. + + + + + DownloadThread + + + + I/O Error + + + + + The remote host name was not found (invalid hostname) + + + + + The operation was canceled + + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + + + + + The connection to the remote server timed out + + + + + SSL/TLS handshake failed + + + + + The remote server refused the connection + + + + + The connection to the proxy server was refused + + + + + The proxy server closed the connection prematurely + + + + + The proxy host name was not found + + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + + + + + The access to the remote content was denied (401) + + + + + The operation requested on the remote content is not permitted + + + + + The remote content was not found at the server (404) + + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + + + + + The Network Access API cannot honor the request because the protocol is not known + + + + + The requested operation is invalid for this protocol + + + + + An unknown network-related error was detected + + + + + An unknown proxy-related error was detected + + + + + An unknown error related to the remote content was detected + + + + + A breakdown in protocol was detected + + + + + Unknown error + + + + + EventManager + + + + Working + + + + + Updating... + + + + + + Not working + + + + + + Not contacted yet + + + + + + this session + + + + + + /s + /second (i.e. per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + + + + + %1 max + e.g. 10 max + + + + + + %1/s + e.g. 120 KiB/s + + + + + ExecutionLog + + + General + + + + + Blocked IPs + + + + + FeedListWidget + + + RSS feeds + + + + + Unread + + + + + HeadlessLoader + + + Information + + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + + + + + The Web UI administrator user name is: %1 + + + + + The Web UI administrator password is still the default one: %1 + + + + + This is a security risk, please consider changing your password from program preferences. + + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + + + + + HttpServer + + + File + + + + + Edit + + + + + Help + + + + + Download Torrents from their URL or Magnet link + + + + + Only one link per line + + + + + Download local torrent + + + + + Torrent files were correctly added to download list. + + + + + Point to torrent file + + + + + Download + + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + + + + + Download rate limit must be greater than 0 or disabled. + + + + + Upload rate limit must be greater than 0 or disabled. + + + + + Maximum number of connections limit must be greater than 0 or disabled. + + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + + + + + Unable to save program preferences, qBittorrent is probably unreachable. + + + + + Language + + + + + Downloaded + Is the file downloaded or not? + + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + + + + + The Web UI username must be at least 3 characters long. + + + + + The Web UI password must be at least 3 characters long. + + + + + Save + + + + + qBittorrent client is not reachable + + + + + HTTP Server + + + + + The following parameters are supported: + + + + + Torrent path + + + + + Torrent name + + + + + LegalNotice + + + Legal Notice + + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + + + + + Press %1 key to accept and continue... + + + + + Legal notice + + + + + Cancel + + + + + I Agree + + + + + LineEdit + + + Clear the text + + + + + MainWindow + + + &Edit + + + + + &Tools + + + + + &File + + + + + &Help + + + + + &View + + + + + &Options... + + + + + &Resume + + + + + R&esume All + + + + + Torrent &creator + + + + + + Alternative speed limits + + + + + Top &tool bar + + + + + Display top tool bar + + + + + &Speed in title bar + + + + + Show transfer speed in title bar + + + + + &About + + + + + &Add torrent file... + + + + + + Exit + + + + + &Pause + + + + + &Delete + + + + + P&ause All + + + + + Visit &Website + + + + + Auto-Shutdown on downloads completion + + + + + Add &link to torrent... + + + + + Report a &bug + + + + + Set upload limit... + + + + + Set download limit... + + + + + &Documentation + + + + + Set global download limit... + + + + + Set global upload limit... + + + + + &RSS reader + + + + + Search &engine + + + + + Exit qBittorrent + + + + + Suspend system + + + + + Shutdown system + + + + + Disabled + + + + + + Lock qBittorrent + + + + + Ctrl+L + + + + + Import existing torrent... + + + + + Import torrent... + + + + + Donate money + + + + + If you like qBittorrent, please donate! + + + + + Execution &Log + + + + + + Execution Log + + + + + Decrease priority + + + + + Increase priority + + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + + + + + Set the password... + + + + + Transfers + + + + + Torrent file association + + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + + + + + + + UI lock password + + + + + + + Please type the UI lock password: + + + + + The password should contain at least 3 characters + + + + + Password update + + + + + The UI lock password has been successfully updated + + + + + RSS + + + + + Search + + + + + Transfers (%1) + + + + + Download completion + + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + + + + + I/O Error + i.e: Input/Output Error + + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + + + + + Alt+1 + shortcut to switch to first tab + + + + + Alt+2 + shortcut to switch to third tab + + + + + Ctrl+F + shortcut to switch to search tab + + + + + Alt+3 + shortcut to switch to fourth tab + + + + + Recursive download confirmation + + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + + + + + + Yes + + + + + + No + + + + + Never + + + + + Url download error + + + + + Couldn't download file at url: %1, reason: %2. + + + + + Global Upload Speed Limit + + + + + Global Download Speed Limit + + + + + + Invalid password + + + + + The password is invalid + + + + + Exiting qBittorrent + + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + + + + + Always + + + + + Open Torrent Files + + + + + Torrent Files + + + + + Options were saved successfully. + + + + + qBittorrent + + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + + + + + A newer version is available + + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + + + + + Impossible to update qBittorrent + + + + + qBittorrent failed to update, reason: %1 + + + + + PeerAdditionDlg + + + Invalid IP + + + + + The IP you provided is invalid. + + + + + PeerListDelegate + + + /s + /second (i.e. per second) + + + + + PeerListWidget + + + IP + + + + + Connection + + + + + Client + i.e.: Client application + + + + + Progress + i.e: % downloaded + + + + + Down Speed + i.e: Download speed + + + + + Up Speed + i.e: Upload speed + + + + + Downloaded + i.e: total data downloaded + + + + + Uploaded + i.e: total data uploaded + + + + + Add a new peer... + + + + + Copy IP + + + + + Limit download rate... + + + + + Limit upload rate... + + + + + Ban peer permanently + + + + + + Peer addition + + + + + The peer was added to this torrent. + + + + + The peer could not be added to this torrent. + + + + + Are you sure? -- qBittorrent + + + + + Are you sure you want to ban permanently the selected peers? + + + + + &Yes + + + + + &No + + + + + Manually banning peer %1... + + + + + Upload rate limiting + + + + + Download rate limiting + + + + + Preferences + + + Downloads + + + + + Connection + + + + + Speed + + + + + Web UI + + + + + Advanced + + + + + (Requires restart) + + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + + + + + + Start / Stop Torrent + + + + + + No action + + + + + Append .!qB extension to incomplete files + + + + + Copy .torrent files to: + + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + + + + + Connections Limits + + + + + Proxy Server + + + + + Global Rate Limits + + + + + Apply rate limit to uTP connections + + + + + Apply rate limit to transport overhead + + + + + Alternative Global Rate Limits + + + + + Schedule the use of alternative rate limits + + + + + Enable Local Peer Discovery to find more peers + + + + + Encryption mode: + + + + + Prefer encryption + + + + + Require encryption + + + + + Disable encryption + + + + + Maximum active downloads: + + + + + Maximum active uploads: + + + + + Maximum active torrents: + + + + + When adding a torrent + + + + + + Behavior + + + + + Language + + + + + Display torrent content and some options + + + + + Port used for incoming connections: + + + + + Random + + + + + Global maximum number of connections: + + + + + Maximum number of connections per torrent: + + + + + Maximum number of upload slots per torrent: + + + + + + Upload: + + + + + + Download: + + + + + + + + KiB/s + + + + + Remove folder + + + + + to + time1 to time2 + + + + + Every day + + + + + Week days + + + + + Week ends + + + + + DHT port: + + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + + + + + Host: + + + + + SOCKS4 + + + + + Type: + + + + + + Options + + + + + Action on double-click + + + + + Downloading torrents: + + + + + + Open destination folder + + + + + Completed torrents: + + + + + Desktop + + + + + Show splash screen on start up + + + + + Start qBittorrent minimized + + + + + Minimize qBittorrent to notification area + + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + + + + + Tray icon style: + + + + + Normal + + + + + Monochrome (Dark theme) + + + + + Monochrome (Light theme) + + + + + Ask for program exit confirmation + + + + + User Interface Language: + + + + + Transfer List + + + + + Show qBittorrent in notification area + + + + + Power Management + + + + + Inhibit system sleep when torrents are active + + + + + Do not start the download automatically + The torrent will be added to download list in pause state + + + + + Hard Disk + + + + + Save files to location: + + + + + Append the label of the torrent to the save path + + + + + Pre-allocate disk space for all files + + + + + Keep incomplete torrents in: + + + + + Automatically add torrents from: + + + + + Add folder... + + + + + Email notification upon download completion + + + + + Destination email: + + + + + SMTP server: + + + + + This server requires a secure connection (SSL) + + + + + Run an external program on torrent completion + + + + + Listening Port + + + + + Use UPnP / NAT-PMP port forwarding from my router + + + + + Otherwise, the proxy server is only used for tracker connections + + + + + Use proxy for peer connections + + + + + IP Filtering + + + + + Reload the filter + + + + + Enable bandwidth management (uTP) + + + + + from + from (time1 to time2) + + + + + When: + + + + + Privacy + + + + + Enable DHT (decentralized network) to find more peers + + + + + Use a different port for DHT and BitTorrent + + + + + Enable Peer Exchange (PeX) to find more peers + + + + + Look for peers on your local network + + + + + Seed torrents until their ratio reaches + + + + + then + + + + + Pause them + + + + + Remove them + + + + + Use UPnP / NAT-PMP to forward the port from my router + + + + + Use HTTPS instead of HTTP + + + + + Import SSL Certificate + + + + + Import SSL Key + + + + + Certificate: + + + + + Key: + + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + Bypass authentication for localhost + + + + + Update my dynamic domain name + + + + + Service: + + + + + Register + + + + + Domain name: + + + + + (None) + + + + + BitTorrent + + + + + HTTP + + + + + + Port: + + + + + + + Authentication + + + + + + + + Username: + + + + + + + + Password: + + + + + Torrent Queueing + + + + + Share Ratio Limiting + + + + + Enable Web User Interface (Remote control) + + + + + SOCKS5 + + + + + Filter path (.dat, .p2p, .p2b): + + + + + PreviewSelect + + + Name + + + + + Size + + + + + Progress + + + + + + + Preview impossible + + + + + + + Sorry, we can't preview this file + + + + + PropListDelegate + + + Not downloaded + + + + + + Normal + Normal (priority) + + + + + + High + High (priority) + + + + + Mixed + Mixed (priorities + + + + + + Maximum + Maximum (priority) + + + + + PropTabBar + + + General + + + + + Trackers + + + + + Peers + + + + + HTTP Sources + + + + + Content + + + + + PropertiesWidget + + + Save path: + + + + + Torrent hash: + + + + + Share ratio: + + + + + + Downloaded: + + + + + Availability: + + + + + Transfer + + + + + Uploaded: + + + + + Wasted: + + + + + UP limit: + + + + + DL limit: + + + + + Connections: + + + + + Time active: + Time (duration) the torrent is active (not paused) + + + + + Reannounce in: + + + + + Information + + + + + Created on: + + + + + Pieces size: + + + + + Comment: + + + + + Torrent content: + + + + + Select All + + + + + Select None + + + + + Normal + + + + + High + + + + + Maximum + + + + + + Do not download + + + + + + this session + + + + + + /s + /second (i.e. per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + + + + + %1 max + e.g. 10 max + + + + + + I/O Error + + + + + This file does not exist yet. + + + + + This folder does not exist yet. + + + + + Rename... + + + + + Priority + + + + + Rename the file + + + + + New name: + + + + + + The file could not be renamed + + + + + This file name contains forbidden characters, please choose a different one. + + + + + + This name is already in use in this folder. Please use a different name. + + + + + The folder could not be renamed + + + + + New url seed + New HTTP source + + + + + New url seed: + + + + + qBittorrent + + + + + This url seed is already in the list. + + + + + + Choose save path + + + + + QBtSession + + + + %1 reached the maximum ratio you set. + + + + + Removing torrent %1... + + + + + Pausing torrent %1... + + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + + + + + HTTP user agent is %1 + + + + + Reporting IP address %1 to trackers... + + + + + DHT support [ON], port: UDP/%1 + + + + + + DHT support [OFF] + + + + + PeX support [ON] + + + + + PeX support [OFF] + + + + + Restart is required to toggle PeX support + + + + + Local Peer Discovery support [OFF] + + + + + Encryption support [ON] + + + + + Encryption support [FORCED] + + + + + Encryption support [OFF] + + + + + Embedded Tracker [ON] + + + + + Failed to start the embedded tracker! + + + + + Embedded Tracker [OFF] + + + + + The Web UI is listening on port %1 + + + + + Web User Interface Error - Unable to bind Web UI to port %1 + + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + + + + + '%1' is not a valid magnet URI. + + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + + + + + Error: Failed to parse the provided IP filter. + + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + + + + + UPnP / NAT-PMP support [ON] + + + + + UPnP / NAT-PMP support [OFF] + + + + + Local Peer Discovery support [ON] + + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + + + + + This file is either corrupted or this isn't a torrent. + + + + + Error: The torrent %1 does not contain any file. + + + + + Note: new trackers were added to the existing torrent. + + + + + Note: new URL seeds were added to the existing torrent. + + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + + + + + The network interface defined is invalid: %1 + + + + + Trying any other network interface available instead. + + + + + Listening on IP address %1 on network interface %2... + + + + + Failed to listen on network interface %1 + + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + + + + + + Unable to decode %1 torrent file. + + + + + Torrent name: %1 + + + + + Torrent size: %1 + + + + + Save path: %1 + + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + + + + + Thank you for using qBittorrent. + + + + + [qBittorrent] %1 has finished downloading + + + + + An I/O error occured, '%1' paused. + + + + + + Reason: %1 + + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + + + + + File sizes mismatch for torrent %1, pausing it. + + + + + Fast resume data was rejected for torrent %1, checking again... + + + + + Url seed lookup failed for url: %1, message: %2 + + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + + + + + RSS + + + Search + + + + + New subscription + + + + + + + Mark items read + + + + + Update all + + + + + RSS Downloader... + + + + + Settings... + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + + + + + + Delete + + + + + Rename... + + + + + Rename + + + + + + Update + + + + + New subscription... + + + + + + Update all feeds + + + + + Download torrent + + + + + Open news URL + + + + + Copy feed URL + + + + + New folder... + + + + + Manage cookies... + + + + + Refresh RSS streams + + + + + RSSImp + + + Please type a rss stream url + + + + + Stream URL: + + + + + + Are you sure? -- qBittorrent + + + + + + &Yes + + + + + + &No + + + + + Please choose a folder name + + + + + Folder name: + + + + + New folder + + + + + Overwrite attempt + + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + + + + + qBittorrent + + + + + This rss feed is already in the list. + + + + + Are you sure you want to delete these elements from the list? + + + + + Are you sure you want to delete this element from the list? + + + + + Please choose a new name for this RSS feed + + + + + New feed name: + + + + + Name already in use + + + + + This name is already used by another item, please choose another one. + + + + + Date: + + + + + Author: + + + + + Unread + + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + + + + + RssSettingsDlg + + + RSS Reader Settings + + + + + RSS feeds refresh interval: + + + + + minutes + + + + + Maximum number of articles per feed: + + + + + ScanFoldersModel + + + Watched Folder + + + + + Download here + + + + + SearchCategories + + + All categories + + + + + Movies + + + + + TV shows + + + + + Music + + + + + Games + + + + + Anime + + + + + Software + + + + + Pictures + + + + + Books + + + + + SearchEngine + + + Cut + + + + + Copy + + + + + Paste + + + + + Clear field + + + + + Clear completion history + + + + + Confirmation + + + + + Are you sure you want to clear the history? + + + + + + + Search + + + + + Missing Python Interpreter + + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + + + + + Empty search pattern + + + + + Please type a search pattern first + + + + + + Results + + + + + Searching... + + + + + Search Engine + + + + + + Search has finished + + + + + An error occured during search... + + + + + + Search aborted + + + + + Download error + + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + + + + + Search returned no results + + + + + Results + i.e: Search results + + + + + + Unknown + + + + + SearchTab + + + Name + i.e: file name + + + + + Size + i.e: file size + + + + + Seeders + i.e: Number of full sources + + + + + Leechers + i.e: Number of partial sources + + + + + Search engine + + + + + ShutdownConfirmDlg + + + Shutdown confirmation + + + + + SpeedLimitDialog + + + KiB/s + + + + + StatusBar + + + + Connection status: + + + + + + No direct connections. This may indicate network configuration problems. + + + + + + DHT: %1 nodes + + + + + qBittorrent needs to be restarted + + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + + + + + + Connection Status: + + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + + + + + Online + + + + + + %1/s + Per second + + + + + Click to switch to alternative speed limits + + + + + Click to switch to regular speed limits + + + + + Global Download Speed Limit + + + + + Global Upload Speed Limit + + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + + + + + Select a file to add to the torrent + + + + + No input path set + + + + + Please type an input path first + + + + + Select destination torrent file + + + + + Torrent Files + + + + + + + Torrent creation + + + + + Torrent creation was unsuccessful, reason: %1 + + + + + Created torrent file is invalid. It won't be added to download list. + + + + + Torrent was created successfully: + + + + + TorrentFilesModel + + + Name + + + + + Size + + + + + Progress + + + + + Priority + + + + + TorrentImportDlg + + + Torrent Import + + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + + + + + Torrent file to import: + + + + + + ... + + + + + Content location: + + + + + Skip the data checking stage and start seeding immediately + + + + + Import + + + + + Torrent file to import + + + + + Torrent files (*.torrent) + + + + + %1 Files + %1 is a file extension (e.g. PDF) + + + + + Please provide the location of %1 + %1 is a file name + + + + + Please point to the location of the torrent: %1 + + + + + Invalid torrent file + + + + + This is not a valid torrent file. + + + + + TorrentModel + + + Name + i.e: torrent name + + + + + Size + i.e: torrent size + + + + + Done + % Done + + + + + Status + Torrent status (e.g. downloading, seeding, paused) + + + + + Seeds + i.e. full sources (often untranslated) + + + + + Peers + i.e. partial sources (often untranslated) + + + + + Down Speed + i.e: Download speed + + + + + Up Speed + i.e: Upload speed + + + + + Ratio + Share ratio + + + + + ETA + i.e: Estimated Time of Arrival / Time left + + + + + Label + + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + + + + + Tracker + + + + + Down Limit + i.e: Download limit + + + + + Up Limit + i.e: Upload limit + + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + + + + + Amount left + Amount of data left to download (e.g. in MB) + + + + + Time Active + Time (duration) the torrent is active (not paused) + + + + + TrackerList + + + URL + + + + + Status + + + + + Peers + + + + + Message + + + + + [DHT] + + + + + [PeX] + + + + + [LSD] + + + + + + + + + Working + + + + + + + Disabled + + + + + This torrent is private + + + + + Updating... + + + + + + Not working + + + + + + Not contacted yet + + + + + Add a new tracker... + + + + + Remove tracker + + + + + Force reannounce + + + + + TrackersAdditionDlg + + + Trackers addition dialog + + + + + List of trackers to add (one per line): + + + + + µTorrent compatible list URL: + + + + + I/O Error + + + + + Error while trying to open the downloaded file. + + + + + No change + + + + + No additional trackers were found. + + + + + Download error + + + + + The trackers list could not be downloaded, reason: %1 + + + + + TransferListDelegate + + + Downloading + + + + + Paused + + + + + Queued + i.e. torrent is queued + + + + + Seeding + Torrent is complete and in upload-only mode + + + + + Stalled + Torrent is waiting for download to begin + + + + + Checking + Torrent local data is being checked + + + + + /s + /second (.i.e per second) + + + + + KiB/s + KiB/second (.i.e per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + + + + + TransferListFiltersWidget + + + + All + + + + + + Downloading + + + + + + Completed + + + + + + Paused + + + + + + Active + + + + + + Inactive + + + + + + All labels + + + + + + Unlabeled + + + + + Remove label + + + + + Add label... + + + + + Resume torrents + + + + + Pause torrents + + + + + Delete torrents + + + + + New Label + + + + + Label: + + + + + Invalid label name + + + + + Please don't use any special characters in the label name. + + + + + TransferListWidget + + + Column visibility + + + + + Label + + + + + Choose save path + + + + + Torrent Download Speed Limiting + + + + + Torrent Upload Speed Limiting + + + + + New Label + + + + + Label: + + + + + Invalid label name + + + + + Please don't use any special characters in the label name. + + + + + Rename + + + + + New name: + + + + + Resume + Resume/start the torrent + + + + + Pause + Pause the torrent + + + + + Delete + Delete the torrent + + + + + Preview file... + + + + + Limit share ratio... + + + + + Limit upload rate... + + + + + Limit download rate... + + + + + Open destination folder + + + + + Move up + i.e. move up in the queue + + + + + Move down + i.e. Move down in the queue + + + + + Move to top + i.e. Move to top of the queue + + + + + Move to bottom + i.e. Move to bottom of the queue + + + + + Set location... + + + + + Priority + + + + + Force recheck + + + + + Copy magnet link + + + + + Super seeding mode + + + + + Rename... + + + + + Download in sequential order + + + + + Download first and last piece first + + + + + New... + New label... + + + + + Reset + Reset label + + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + + + + + Use global ratio limit + + + + + + + buttonGroup + + + + + Set no ratio limit + + + + + Set ratio limit to + + + + + UsageDisplay + + + Usage: + + + + + displays program version + + + + + disable splash screen + + + + + displays this help message + + + + + changes the webui port (current: %1) + + + + + [files or urls]: downloads the torrents passed by the user (optional) + + + + + about + + + qBittorrent + + + + + I would like to thank the following people who volunteered to translate qBittorrent: + + + + + Please contact me if you would like to translate qBittorrent into your own language. + + + + + addPeerDialog + + + Peer addition + + + + + IP + + + + + Port + + + + + addTorrentDialog + + + Torrent addition dialog + + + + + Save path: + + + + + ... + + + + + Torrent size: + + + + + + Unknown + + + + + Free disk space: + + + + + Label: + + + + + Torrent content: + + + + + Select All + + + + + Select None + + + + + Download in sequential order (slower but good for previewing) + + + + + Skip file checking and start seeding immediately + + + + + Add to download list in paused state + + + + + Add + + + + + Cancel + + + + + Normal + + + + + High + + + + + Maximum + + + + + + Do not download + + + + + authentication + + + + Tracker authentication + + + + + Tracker: + + + + + Login + + + + + Username: + + + + + Password: + + + + + Log in + + + + + Cancel + + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + + + + + Are you sure you want to delete the selected torrents from the transfer list? + + + + + Remember choice + + + + + Also delete the files on the hard disk + + + + + createTorrentDialog + + + Cancel + + + + + Torrent Creation Tool + + + + + Torrent file creation + + + + + Add file + + + + + Add folder + + + + + File or folder to add to the torrent: + + + + + Tracker URLs: + + + + + Web seeds urls: + + + + + Comment: + + + + + Piece size: + + + + + 32 KiB + + + + + 64 KiB + + + + + 128 KiB + + + + + 256 KiB + + + + + 512 KiB + + + + + 1 MiB + + + + + 2 MiB + + + + + 4 MiB + + + + + Auto + + + + + Private (won't be distributed on DHT network if enabled) + + + + + Start seeding after creation + + + + + Create and save... + + + + + Progress: + + + + + downloadFromURL + + + Add torrent links + + + + + Both HTTP and Magnet links are supported + + + + + Download + + + + + Cancel + + + + + Download from urls + + + + + No URL entered + + + + + Please type at least one URL. + + + + + engineSelect + + + Search plugins + + + + + Installed search engines: + + + + + Name + + + + + Url + + + + + + Enabled + + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + + Install a new one + + + + + Check for updates + + + + + Close + + + + + Uninstall + + + + + engineSelectDlg + + + Uninstall warning + + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + + + + + Uninstall success + + + + + Select search plugins + + + + + qBittorrent search plugins + + + + + + + + + Search plugin install + + + + + + + Yes + + + + + + + + No + + + + + + + + + + + + + qBittorrent + + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + + + + + + + + Search plugin update + + + + + + Sorry, update server is temporarily unavailable. + + + + + All your plugins are already up to date. + + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + + + + + All selected plugins were uninstalled successfully + + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + + + + + New search engine plugin URL + + + + + URL: + + + + + misc + + + B + bytes + + + + + KiB + kibibytes (1024 bytes) + + + + + MiB + mebibytes (1024 kibibytes) + + + + + GiB + gibibytes (1024 mibibytes) + + + + + TiB + tebibytes (1024 gibibytes) + + + + + %1h %2m + e.g: 3hours 5minutes + + + + + %1d %2h + e.g: 2days 10hours + + + + + Unknown + Unknown (size) + + + + + qBittorrent will shutdown the computer now because all downloads are complete. + + + + + + + + + + Unknown + + + + + < 1m + < 1 minute + + + + + %1m + e.g: 10minutes + + + + + options_imp + + + + Choose export directory + + + + + + + + Choose a save directory + + + + + + Choose an ip filter file + + + + + Add directory to scan + + + + + Folder is already being watched. + + + + + Folder does not exist. + + + + + Folder is not readable. + + + + + Failure + + + + + Failed to add Scan Folder '%1': %2 + + + + + + Filters + + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + + + + + Failed to parse the provided IP filter + + + + + Successfully refreshed + + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + + pluginSourceDlg + + + Plugin source + + + + + Search plugin source: + + + + + Local file + + + + + Web link + + + + + preview + + + Preview selection + + + + + File preview + + + + + The following files support previewing, <br>please select one of them: + + + + + Preview + + + + + Cancel + + + + + search_engine + + + + Search + + + + + Status: + + + + + Stopped + + + + + Download + + + + + Go to description page + + + + + Search engines... + + + + + torrentAdditionDialog + + + Unable to decode magnet link: + + + + + Magnet Link + + + + + + Unable to decode torrent file: + + + + + Rename... + + + + + Priority + + + + + Rename the file + + + + + New name: + + + + + + The file could not be renamed + + + + + This file name contains forbidden characters, please choose a different one. + + + + + + This name is already in use in this folder. Please use a different name. + + + + + The folder could not be renamed + + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + + + + + + + Choose save path + + + + + Empty save path + + + + + Please enter a save path + + + + + Save path creation error + + + + + Could not create the save path + + + + + Invalid label name + + + + + Please don't use any special characters in the label name. + + + + + Seeding mode error + + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + + + + + Invalid file selection + + + + + You must select at least one file in the torrent + + + + diff --git a/src/lang/qbittorrent_es.qm b/src/lang/qbittorrent_es.qm new file mode 100644 index 0000000000000000000000000000000000000000..19b818c562be42b2646e018be4d14db196bd2eca GIT binary patch literal 108417 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

r?xNGI(mDWkCTTJ+OBfYB=2hQe;i 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 X?hRkYXF>&7i!$@~&~v`_(o6pjkEIJv literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_es.ts b/src/lang/qbittorrent_es.ts new file mode 100644 index 000000000..b348ba6d7 --- /dev/null +++ b/src/lang/qbittorrent_es.ts @@ -0,0 +1,6540 @@ + + + + + AboutDlg + + + About qBittorrent + Acerca de qBittorrent + + + + About + Acerca de + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Es un cliente Bittorrent programado en C++, basado en Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">y libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Página Oficial:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + Author + Autor + + + + Name: + Nombre: + + + + Country: + País: + + + + E-mail: + E-Mail: + + + + Christophe Dumez + Christophe Dumez + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + + France + Francia + + + + Translation + Traducción + + + + License + Licencia + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + + chris@qbittorrent.org + + + + + Thanks to + Gracias a + + + + AdvancedSettings + + Property + Prioridad + + + Value + Valor + + + + Disk write cache size + Tamaño cache del Disco + + + + MiB + MiB + + + + Outgoing ports (Min) [0: Disabled] + Puertos de salida (Min) [0: Desactivado] + + + + Outgoing ports (Max) [0: Disabled] + Puertos de salida (Max) [0: Desactivado] + + + + Recheck torrents on completion + Verificar Torrents completados + + + + Transfer list refresh interval + Intervalo de actualización de las listas de transferencia + + + + ms + milliseconds + ms + + + + Setting + + + + + Value + Value set for this setting + Valor + + + + Resolve peer countries (GeoIP) + Mostrar Pares por Países (GeoIP) + + + + Resolve peer host names + Mostrar Pares por nombre de Host + + + + Maximum number of half-open connections [0: Disabled] + Número máximo de conexiones abiertas [0: Desactivado] + + + + Strict super seeding + Siembra super estricta + + + + Network Interface (requires restart) + Selección de Red (es necesario reiniciar) + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + Cualquier Red + + + + IP Address to report to trackers (requires restart) + Dirección IP para informe de incidencias a los trackers (es necesario reiniciar) + + + + Display program on-screen notifications + Visualización en pantalla de las notificaciones + + + Display program notification balloons + Mostrar globos de notificación + + + + Enable embedded tracker + Habilitar integración de tracker + + + + Embedded tracker port + Puerto de integración de tracker + + + + Check for software updates + Comprobar si hay actualizaciones + + + + Use system icon theme + Usar iconos del tema actual + + + + Confirm torrent deletion + Confirmar la eliminación del torrent + + + Display program notification baloons + Mostrar globos de notificación + + + + Ignore transfer limits on local network + Ignorar limites de transferencia de la red local + + + Include TCP/IP overhead in transfer limits + Incluir TCP / IP en los límites generales de transferencia + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Automatizar Descarga canales RSS + + + + Enable the automated RSS downloader + Activar Descarga automatizada de canales RSS + + + + Download rules + Reglas de Descargas + + + + Rule definition + Definición de reglas + + + + Must contain: + Debe contener: + + + + Must not contain: + No debe contener: + + + + Use regular expressions + + + + + Import... + Importar... + + + + Export... + Exportar... + + + Save torrent to: + Guardar torrent en: + + + + ... + ... + + + + Assign label: + Etiquetar como: + + + + Save to a different directory + Guardar en un directorio diferente + + + + Save to: + Guardar en: + + + + Apply rule to feeds: + Aplicar reglas a los canales: + + + + Matching RSS articles + Coincidencia de canales RSS + + + + New rule name + Nueva regla + + + + Please type the name of the new download rule. + Por favor, escriba el nombre de la nueva regla a descargar. + + + + + Rule name conflict + Conflicto con el nombre de la regla + + + + + A rule with this name already exists, please choose another name. + Ya existena una regla con este nombre, por favor, elija otro nombre. + + + + Are you sure you want to remove the download rule named %1? + ¿Está seguro que desea eliminar la regla de transferencia llamada %1? + + + + Are you sure you want to remove the selected download rules? + ¿Está seguro que desea eliminar las normas de descargas seleccionadas? + + + + Rule deletion confirmation + Confirmar eliminar regla + + + + Destination directory + Directorio de destino + + + + Invalid action + Acción no válida + + + + The list is empty, there is nothing to export. + La lista está vacía, no hay nada para exportar. + + + + Where would you like to save the list? + ¿Dónde le gustaría guardar la lista? + + + + Rules list (*.rssrules) + Lista de reglas (*.rssrules) + + + + I/O Error + Error de Entrada/Salida + + + + Failed to create the destination file + No se pudo crear el archivo de destino + + + + Please point to the RSS download rules file + Por favor, seleccione las normas de descarga de canales RSS + + + + Rules list (*.rssrules *.filters) + Lista de reglas (*.rssrules *.filters) + + + + Import Error + Error al importar + + + + Failed to import the selected rules file + No se pudo importar el archivo de reglas seleccionado + + + + Add new rule... + Añadir nueva regla... + + + + Delete rule + Eliminar regla + + + + Rename rule... + Renombrar regla... + + + + Delete selected rules + Eliminar reglas seleccionadas + + + + Rule renaming + Regla renombrada + + + + Please type the new rule name + Por favor, escriba el nombre de la nueva regla + + + + Regex mode: use Perl-like regular expressions + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 alcanzó el ratio máximo establecido. + + + Removing torrent %1... + Extrayendo torrent %1... + + + Pausing torrent %1... + Torrent Pausado %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent está usando el puerto: TCP/%1 + + + UPnP support [ON] + Soporte para UPnP [Encendido] + + + UPnP support [OFF] + Soporte para UPnP [Apagado] + + + NAT-PMP support [ON] + Soporte para NAT-PMP [Encendido] + + + NAT-PMP support [OFF] + Soporte para NAT-PMP[Apagado] + + + HTTP user agent is %1 + HTTP de usuario es %1 + + + Using a disk cache size of %1 MiB + Tamaño cache del Disco %1 MiB + + + DHT support [ON], port: UDP/%1 + Soporte para DHT [Encendido], puerto: UPD/%1 + + + DHT support [OFF] + Soporte para DHT [Apagado] + + + PeX support [ON] + Soporte para PeX [Encendido] + + + PeX support [OFF] + Soporte PeX [Apagado] + + + Restart is required to toggle PeX support + Es necesario reiniciar para activar soporte PeX + + + Local Peer Discovery [ON] + Estado local de Pares [Encendido] + + + Local Peer Discovery support [OFF] + Soporte para estado local de Pares [Apagado] + + + Encryption support [ON] + Soporte para encriptado [Encendido] + + + Encryption support [FORCED] + Soporte para encriptado [Forzado] + + + Encryption support [OFF] + Sopote para encriptado [Apagado] + + + The Web UI is listening on port %1 + Puerto de escucha de Interfaz Usuario Web %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Error interfaz de Usuario Web - No se puede enlazar al puerto %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' Fue eliminado de la lista de transferencia y del disco. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' Fue eliminado de la lista de transferencia. + + + '%1' is not a valid magnet URI. + '%1' no es una URI válida. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' ya está en la lista de descargas. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' reiniciado. (reinicio rápido) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' agregado a la lista de descargas. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Imposible decodificar el archivo torrent: '%1' + + + This file is either corrupted or this isn't a torrent. + Este archivo puede estar corrupto, o no ser un torrent. + + + Note: new trackers were added to the existing torrent. + Nota: nuevos Trackers se han añadido al torrent existente. + + + Note: new URL seeds were added to the existing torrent. + Nota: nuevas semillas URL se han añadido al Torrent existente. + + + Error: The torrent %1 does not contain any file. + Error: este torrent %1 no contiene ningún archivo. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>fue bloqueado debido al filtro IP</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>Fue bloqueado debido a fragmentos corruptos</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Descarga recursiva de archivo %1 inscrustada en Torrent %2 + + + Unable to decode %1 torrent file. + No se puede descodificar %1 archivo torrent. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Falló el mapeo del puerto, mensaje: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Mapeo del puerto exitoso, mensaje: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Se negaron los datos para reinicio rápido del torrent: %1, verificando de nuevo... + + + Reason: %1 + Razón: %1 + + + Torrent name: %1 + Nombre del torrent: %1 + + + Torrent size: %1 + Tamaño del torrent: %1 + + + Save path: %1 + Guardar ruta: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + El torrernt se descargó en %1. + + + Thank you for using qBittorrent. + Gracias por utilizar qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 ha finalizado la descarga + + + An I/O error occured, '%1' paused. + Error de E/S ocurrido, '%1' pausado. + + + File sizes mismatch for torrent %1, pausing it. + El tamaño de archivo no coincide con el torrent %1, pausandolo. + + + Url seed lookup failed for url: %1, message: %2 + Falló la búsqueda de semilla por Url para la Url: %1, mensaje: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Descargando '%1', por favor espere... + + + + ConsoleDlg + + qBittorrent log viewer + qBittorrent visor de registros + + + General + General + + + Blocked IPs + IPs bloqueadas + + + + CookiesDlg + + + Cookies management + Administración de Cookies + + + + Key + As in Key/Value pair + Clave + + + + Value + As in Key/Value pair + Valor + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Las Claves para las Cookies son : '%1', '%2' +Debe obtener esta información de las preferencias de su navegador Web. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + + + + + Dynamic DNS error: Invalid username/password. + + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: Your username was blocked due to abuse. + + + + + Dynamic DNS error: supplied domain name is invalid. + + + + + Dynamic DNS error: supplied username is too short. + + + + + Dynamic DNS error: supplied password is too short. + + + + + DownloadThread + + + + I/O Error + Error de Entrada/Salida + + + + The remote host name was not found (invalid hostname) + El nombre de host remoto no se ha encontrado (nombre de host no válido) + + + + The operation was canceled + La operación fue cancelada + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + El servidor remoto cerró la conexión antes de tiempo, antes que fuese recibido y procesado + + + + The connection to the remote server timed out + Conexión con el servidor remoto fallida, Tiempo de espera agotado + + + + SSL/TLS handshake failed + SSL/TLS handshake fallida + + + + The remote server refused the connection + El servidor remoto rechazó la conexión + + + + The connection to the proxy server was refused + La conexión con el servidor proxy fue rechazada + + + + The proxy server closed the connection prematurely + Conexión cerrada antes de tiempo por el servidor proxy + + + + The proxy host name was not found + El nombre de host del proxy no se ha encontrado + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + La conexión con el servidor proxy se ha agotado, o el proxy no respondió a tiempo a la solicitud enviada + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + El proxy requiere autenticación con el fin de atender la solicitud, pero no aceptó las credenciales que ofreció + + + + The access to the remote content was denied (401) + El acceso al contenido remoto ha sido rechazado (401) + + + + The operation requested on the remote content is not permitted + La operación solicitada del contenido remoto no está permitida + + + + The remote content was not found at the server (404) + El contenido remoto no se encuentra en el servidor (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + El servidor remoto requiere autenticación para servir el contenido, pero las credenciales proporcionadas no son correctas + + + + The Network Access API cannot honor the request because the protocol is not known + El acceso a la red de la API no puede cumplir con la solicitud debido a que el protocolo es desconocido + + + + The requested operation is invalid for this protocol + La operación solicitada no es válida para este protocolo + + + + An unknown network-related error was detected + Error de Red desconocido + + + + An unknown proxy-related error was detected + Error de Proxy desconocido + + + + An unknown error related to the remote content was detected + Error desconocido en el servidor remoto + + + + A breakdown in protocol was detected + Error de protocolo + + + + Unknown error + Error desconocido + + + + EventManager + + + + Working + Trabajando + + + + Updating... + Actualizando... + + + + + Not working + Sin servicio + + + + + Not contacted yet + No conectado todavía + + + + + this session + en esta sesión + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Completo desde %1 + + + + %1 max + e.g. 10 max + + + + + + %1/s + e.g. 120 KiB/s + + + + + ExecutionLog + + Form + Formulario + + + + General + General + + + + Blocked IPs + IPs bloqueadas + + + + FeedDownloader + + RSS Feed downloader + Descargando canal RSS + + + RSS feed: + Canal RSS: + + + Feed name + Nombre del Canal + + + Automatically download torrents from this feed + Descargar automáticamente torrents desde este Canal + + + Download filters + Descargar filtros + + + Filters: + Filtros: + + + Filter settings + Ajustes de filtros + + + Matches: + Concordancias: + + + Does not match: + No coinciden con: + + + Destination folder: + Carpeta de destino: + + + ... + ... + + + Filter testing + Verificando filtros + + + Torrent title: + Título Torrent: + + + Result: + Resultado: + + + Test + Prueba + + + Import... + Importar... + + + Export... + Exportar... + + + Rename filter + Renombrar filtro + + + Remove filter + Eliminar filtro + + + Add filter + Agregar filtro + + + + FeedDownloaderDlg + + New filter + Nuevo filtro + + + Please choose a name for this filter + Por favor, elija un nombre para este filtro + + + Filter name: + Nombre del filtro: + + + Invalid filter name + Nombre no valido para el filtro + + + The filter name cannot be left empty. + El nombre del filtro no puede quedar vació. + + + This filter name is already in use. + Este nombre de filtro ya se está usando. + + + Choose save path + Seleccione la ruta donde guardarlo + + + Filter testing error + Error en la verificación del filtro + + + Please specify a test torrent name. + Por favor, especifique el nombre del torrent a verificar. + + + matches + Contiene + + + does not match + no contiene + + + Select file to import + Seleccione el archivo a importar + + + Filters Files + Filtro de archivos + + + Import successful + Importación satisfactoria + + + Filters import was successful. + Filtros importados satisfactoriamente. + + + Import failure + Importación fallida + + + Filters could not be imported due to an I/O error. + Los filtros no pueden ser importados debido a un Error de Entrada/Salida. + + + Select destination file + Seleccione la ruta del archivo + + + Export successful + Exportación satisfactoria + + + Filters export was successful. + Filtros exportados satisfactoriamente. + + + Export failure + Exportación fallida + + + Filters could not be exported due to an I/O error. + Los filtros no pueden ser exportados debido a un Error de Entrada/Salida. + + + + FeedList + + Unread + No leído + + + + FeedListWidget + + + RSS feeds + Canales RSS + + + + Unread + No leídos + + + + GUI + + Open Torrent Files + Abrir archivos Torrent + + + Torrent Files + Archivos Torrent + + + qBittorrent + qBittorrent + + + Transfers + Transferencia + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Vel. de Bajada: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Vel. de Subida: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 ha terminado de descargarse. + + + I/O Error + i.e: Input/Output Error + Error de Entrada/Salida + + + Search + Buscar + + + Torrent file association + Asociación de archivos Torrent + + + Set the password... + Configurar Contraseña... + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent no es la aplicación por defecto para abrir archivos Torrent o enlaces Magnet. +¿Quiere que qBittorrent sea el programa por defecto para gestionar estos archivos? + + + Password update + Actualizar Contraseña + + + The UI lock password has been successfully updated + La contraseña de bloqueo de qBittorrent se ha actualizado correctamente + + + RSS + RSS + + + Transfers (%1) + Transferencias (%1) + + + Download completion + Descarga completada + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Se produjo un Error de Entrada/Salida, torrent %1. + Razón: %2 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Confirmación descargas recursivas + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Este torrent %1 contiene archivos torrent, ¿quiere seguir adelante con su descarga? + + + Yes + + + + No + No + + + Never + Nunca + + + Global Upload Speed Limit + Límite global de subida + + + Global Download Speed Limit + Limite global de bajada + + + A newer version is available + Hay una nueva versión disponible + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Hay disponible una versión más reciente de qBittorrent en Sourceforge. +¿Desea actualizar qBittorrent a la versión%1? + + + Impossible to update qBittorrent + Ha sido imposible actualizar qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent no pudo actualizarse, por la siguiente razón: %1 + + + UI lock password + Contraseña de bloqueo + + + Please type the UI lock password: + Por favor, escriba la contraseña de bloqueo: + + + Invalid password + Contraseña no válida + + + The password is invalid + La contraseña no es válida + + + Exiting qBittorrent + Cerrando qBittorrent + + + Always + Siempre + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Bajada: %2/s, Subida: %3/s) + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Error de descarga de Url + + + Couldn't download file at url: %1, reason: %2. + No se pudo descargar el archivo en la url: %1, razón: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl + F + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Algunos archivos están aún transfiriendose. +¿Está seguro que quiere salir? + + + Options were saved successfully. + Opciones guardadas correctamente. + + + + GeoIP + + France + Francia + + + Saudi Arabia + Arabia Saudí + + + + HeadlessLoader + + + Information + Información + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Control qBittorrent, acceso a interfaz de usuario Web a http://localhost:%1 + + + + The Web UI administrator user name is: %1 + Nombre de usuario del administrador Web: %1 + + + + The Web UI administrator password is still the default one: %1 + La contraseña del administrador de interfaz de usuario web sigue siendo por defecto:%1 + + + + This is a security risk, please consider changing your password from program preferences. + Esto es un riesgo de seguridad, por favor considere cambiar su contraseña de las preferencias del programa. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + Tras muchos intentos de conexión, parece ser que tu dirección IP ha sido restringida. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Bajada: %1/s - Total: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Subida: %1/s - Total: %2 + + + + HttpServer + + + File + Archivo + + + + Edit + Editar + + + + Help + Ayuda + + + Delete from HD + Eliminar del disco + + + + Download Torrents from their URL or Magnet link + Descargar Torrents desde URL o Enlace (Link) + + + + Only one link per line + Solamente un enlace (Link) por línea + + + + Download local torrent + Descargar torrent local + + + + Torrent files were correctly added to download list. + Los archivos torrents se añadieron correctamente a la lista de descarga. + + + + Point to torrent file + Indique un archivo torrent + + + + Download + Descargar + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + ¿Está seguro que quiere eliminar los torrents seleccionados de la lista de transferencia y del disco? + + + + Download rate limit must be greater than 0 or disabled. + El límite de la tasa de descarga debe ser mayor que 0 o estar inhabilitado. + + + + Upload rate limit must be greater than 0 or disabled. + El límite de la tasa de subida debe ser mayor que 0 o estar inhabilitado. + + + + Maximum number of connections limit must be greater than 0 or disabled. + El número máximo del limite de conexiones debe ser mayor que 0 o estar inhabilitado. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + El número máximo del limite de conexiones por torrent debe ser mayor que 0 o estar inhabilitado. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + El número máximo de subidas de slots por torrent debe ser mayor que 0 o estar inhabilitado. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + No se puede guardar las preferencias del programa, qbittorrent probablemente no es accesible. + + + + Language + Idioma + + + + Downloaded + Is the file downloaded or not? + Bajado + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + El puerto utilizado para conexiones entrantes debe ser mayor de 1024 y menor de 65535. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + El puerto utilizado para la Interfaz de Usuario Web debe ser mayor de 1024 y menor de 65535. + + + + The Web UI username must be at least 3 characters long. + El nombre de Interfaz de Usuario web debe ser de al menos 3 caracteres. + + + + The Web UI password must be at least 3 characters long. + La contraseña de Interfaz de Usuario Web debe ser de al menos 3 caracteres. + + + + Save + Guardar + + + + qBittorrent client is not reachable + El cliente qBittorrent no es accesible + + + + HTTP Server + Servidor HTTP + + + + The following parameters are supported: + + + + + Torrent path + + + + + Torrent name + + + + + LegalNotice + + + Legal Notice + Aviso Legal + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent es un programa para compartir archivos. Cuando se ejecuta un torrente, sus datos se pondrán a disposición de los demás usuarios por medio de las subidas. Por supuesto, cualquier contenido que usted comparta es bajo su propia responsabilidad. + +Probablemente esto es algo que ya sabía, así que no se lo diré otra vez. + + + + Press %1 key to accept and continue... + Pulse cualquier tecla para aceptar y continuar ... + + + + Legal notice + Aviso Legal + + + + Cancel + Cancelar + + + + I Agree + Estoy de acuerdo + + + + LineEdit + + + Clear the text + Borrar texto + + + + MainWindow + + + &Edit + &Editar + + + + &Tools + &Herramientas + + + + &File + &Archivo + + + + &Help + A&yuda + + + + &View + &Ver + + + &Add File... + &Agregar archivo... + + + E&xit + &Salir + + + + &Options... + &Opciones... + + + Add &URL... + Añadir &URL... + + + + Torrent &creator + Crear &Torrent + + + + Set upload limit... + Límitie de Subidad... + + + + Set download limit... + Límite de Bajada... + + + + &About + &Acerca de + + + + &Pause + &Pausar + + + + &Delete + &Borrar + + + + P&ause All + Pa&usar Todas + + + + &Resume + &Reanudar + + + + &Add torrent file... + &Añadir archivo torrent... + + + + + Exit + Salir + + + + R&esume All + R&eanudar Todas + + + + Visit &Website + &Visite mi sitio Web + + + + Auto-Shutdown on downloads completion + Cerrar cuando se completen las descargas + + + + Add &link to torrent... + Añadir &enlace torrent... + + + + Report a &bug + Comunicar un &bug + + + + &Documentation + &Documentación + + + + Set global download limit... + Límite global de Bajada... + + + + Set global upload limit... + Límite global de Subida... + + + + Exit qBittorrent + Cerrar qBittorrent + + + + Suspend system + Suspender sistema + + + + Shutdown system + Cerrar sistema + + + + Disabled + Deshabilitado + + + &Log viewer... + Visor de &registros... + + + Log viewer + Visor de registros + + + Shutdown computer when downloads complete + Apagar el equipo al finalizar las descargas + + + + + Lock qBittorrent + Bloquear qBittorrent + + + + Ctrl+L + Ctrl+L + + + Shutdown qBittorrent when downloads complete + Apagar qBittorrent cuando la descarga esté completa + + + + Import existing torrent... + Importar torrent existente... + + + + Import torrent... + Importar torrent... + + + + Donate money + Donar + + + + If you like qBittorrent, please donate! + Si le gusta qBittorrent, por favor realice una donación! + + + + Execution &Log + Ejecución &Log + + + + + Execution Log + Ejecución Log + + + + + Alternative speed limits + Límites de velocidad alternativa + + + + &RSS reader + &Lector RSS + + + + Search &engine + &Motor de búsqueda + + + + Top &tool bar + Barra &Herramientas superior + + + + Display top tool bar + Mostrar barra heramientas superior + + + + &Speed in title bar + &Velocidad en la barra + + + + Show transfer speed in title bar + Mostrar velocidad en la barra de título + + + Preview file + Previsualizar archivo + + + Clear log + Limpiar registro + + + + Decrease priority + Disminuir prioridad + + + + Increase priority + Incrementar prioridad + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + Configurar Contraseña... + + + + Transfers + Transferencia + + + + Torrent file association + Asociación de archivos Torrent + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent no es la aplicación por defecto para abrir archivos Torrent o enlaces Magnet. +¿Quiere que qBittorrent sea el programa por defecto para gestionar estos archivos? + + + + + + UI lock password + Contraseña de bloqueo + + + + + + Please type the UI lock password: + Por favor, escriba la contraseña de bloqueo: + + + + The password should contain at least 3 characters + Cómo mínimo la contraseña debe tener 3 caracteres + + + + Password update + Actualizar Contraseña + + + + The UI lock password has been successfully updated + La contraseña de bloqueo de qBittorrent se ha actualizado correctamente + + + + RSS + RSS + + + + Search + Buscar + + + + Transfers (%1) + Transferencias (%1) + + + + Download completion + Descarga completada + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 ha terminado de descargarse. + + + + I/O Error + i.e: Input/Output Error + Error de Entrada/Salida + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Se produjo un Error de Entrada/Salida, torrent %1. + Razón: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Confirmación descargas recursivas + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Este torrent %1 contiene archivos torrent, ¿quiere seguir adelante con su descarga? + + + + + Yes + + + + + + No + No + + + + Never + Nunca + + + + Url download error + Error de descarga de Url + + + + Couldn't download file at url: %1, reason: %2. + No se pudo descargar el archivo en la url: %1, razón: %2. + + + + Global Upload Speed Limit + Límite de velocidad global de subida + + + + Global Download Speed Limit + Límite de velocidad global de bajada + + + + + Invalid password + Contraseña no válida + + + + The password is invalid + La contraseña no es válida + + + + Exiting qBittorrent + Cerrando qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Algunos archivos aún están transfiriendose. +¿Está seguro que quiere salir? + + + + Always + Siempre + + + + Open Torrent Files + Abrir archivos Torrent + + + + Torrent Files + Archivos torrent + + + + Options were saved successfully. + Opciones guardadas correctamente. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Vel. de Bajada: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Vel. de Subida: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Bajada: %2/s, Subida: %3/s) + + + + A newer version is available + Hay una nueva versión disponible + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Hay disponible una versión más reciente de qBittorrent en Sourceforge. +¿Desea actualizar qBittorrent a la versión %1? + + + + Impossible to update qBittorrent + Ha sido imposible actualizar qBittorrent + + + + qBittorrent failed to update, reason: %1 + qBittorrent no pudo actualizarse, por la siguiente razón: %1 + + + + PeerAdditionDlg + + + Invalid IP + IP inválida + + + + The IP you provided is invalid. + La IP facilitada no es válida. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + + + + + Connection + Conexión + + + + Client + i.e.: Client application + Cliente + + + + Progress + i.e: % downloaded + Progreso + + + + Down Speed + i.e: Download speed + Vel. Bajada + + + + Up Speed + i.e: Upload speed + Vel. Subida + + + + Downloaded + i.e: total data downloaded + Bajado + + + + Uploaded + i.e: total data uploaded + Subido + + + + Add a new peer... + Añadir nuevo par... + + + + Copy IP + Copiar IP + + + + Limit download rate... + Tasa límite de Bajada... + + + + Limit upload rate... + Tasa límite de Subida... + + + + Ban peer permanently + Prohibición permanente de Pares + + + + + Peer addition + Incorporar Par + + + + The peer was added to this torrent. + Los Pares se agregaron al torrent. + + + + The peer could not be added to this torrent. + Los Pares no se han podido agregar al torrent. + + + + Are you sure? -- qBittorrent + ¿Estás seguro? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + ¿Seguro que desea prohibirle la compartición permanente de Pares? + + + + &Yes + &Sí + + + + &No + &No + + + + Manually banning peer %1... + Prohibir manualmente los Pares %1... + + + + Upload rate limiting + Tasa Límite de Subida + + + + Download rate limiting + Tasa Límite de Bajada + + + + Preferences + + UI + User Interface + IU + + + + Downloads + Descargas + + + + Connection + Conexión + + + + Speed + Velocidad + + + + Web UI + IU Web + + + + Advanced + Avanzado + + + Language: + Idioma: + + + + (Requires restart) + (Es necesario reiniciar qBittorrent) + + + Visual style: + Estilo Visual: + + + Transfer list + Lista de Transferencia + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Usar colores alternos en la lista de Transferencia + + + + + Start / Stop Torrent + Iniciar / Parar Torrent + + + + + No action + Sin acción + + + File system + Opciones sobre archivos del Sistema + + + + Copy .torrent files to: + Copiar archivos .torrent en: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Los siguientes parámetros son compatibles: +<ul> +<li>%f: Torrent ruta</li> +<li>%n: Torrent nombre</li> +</ul> + + + + Listening Port + + + + + Connections Limits + + + + + Proxy Server + + + + + Enable bandwidth management (uTP) + + + + + Enable Peer Exchange (PeX) to find more peers + Habilitar intercambio de pares (PeX) para encontrar más pares + + + + Enable Local Peer Discovery to find more peers + Habilitar Hallado Local de Pares para encontrar más pares + + + + Encryption mode: + Modo de cifrado: + + + + Prefer encryption + Preferencia de cifrado + + + + Require encryption + Necesitan cifrado + + + + Disable encryption + Deshabilitar cifrado + + + Torrent queueing + Gestión de Colas + + + + Maximum active downloads: + Máximo de archivos Bajando: + + + + Maximum active uploads: + Máximo de archivos Subiendo: + + + + Maximum active torrents: + Máximo de archivos Torrents: + + + + When adding a torrent + Al añadir un torrent + + + + + Options + Opciones + + + User Interface + Interfaz de Usuario + + + Visual Appearance + Apariencia Visual + + + + Action on double-click + Acción a realizar con un doble-click + + + + Downloading torrents: + Torrents Descargando: + + + + + Open destination folder + Abrir carpeta de destino + + + + Completed torrents: + Torrents Completados: + + + + Desktop + Escritorio + + + + Show splash screen on start up + Mostrar pantalla de bienvenida al iniciar + + + + Start qBittorrent minimized + Iniciar qBittorrent minimizado + + + Show qBittorrent icon in notification area + Mostrar icono de qBittorrent en el area de notificación + + + Use monochrome system tray icon (requires restart) + Usar icono monocromático en la bandeja del sistema (es necesario reinicar) + + + + Minimize qBittorrent to notification area + Minimizar qBittorrent en el area de notificación + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + El icono de la bandeja del sistema seguirá siendo visible al cerrar la ventana principal. + Al cerrar qBittorrent dejadlo activo en el area de notificación + + + + Tray icon style: + + + + + Normal + Normal + + + + Monochrome (Dark theme) + + + + + Monochrome (Light theme) + + + + + Ask for program exit confirmation + Pedir confirmación para salir del programa + + + + User Interface Language: + + + + + Transfer List + + + + + Show qBittorrent in notification area + + + + + Power Management + Administración de energía + + + + Inhibit system sleep when torrents are active + Inhabilitar la suspensión del equipo cuando aún queden torrents activos + + + + Display torrent content and some options + Mostrar el contenido del Torrent y opciones + + + + Do not start the download automatically + The torrent will be added to download list in pause state + El torrente se añadirá a la lista de descargas de pausados + No iniciar las descargas de forma automática + + + + Hard Disk + + + + + Save files to location: + Guardar los archivos en su ubicación: + + + + Append the label of the torrent to the save path + Añadir la etiqueta del torrente a la ruta donde se guarda + + + + Pre-allocate disk space for all files + Pre-asignar espacio en el disco para todos los archivos + + + + Keep incomplete torrents in: + Mantener torrents incompletos en: + + + Append .!qB extension to incomplete files' names + Añadir la extensión .!qB a los nombres de los archivos incompletos + + + + Automatically add torrents from: + Cargar automáticamente archivos Torrents desde: + + + + Add folder... + Agregar carpeta... + + + + Email notification upon download completion + Notificarme por correo electrónico de la finalización de las descargas + + + + Destination email: + Dirección de correo electrónico: + + + + SMTP server: + Servidor SMTP: + + + + This server requires a secure connection (SSL) + + + + + Run an external program on torrent completion + Ejecutar un programa externo al completarse el torrent + + + + Otherwise, the proxy server is only used for tracker connections + + + + + Use proxy for peer connections + + + + + Global Rate Limits + + + + + Apply rate limit to uTP connections + + + + + Apply rate limit to transport overhead + + + + + Alternative Global Rate Limits + + + + + Schedule the use of alternative rate limits + + + + + Use HTTPS instead of HTTP + + + + + Import SSL Certificate + + + + + Import SSL Key + + + + + Certificate: + + + + + Key: + + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + Update my dynamic domain name + + + + + Service: + + + + + Register + + + + + Domain name: + + + + Use %f to pass the torrent path in parameters + Use % f para pasar al torrente la ruta de los parámetros + + + + Use UPnP / NAT-PMP port forwarding from my router + Usar UPnP / NAT-PMP reenvío de puertos del router + + + Proxy server + Servidor Proxy + + + + IP Filtering + filtrado IP + + + + Reload the filter + Actualizar el filtro + + + Schedule the use of alternative speed limits + Calendario para utilización de los límites de velocidad alternativa + + + + from + from (time1 to time2) + De x hora hasta x hora + a partir de + + + + When: + Cuándo: + + + + Privacy + Privacidad + + + + Enable DHT (decentralized network) to find more peers + Activar DHT (red descentralizada) para encontrar más pares + + + + Use a different port for DHT and BitTorrent + Usar difrente puerto para DHT y BitTorrent + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Intercambiar pares con clientes Bittorrent compatibles (µTorrent, Vuze, ...) + + + + Torrent Queueing + + + + + Share Ratio Limiting + + + + + Use UPnP / NAT-PMP to forward the port from my router + + + + + Bypass authentication for localhost + Eludir la autenticación para localhost + + + Protocol encryption: + Protocolo de encriptación: + + + Share ratio limiting + Límite ratio compartición + + + + Seed torrents until their ratio reaches + Ratio compartición de semillas Torrent + + + + then + luego + + + + Pause them + Pausar + + + + Remove them + Eliminar + + + + Enable Web User Interface (Remote control) + Habilitar interfaz Web de usuario (Control remoto) + + + Listening port + Puerto de escucha + + + + Port used for incoming connections: + Puerto utilizado para conexiones entrantes: + + + + Random + Aleatorio + + + Enable UPnP port mapping + Habilitar mapeo de puertos UPnP + + + Enable NAT-PMP port mapping + Habilitar mapeo de puertos NAT-PMP + + + Connections limit + Límite de conexiones + + + + Global maximum number of connections: + Número global máximo de conexiones: + + + + Maximum number of connections per torrent: + Número máximo de conexiones por torrent: + + + + Maximum number of upload slots per torrent: + Número máximo de slots de subida por torrent: + + + + + Upload: + Subida: + + + + + Download: + Bajada: + + + + + + + KiB/s + + + + + + Behavior + Comportamiento + + + + BitTorrent + Bittorrent + + + + Language + Idioma + + + Global speed limits + Límites de velocidad global + + + Alternative global speed limits + Límites de velocidad global alternativa + + + + to + time1 to time2 + a + + + + Every day + Todos + + + + Week days + Días laborales + + + + Week ends + Fines de Semana + + + Bittorrent features + Características de Bittorrent + + + Enable DHT network (decentralized) + Habilitar red DHT (descentralizada) + + + Use a different port for DHT and Bittorrent + Utilizar un puerto diferente para la DHT y Bittorrent + + + + DHT port: + Puerto DHT: + + + Enable Peer Exchange / PeX (requires restart) + Activar intercambio de Pares / PeX (es necesario reiniciar qBittorrent) + + + + Look for peers on your local network + Puede buscar pares en su Red local + + + Enable Local Peer Discovery + Habilitar la fuente de búsqueda local de Pares + + + Enabled + Habilitado + + + Forced + Forzado + + + Disabled + Deshabilitado + + + HTTP Communications (trackers, Web seeds, search engine) + Comunicaciones HTTP (Trackers, Semillas Web, Motores de búsqueda) + + + + Type: + Tipo: + + + + (None) + (Ninguno) + + + + HTTP + + + + + Host: + + + + + + Port: + Puerto: + + + + + + Authentication + Autentificación + + + + Append .!qB extension to incomplete files + + + + + + + + Username: + Nombre de Usuario: + + + + + + + Password: + Contraseña: + + + Peer Communications + Comunicaciones Pares + + + + SOCKS4 + + + + + SOCKS5 + + + + + Remove folder + Eliminar carpeta + + + + Filter path (.dat, .p2p, .p2b): + Ruta de Filtro (.dat, .p2p, .p2b): + + + HTTP Server + Servidor HTTP + + + + PreviewSelect + + + Name + Nombre + + + + Size + Tamaño + + + + Progress + Progreso + + + + + + Preview impossible + Imposible vista previa + + + + + + Sorry, we can't preview this file + Lo siento, no se puede realizar una vista previa de este archivo + + + + ProgramUpdater + + Could not create the file %1 + No se pudo crear el archivo %1 + + + Failed to download the update at %1 + %1 is an URL + Error al descargar la actualización %1 + + + + PropListDelegate + + + Not downloaded + No descargar + + + + + Normal + Normal (priority) + Normal + + + + + High + High (priority) + Alta + + + + Mixed + Mixed (priorities + Mixto + + + + + Maximum + Maximum (priority) + Máxima + + + + PropTabBar + + + General + General + + + + Trackers + Trackers + + + + Peers + Pares + + + + HTTP Sources + Fuentes HTTP + + + + Content + Contenido + + + URL Seeds + URL Semillas + + + Files + Archivos + + + + PropertiesWidget + + + Save path: + Directorio de destino: + + + + Torrent hash: + Hash de torrent: + + + + Comment: + Comentario: + + + + Share ratio: + Ratio de Compartición: + + + + + Downloaded: + Progreso: + + + + Availability: + Disponibilidad: + + + + Transfer + Transferencia + + + + Uploaded: + Subido: + + + + Wasted: + Perdido: + + + + Time active: + Time (duration) the torrent is active (not paused) + Tiempo activo: + + + + Pieces size: + Tamaño de las piezas: + + + + Torrent content: + Contenido del torrent: + + + + Select All + Seleccionar Todo + + + + Select None + Quitar Selecciones + + + + + Do not download + No descargar + + + + UP limit: + Límite Subida: + + + + DL limit: + Límite Bajada: + + + Time elapsed: + Tiempo transcurrido: + + + + Connections: + Número Conexiones: + + + + Reannounce in: + Republicar en: + + + + Information + Información + + + + Created on: + Fecha de creación: + + + General + General + + + Trackers + Trackers + + + Peers + Pares + + + URL seeds + URL Semillas + + + Files + Archivos + + + + Priority + Prioridad + + + + Normal + Normal + + + + Maximum + Máxima + + + + High + Alta + + + + + this session + en esta sesión + + + + + /s + /second (i.e. per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + Semillas por %1 + + + + %1 max + e.g. 10 max + + + + + + I/O Error + Error de Entrada/Salida + + + + This file does not exist yet. + Ese archivo todavía no existe. + + + + This folder does not exist yet. + Ese archivo todavía no existe. + + + + Rename... + Renombrar... + + + + Rename the file + Renombrar archivo + + + + New name: + Nuevo nombre: + + + + + The file could not be renamed + No se puede cambiar el nombre de archivo + + + + This file name contains forbidden characters, please choose a different one. + El nombre introducido contiene caracteres prohibidos, por favor elija otro. + + + + + This name is already in use in this folder. Please use a different name. + Este nombre ya está en uso. Por favor, use un nombre diferente. + + + + The folder could not be renamed + No se puede cambiar el nombre de archivo + + + + New url seed + New HTTP source + Nueva semilla url + + + + New url seed: + Nueva semilla url: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Esta semilla url ya está en la lista. + + + + + Choose save path + Seleccione un directorio de destino + + + Save path creation error + Error en la creación del directorio de destino + + + Could not create the save path + No se pudo crear el directorio de destino + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 alcanzó el ratio máximo establecido. + + + + Removing torrent %1... + Extrayendo torrent %1... + + + + Pausing torrent %1... + Torrent Pausado %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent está usando el puerto: TCP/%1 + + + UPnP support [ON] + Soporte para UPnP [Encendido] + + + UPnP support [OFF] + Soporte para UPnP [Apagado] + + + NAT-PMP support [ON] + Soporte para NAT-PMP [Encendido] + + + NAT-PMP support [OFF] + Soporte para NAT-PMP[Apagado] + + + + HTTP user agent is %1 + HTTP de usuario es %1 + + + Using a disk cache size of %1 MiB + Tamaño cache del Disco %1 MiB + + + + DHT support [ON], port: UDP/%1 + Soporte para DHT [Encendido], puerto: UPD/%1 + + + + + DHT support [OFF] + Soporte para DHT [Apagado] + + + + PeX support [ON] + Soporte para PeX [Encendido] + + + + PeX support [OFF] + Soporte PeX [Apagado] + + + + Restart is required to toggle PeX support + Es necesario reiniciar para activar el soporte PeX + + + Local Peer Discovery [ON] + Estado local de Pares [Encendido] + + + + Local Peer Discovery support [OFF] + Soporte para estado local de Pares [Apagado] + + + + Encryption support [ON] + Soporte para encriptado [Encendido] + + + + Encryption support [FORCED] + Soporte para encriptado [Forzado] + + + + Encryption support [OFF] + Sopote para encriptado [Apagado] + + + + Embedded Tracker [ON] + Integrador de Tracker [Encendido] + + + + Failed to start the embedded tracker! + Error al iniciar el integrado de Tracker! + + + + Embedded Tracker [OFF] + Integrador de Tracker [Apagado] + + + + The Web UI is listening on port %1 + Puerto de escucha de Interfaz Usuario Web %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Error interfaz de Usuario Web - No se puede enlazar al puerto %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' Fue eliminado de la lista de transferencia y del disco. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' Fue eliminado de la lista de transferencia. + + + + '%1' is not a valid magnet URI. + '%1' no es una URI válida. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' ya está en la lista de descargas. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' reiniciado. (reinicio rápido) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' agregado a la lista de descargas. + + + + UPnP / NAT-PMP support [ON] + Soporte UPnP / NAT-PMP [ON] + + + + UPnP / NAT-PMP support [OFF] + Soporte UPnP / NAT-PMP [OFF] + + + + Reporting IP address %1 to trackers... + Dirección IP de infomes %1 de trackers... + + + + Local Peer Discovery support [ON] + Soporte Hallado Local de Pares [ON] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Imposible decodificar el archivo torrent: '%1' + + + + This file is either corrupted or this isn't a torrent. + Este archivo puede estar corrupto, o no ser un torrent. + + + + Error: The torrent %1 does not contain any file. + Error: este torrent %1 no contiene ningún archivo. + + + + Note: new trackers were added to the existing torrent. + Nota: nuevos Trackers se han añadido al torrent existente. + + + + Note: new URL seeds were added to the existing torrent. + Nota: nuevas semillas URL se han añadido al Torrent existente. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>fue bloqueado debido al filtro IP</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>Fue bloqueado debido a fragmentos corruptos</i> + + + + The network interface defined is invalid: %1 + La interfaz de la red definida no es válida: %1 + + + + Trying any other network interface available instead. + Tratando cualquier interfaz de red disponibles en su lugar. + + + + Listening on IP address %1 on network interface %2... + Escuchando la dirección IP %1 de la interfaz de red %2... + + + + Failed to listen on network interface %1 + No se ha podido escuchar la interfaz de red %1 + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Descarga recursiva de archivo %1 inscrustada en Torrent %2 + + + + + Unable to decode %1 torrent file. + No se puede descodificar %1 archivo torrent. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + El equipo entrará en 15 segundos en estado de suspensión, a menos que lo cancele... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + El equipo se apagará en 15 segundos, a menos que lo cancele... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent será cerrado en 15 segundos, a menos que lo cancele... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Análisis exitoso de filtrado IP: %1 normas aplicadas. + + + + Error: Failed to parse the provided IP filter. + Error: Falló el análisis de filtrado IP. + + + + Torrent name: %1 + Nombre del torrent: %1 + + + + Torrent size: %1 + Tamaño del torrent: %1 + + + + Save path: %1 + Guardar ruta: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + El torrernt se descargó en %1. + + + + Thank you for using qBittorrent. + Gracias por utilizar qBittorrent. + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 ha finalizado la descarga + + + + An I/O error occured, '%1' paused. + Error de E/S ocurrido, '%1' pausado. + + + + + Reason: %1 + Razón: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Falló el mapeo del puerto, mensaje: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Mapeo del puerto exitoso, mensaje: %1 + + + + File sizes mismatch for torrent %1, pausing it. + El tamaño de archivo no coincide con el torrent %1, pausandolo. + + + + Fast resume data was rejected for torrent %1, checking again... + Se negaron los datos para reinicio rápido del torrent: %1, verificando de nuevo... + + + + Url seed lookup failed for url: %1, message: %2 + Falló la búsqueda de semilla por Url para la Url: %1, mensaje: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Descargando '%1', por favor espere... + + + + RSS + + + Search + Buscar + + + + New subscription + Nueva suscripción + + + + + + Mark items read + Marcar para leer + + + + Update all + Actualizar todo + + + + RSS Downloader... + Descargar RSS... + + + + Settings... + Configuración... + + + Feed URL + Canal URL + + + + Rename... + Renombrar... + + + + + Update + Actualizar + + + RSS feed downloader... + Descargar Canal RSS... + + + + New folder... + Nueva carpeta... + + + + Manage cookies... + Administrar Cookies... + + + RSS feeds + Canales RSS + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(doble-click para iniciar la descarga)</span></p></body></html> + + + Article title + Título del artículo + + + + New subscription... + Nueva suscripción... + + + + + Update all feeds + Actualizar todos los Canales + + + + + Delete + Borrar + + + + Rename + Renombrar + + + + Download torrent + descargar torrent + + + + Open news URL + Abrir nueva URL + + + + Copy feed URL + Copiar Canal URL + + + + Refresh RSS streams + Actualizar los Canales RSS + + + + RSSImp + + + Please type a rss stream url + Por favor escribe una URL de un Canal RSS + + + + Stream URL: + URL del Canal: + + + + + Are you sure? -- qBittorrent + ¿Estás seguro? -- qBittorrent + + + + + &Yes + &Sí + + + + + &No + &No + + + + Please choose a folder name + Por favor elija un nombre para la carpeta + + + + Folder name: + Nombre de la carpeta: + + + + New folder + Nueva carpeta + + + + Overwrite attempt + Intentando sobrescribir + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Imposible sobrescribir %1 sector. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Esta fuente de RSS ya está en la lista. + + + + Are you sure you want to delete these elements from the list? + ¿Seguro que quiere eliminar estos elementos de la lista? + + + + Are you sure you want to delete this element from the list? + ¿Seguro que desea eliminar este elemento de la lista? + + + + Please choose a new name for this RSS feed + Por favor, elija un nuevo nombre para el Canal RSS + + + + New feed name: + Nombre del nuevo Canal: + + + + Name already in use + Ese nombre ya se encuentra en uso + + + + This name is already used by another item, please choose another one. + Ese nombre ya se está usando, por favor, elija otro. + + + + Date: + Fecha: + + + + Author: + Autor: + + + + Unread + No leídos + + + + RssArticle + + No description available + Sin descripción disponible + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Descargar automática %1 Torrent %2 Canal RSS... + + + + RssItem + + No description available + Sin descripción disponible + + + + RssSettings + + RSS Reader Settings + Ajustaments Lector RSS + Ajustes Lector RSS + + + RSS feeds refresh interval: + Intervalo de actualización de Canales RSS: + + + minutes + minutos + + + Maximum number of articles per feed: + Número máximo de artículos por Canal: + + + + RssSettingsDlg + + + RSS Reader Settings + Ajustes Lector RSS + + + + RSS feeds refresh interval: + Intervalo de actualización de Canales RSS: + + + + minutes + minutos + + + + Maximum number of articles per feed: + Número máximo de artículos por Canal: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Descargar automática %1 Torrent %2 Canal RSS... + + + + ScanFoldersModel + + + Watched Folder + Buscar ficheros .torrents + + + + Download here + Descargar Torrents aquí + + + + SearchCategories + + + All categories + Todas las categorías + + + + Movies + Vídeos + + + + TV shows + Programas TV + + + + Music + Música + + + + Games + Juegos + + + + Anime + + + + + Software + Programas Pc + + + + Pictures + Imágenes + + + + Books + Libros + + + + SearchEngine + + + Empty search pattern + Patrón de búsqueda vacío + + + + Please type a search pattern first + Por favor escriba primero un patrón de búsqueda + + + + + Results + Resultados + + + + Searching... + Buscando... + + + + Cut + Cortar + + + + Copy + Copiar + + + + Paste + Pegar + + + + Clear field + Eliminar de la lista + + + + Clear completion history + Limpiar historial de búsquedas + + + + Confirmation + Confirmación + + + + Are you sure you want to clear the history? + ¿Estás seguro que desea borrar el historial? + + + + + + Search + Buscar + + + + Missing Python Interpreter + Falta intérprete de Python + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x es necesario para utilizar el motor de búsqueda pero no parece que esté instalado. +¿Desea instalarlo ahora? + + + + Search Engine + Motor de Búsqueda + + + + + Search has finished + Búsqueda terminada + + + + An error occured during search... + Ocurrió un error durante la búsqueda... + + + + + Search aborted + Búsqueda abortada + + + + Download error + Error de descarga + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + La instalación de Python no se pudo realizar, la razón: %1. +Por favor, instálelo de forma manual. + + + + Search returned no results + La búsqueda no devolvió resultados + + + + Results + i.e: Search results + Resultados + + + + + Unknown + Desconocido + + + + SearchTab + + + Name + i.e: file name + Nombre + + + + Size + i.e: file size + Tamaño + + + + Seeders + i.e: Number of full sources + Semillas + + + + Leechers + i.e: Number of partial sources + Leechers + + + + Search engine + Motor de búsqueda + + + + ShutdownConfirmDlg + + + Shutdown confirmation + Cerrar confirmación + + + + SpeedLimitDialog + + + KiB/s + KiB/s + + + + StatusBar + + + + Connection status: + Estado de la conexión: + + + + + No direct connections. This may indicate network configuration problems. + No hay conexiones directas. Esto puede indicar problemas en la configuración de red. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + Bajada: %1 B/s - Total: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + Subida: %1 B/s - Total: %2 + + + + + DHT: %1 nodes + DHT: %1 nodos + + + + qBittorrent needs to be restarted + Es necesario reiniciar qBittorrent + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent a sido actualizado y debe ser reiniciado para que los cambios sean efectivos. + + + + + Connection Status: + Estado de la conexión: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Fuera de línea. Esto normalmente significa que qBittorrent no puede escuchar el puerto seleccionado para las conexiones entrantes. + + + + Online + En línea + + + + + %1/s + Per second + %1/s + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Bajada: %1/s - Total: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Subida: %1/s - Total: %2 + + + + Click to switch to alternative speed limits + Clique para cambiar a los límites de velocidad alternativa + + + + Click to switch to regular speed limits + Clique para cambiar a los límites de velocidad normal + + + Click to disable alternative speed limits + Click para desactivar los límites de velocidad alternativa + + + Click to enable alternative speed limits + Click para activar los límites de velocidad alternativa + + + + Global Download Speed Limit + Velocidad límite global de descarga + + + + Global Upload Speed Limit + Velocidad límite global de subida + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Seleccione otra carpeta para agregar el torrent + + + + Select a file to add to the torrent + Seleccione otro archivo para agregar el torrent + + + Please type an announce URL + Por favor escribe una Dirección URL + + + Announce URL: + Tracker URL + Dirección URL: + + + Please type a web seed url + Por favor escribe una Dirección Web para la Semilla + + + Web seed URL: + Dirección Web de la Semilla: + + + + No input path set + Sin ruta de destino establecida + + + + Please type an input path first + Por favor escriba primero una ruta de entrada + + + + Select destination torrent file + Seleccione un destino para el archivo torrent + + + + Torrent Files + Archivos Torrent + + + + + + Torrent creation + Crear nuevo Torrent + + + + Torrent creation was unsuccessful, reason: %1 + La creación del torrent no ha sido exitosa, razón: %1 + + + + Created torrent file is invalid. It won't be added to download list. + La creación del archivo torrent no es válida. No se añadirá a la lista de descargas. + + + + Torrent was created successfully: + El Torrent se creó con éxito: + + + + TorrentFilesModel + + + Name + Nombre + + + + Size + Tamaño + + + + Progress + Progreso + + + + Priority + Prioridad + + + + TorrentImportDlg + + + Torrent Import + Importar Torrent + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Este asistente le ayudará a compartir con qBittorrent, un torrente ya descargado. + + + + Torrent file to import: + Archivo Torrent para importar: + + + + + ... + ... + + + + Content location: + Ubicación del contenido: + + + + Skip the data checking stage and start seeding immediately + Saltarse la fase de control de datos y empezar a sembrar de inmediato + + + + Import + Importar + + + + Torrent file to import + Archivo Torrent para importar + + + + Torrent files (*.torrent) + Archivos Torrent (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 Archivos + + + + Please provide the location of %1 + %1 is a file name + Por favor, indique la ubicación del %1 + + + + Please point to the location of the torrent: %1 + Por favor, elija la ubicación del torrent: %1 + + + + Invalid torrent file + Archivo torrent no válido + + + + This is not a valid torrent file. + Esto no es un archivo torrent válido. + + + + TorrentModel + + + Name + i.e: torrent name + Nombre + + + + Size + i.e: torrent size + Tamaño + + + + Done + % Done + Progreso + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Estado + + + + Seeds + i.e. full sources (often untranslated) + Semillas + + + + Peers + i.e. partial sources (often untranslated) + Pares + + + + Down Speed + i.e: Download speed + Vel. Bajada + + + + Up Speed + i.e: Upload speed + Vel. Subida + + + + Ratio + Share ratio + Ratio + + + + ETA + i.e: Estimated Time of Arrival / Time left + Tiemp aprox + + + + Label + Etiqueta + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Añadido el + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Completado el + + + + Tracker + Tracker + + + + Down Limit + i.e: Download limit + Límite Bajada + + + + Up Limit + i.e: Upload limit + Límite Subida + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Cantidad descargada + + + + Amount left + Amount of data left to download (e.g. in MB) + Cantidad que falta + + + + Time Active + Time (duration) the torrent is active (not paused) + Tiempo activo + + + + TrackerList + + + URL + + + + + Status + Estado + + + + Peers + Pares + + + + Message + Mensaje + + + + [DHT] + + + + + [PeX] + + + + + [LSD] + + + + + + + + + Working + Trabajando + + + + + + Disabled + Deshabilitado + + + + This torrent is private + Este torrent es privado + + + + Updating... + Actualizando... + + + + + Not working + Parado + + + + + Not contacted yet + Todavía sin conexión + + + + Add a new tracker... + Añadir nuevo tracker... + + + + Remove tracker + Eliminar tracker + + + + Force reannounce + Forzar Re-publicar + + + + TrackersAdditionDlg + + + Trackers addition dialog + Diálogo para añadir trackers + + + + List of trackers to add (one per line): + Lista de trackers a añadir (uno por línea): + + + + µTorrent compatible list URL: + Lista de URL de μTorrent compatibles: + + + + I/O Error + Error de Entrada/Salida + + + + Error while trying to open the downloaded file. + Error al intentar abrir el archivo descargado. + + + + No change + Sin cambios + + + + No additional trackers were found. + No se encontró ningún Tracker. + + + + Download error + Error de descarga + + + + The trackers list could not be downloaded, reason: %1 + La lista de Trackers no pudo ser descargada. Razón: %1 + + + + TransferListDelegate + + + Downloading + Descargando + + + + Paused + Pausar + + + + Queued + i.e. torrent is queued + En cola + + + + Seeding + Torrent is complete and in upload-only mode + Sembrando + + + + Stalled + Torrent is waiting for download to begin + Detenida + + + + Checking + Torrent local data is being checked + Verificando + + + + /s + /second (.i.e per second) + + + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Sembrando %1 + + + + TransferListFiltersWidget + + + + All + Todos + + + + + Downloading + Descargando + + + + + Completed + Completados + + + + + Paused + Pausados + + + + + Active + Activos + + + + + Inactive + Inactivos + + + + + All labels + Etiquetados + + + + + Unlabeled + No Etiquetados + + + + Remove label + Eliminar Etiqueta + + + + Add label... + Añadir Etiqueta... + + + + Resume torrents + Reanudar torrents + + + + Pause torrents + Pausar torrents + + + + Delete torrents + Eliminar torrents + + + + New Label + Nueva Etiqueta + + + + Label: + Etiqueta: + + + + Invalid label name + Nombre de Etiqueta no válido + + + + Please don't use any special characters in the label name. + Por favor, no utilice caracteres especiales para el nombre de la Etiqueta. + + + + TransferListWidget + + Down Speed + i.e: Download speed + Vel. Bajada + + + Up Speed + i.e: Upload speed + Vel. Subida + + + ETA + i.e: Estimated Time of Arrival / Time left + Tiemp aprox + + + + Column visibility + Visibilidad de columnas + + + Name + i.e: torrent name + Nombre + + + Size + i.e: torrent size + Tamaño + + + Done + % Done + Progreso + + + Status + Torrent status (e.g. downloading, seeding, paused) + Estado + + + Seeds + i.e. full sources (often untranslated) + Semillas + + + Peers + i.e. partial sources (often untranslated) + Pares + + + Ratio + Share ratio + Ratio + + + + Label + Etiqueta + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Añadido el + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Completado el + + + Tracker + Tracker + + + Down Limit + i.e: Download limit + Límite Bajada + + + Up Limit + i.e: Upload limit + Límite Subida + + + + Choose save path + Seleccione un directorio de destino + + + Save path creation error + Error en la creación del directorio de destino + + + Could not create the save path + No se pudo crear el directorio de destino + + + + Torrent Download Speed Limiting + Límite de velocidad de Bajada Torrent + + + + Torrent Upload Speed Limiting + Límite de velocidad de Subida Torrent + + + + New Label + Nueva Etiqueta + + + + Label: + Etiqueta: + + + + Invalid label name + Nombre de Etiqueta no válido + + + + Please don't use any special characters in the label name. + Por favor, no utilice caracteres especiales para el nombre de la Etiqueta. + + + + Rename + Renombrar + + + + New name: + Nuevo nombre: + + + + Resume + Resume/start the torrent + Reanudar + + + + Pause + Pause the torrent + Pausar + + + + Delete + Delete the torrent + Borrar + + + + Preview file... + Previsualizar archivo... + + + + Limit share ratio... + Límite ratio compartición... + + + + Limit upload rate... + Tasa límite de Subida... + + + + Limit download rate... + Tasa límite de Bajada... + + + + Priority + Prioridad + + + + Open destination folder + Abrir carpeta de destino + + + + Move up + i.e. move up in the queue + Mover arriba + + + + Move down + i.e. Move down in the queue + Mover abajo + + + + Move to top + i.e. Move to top of the queue + Mover al principio + + + + Move to bottom + i.e. Move to bottom of the queue + Mover al final + + + + Set location... + Establecer destino... + + + + Force recheck + Forzar verificación de archivo + + + + Copy magnet link + Copiar magnet link + + + + Super seeding mode + Modo de SuperSiembra + + + + Rename... + Renombrar... + + + + Download in sequential order + Descargar en orden secuencial + + + + Download first and last piece first + Descargar primero, primeras y últimas partes + + + + New... + New label... + Nueva... + + + + Reset + Reset label + Borrar todas las Etiquetas + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Límites de ratio de Subida/Bajada + + + + Use global ratio limit + Usar límite de ratio global + + + + + + buttonGroup + buttonGroup + + + + Set no ratio limit + Sin límites de ratio + + + + Set ratio limit to + Límitar ratio a + + + + UsageDisplay + + + Usage: + Uso: + + + + displays program version + Muestra la versión del programa + + + + disable splash screen + Desactivar pantalla de inicio + + + + displays this help message + Muestra mensaje de ayuda + + + + changes the webui port (current: %1) + Cambiar el puerto de IU Web (actual:%1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [archivos o URLs] : la descarga de torrents necesita aprobación por el usuario (opcional) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Quiero agradecer a las siguientes personas que voluntariamente tradujeron qBittorrent: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Por favor contáctame si quieres traducir qBittorrent a tu propio idioma. + + + + addPeerDialog + + + Peer addition + Incorporar Par + + + + IP + + + + + Port + Puerto + + + + addTorrentDialog + + + Torrent addition dialog + Diálogo para añadir un torrent + + + + Save path: + Directorio de destino: + + + + ... + ... + + + + Torrent size: + Tamaño torrent: + + + + + Unknown + Desconocido + + + + Free disk space: + Espacio libre en el Disco: + + + + Label: + Etiqueta: + + + + Torrent content: + Contenido del torrent: + + + + Select All + Seleccionar Todo + + + + Select None + Quitar Selecciones + + + + Download in sequential order (slower but good for previewing) + Descargar en orden secuencial (más lento, pero mejor para la vista previa) + + + + Skip file checking and start seeding immediately + Anular verificación y empezar a sembrar de inmediato + + + + + Do not download + No descargar + + + + Add to download list in paused state + Agregar a la lista de descargas en estado pausado + + + + Add + Agregar + + + + Cancel + Cancelar + + + + Normal + Normal + + + + High + Alta + + + + Maximum + Máxima + + + + authentication + + + + Tracker authentication + Autentificación del Tracker + + + + Tracker: + Tracker: + + + + Login + Autentificarse + + + + Username: + Usuario: + + + + Password: + Contraseña: + + + + Log in + Conectar + + + + Cancel + Cancelar + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Confirmar borrado - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + ¿Seguro que quiere eliminar los torrents seleccionados de la lista de transferencias? + + + + Remember choice + Recordar siempre esta elección + + + + Also delete the files on the hard disk + Eliminar también el archivo del disco físico + + + + createTorrentDialog + + + Cancel + Cancelar + + + + Torrent Creation Tool + Herramienta de Creación de Torrent + + + + Torrent file creation + Creación de un nuevo archivo Torrent + + + Announce urls (trackers): + Dirección Trackers: + + + Comment (optional): + Comentario (opcional): + + + Web seeds urls (optional): + Dirección Semillas (opcional): + + + + File or folder to add to the torrent: + Archivo o carpeta a agregar al torrent: + + + + Add file + Nuevo archivo + + + + Add folder + Nueva carpeta + + + + Tracker URLs: + Tracker URLs: + + + + Web seeds urls: + Semillas web urls: + + + + Comment: + Comentario: + + + + Piece size: + Tamaño de la pieza: + + + + 32 KiB + 32 KiB + + + + 64 KiB + 64 KiB + + + + 128 KiB + 128 KiB + + + + 256 KiB + 256 KiB + + + + 512 KiB + 512 KiB + + + + 1 MiB + 1 MiB + + + + 2 MiB + 2 MiB + + + + 4 MiB + 4 MiB + + + + Auto + Auto + + + + Private (won't be distributed on DHT network if enabled) + Privado (no se distribuirá por red DHT si se habilita) + + + + Start seeding after creation + Comenzar con la siembra después de la creación + + + + Create and save... + Crear y guardar... + + + + Progress: + Progreso: + + + + createtorrent + + Select destination torrent file + Seleccione un destino para el archivo torrent + + + Torrent Files + Archivos Torrent + + + No input path set + Sin ruta de destino establecida + + + Please type an input path first + Por favor escribe primero una ruta de entrada + + + Torrent creation + Crear nuevo Torrent + + + Torrent was created successfully: + El Torrent se creó con éxito: + + + Select a folder to add to the torrent + Seleccione otra carpeta para agregar al torrent + + + Please type an announce URL + Por favor escribe una Dirección URL + + + Torrent creation was unsuccessful, reason: %1 + La creación del torrent no ha sido exitosa, razón: %1 + + + Announce URL: + Tracker URL + Dirección URL: + + + Please type a web seed url + Por favor escribe una Dirección Web para la Semilla + + + Web seed URL: + Dirección Web de la Semilla: + + + Select a file to add to the torrent + Seleccione otro archivo para agregar al torrent + + + Created torrent file is invalid. It won't be added to download list. + La creación del archivo torrent no es válida. No se añadirá a la lista de descargas. + + + + downloadFromURL + + Download Torrents from URLs + Descargar torrents de URLs + + + Only one URL per line + Solo una URL por línea + + + + Add torrent links + Añadir enlace torrent + + + + Both HTTP and Magnet links are supported + Los dos HTTP y Magnet links son soportados + + + + Download + Descargar + + + + Cancel + Cancelar + + + + Download from urls + Descargar de urls + + + + No URL entered + No se ha escrito ninguna URL + + + + Please type at least one URL. + Por favor escribe al menos una URL. + + + + downloadThread + + I/O Error + Error de Entrada/Salida + + + The remote host name was not found (invalid hostname) + El nombre de host remoto no se ha encontrado (nombre de host no válido) + + + The operation was canceled + La operación fue cancelada + + + The remote server closed the connection prematurely, before the entire reply was received and processed + El servidor remoto cerró la conexión antes de tiempo, antes que fuese recibido y procesado + + + The connection to the remote server timed out + Conexión con el servidor remoto fallida, Tiempo de espera agotado + + + SSL/TLS handshake failed + SSL/TLS handshake fallida + + + The remote server refused the connection + El servidor remoto rechazó la conexión + + + The connection to the proxy server was refused + La conexión con el servidor proxy fue rechazada + + + The proxy server closed the connection prematurely + Conexión cerrada antes de tiempo por el servidor proxy + + + The proxy host name was not found + El nombre de host del proxy no se ha encontrado + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + La conexión con el servidor proxy se ha agotado, o el proxy no respondió a tiempo a la solicitud enviada + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + El proxy requiere autenticación con el fin de atender la solicitud, pero no aceptó las credenciales que ofreció + + + The access to the remote content was denied (401) + El acceso al contenido remoto ha sido rechazado (401) + + + The operation requested on the remote content is not permitted + La operación solicitada en el contenido remoto no está permitida + + + The remote content was not found at the server (404) + El contenido remoto no se encuentra en el servidor (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + El servidor remoto requiere autenticación para servir el contenido, pero las credenciales proporcionadas no son correctas + + + The Network Access API cannot honor the request because the protocol is not known + Protocolo desconocido + + + The requested operation is invalid for this protocol + La operación solicitada no es válida para este protocolo + + + An unknown network-related error was detected + Error de Red desconocido + + + An unknown proxy-related error was detected + Error de Proxy desconocido + + + An unknown error related to the remote content was detected + Error desconocido en el servidor remoto + + + A breakdown in protocol was detected + Error de protocolo + + + Unknown error + Error desconocido + + + + engineSelect + + + Search plugins + Buscar plugins + + + + Installed search engines: + Motores de búsqueda instalados: + + + + Name + Nombre + + + + Url + Url + + + + + Enabled + Habilitado + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Puedes obtener nuevos plugins de motores de búsqueda aquí <a href="http:plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Instalar uno nuevo + + + + Check for updates + Buscar actualizaciones + + + + Close + Cerrar + + + Enable + Habilitar + + + Disable + Deshabilitar + + + + Uninstall + Desinstalar + + + + engineSelectDlg + + + Uninstall warning + Alerta de desinstalación + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Algunos plugins no pudieron ser instalados porque están incluídos en qBittorrent. +Solamente los que has agregado por tí mismo pueden ser desinstalados. +De cualquier forma, esos plugins fueron deshabilitados. + + + + Uninstall success + Desinstalación correcta + + + + Select search plugins + Seleccione los plugins de búsqueda + + + + qBittorrent search plugins + Plugins de búsqueda de qBittorrent + + + + + + + + Search plugin install + Instalar plugin de búsqueda + + + + + + Yes + + + + + + + + No + No + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Una versión más reciente del plugin de motor de búsqueda %1 ya está instalada. + + + + + + + Search plugin update + Actualización del plugin de búsqueda + + + + + Sorry, update server is temporarily unavailable. + Lo siento, el servidor de actualización esta temporalmente no disponible. + + + + All your plugins are already up to date. + Todos tus plugins ya están actualizados. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + El plugin de motor de búsqueda %1 no pudo ser actualizado, se mantendrá la versión antigua. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + El plugin de motor de búsqueda %1 no pudo ser instalado. + + + + All selected plugins were uninstalled successfully + Todos los plugins seleccionados fueron instalados exitosamente + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + El plugin de motor de búsqueda %1 fue actualizado exitosamente. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + El plugin de motor de búsqueda %1 fue instalado exitosamente. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Lo lamento, la instalación del plugin de búsqueda %1 ha fallado. + + + + New search engine plugin URL + URL del nuevo plugin de motor de búsqueda + + + + URL: + URL: + + + + misc + + + qBittorrent will shutdown the computer now because all downloads are complete. + Todas las descargas se han completado, qBittorrent apagará el equipo ahora. + + + + B + bytes + B + + + + KiB + kibibytes (1024 bytes) + KiB + + + + MiB + mebibytes (1024 kibibytes) + MiB + + + + GiB + gibibytes (1024 mibibytes) + GiB + + + + TiB + tebibytes (1024 gibibytes) + TiB + + + + %1h %2m + e.g: 3hours 5minutes + + + + + %1d %2h + e.g: 2days 10hours + + + + + + + + + + Unknown + Desconocido + + + + Unknown + Unknown (size) + Desconocido + + + + < 1m + < 1 minute + <1m + + + + %1m + e.g: 10minutes + %1m + + + + options_imp + + + + + + Choose a save directory + Seleccione un directorio para guardar + + + + Add directory to scan + Añadir directorio para escanear + + + + Folder is already being watched. + Esta carpeta ya está en seleccionada para escanear. + + + + Folder does not exist. + La carpeta no existe. + + + + Folder is not readable. + La carpeta no es legible. + + + + Failure + Error + + + + Failed to add Scan Folder '%1': %2 + No se puede escanear esta carpetas '%1': %2 + + + + + Choose export directory + Selecciona directorio de exportación + + + + + Choose an ip filter file + Seleccione un archivo de filtro de ip + + + + + Filters + Filtros + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + Error de análisis + + + + Failed to parse the provided IP filter + No se ha podido analizar el filtrado IP + + + + Successfully refreshed + Actualizado con éxito + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + Succesfully refreshed + Actualizado con éxito + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Análisis exitoso de filtrado IP: %1 normas aplicadas. + + + + pluginSourceDlg + + + Plugin source + Fuente del plugin + + + + Search plugin source: + Fuente del plugin de búsqueda: + + + + Local file + Archivo local + + + + Web link + Vínculo web + + + + preview + + + Preview selection + Selección de vista previa + + + + File preview + Vista previa de archivo + + + + The following files support previewing, <br>please select one of them: + Los siguientes archivos soportan vista previa, <br>por favor seleccione uno de ellos: + + + + Preview + Vista previa + + + + Cancel + Cancelar + + + + previewSelect + + Preview impossible + Imposible vista previa + + + Sorry, we can't preview this file + Lo siento, no se puede realizar una vista previa de este archivo + + + Name + Nombre + + + Size + Tamaño + + + Progress + Progreso + + + + search_engine + + + + Search + Buscar + + + + Status: + Estado: + + + + Stopped + Detenido + + + + Download + Descargar + + + + Go to description page + Página de descripción + + + + Search engines... + Motores de búsqueda... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + Imposible decodificar el archivo torrent: + + + + + + Choose save path + Elegir directorio de destino + + + + Unable to decode magnet link: + No se puede descodificar el enlace magnet: + + + + Magnet Link + Enlace magnet + + + + Rename... + Renombrar... + + + + Rename the file + Renombrar archivo + + + + New name: + Nuevo nombre: + + + + + The file could not be renamed + No se puede cambiar el nombre de archivo + + + + This file name contains forbidden characters, please choose a different one. + Este nombre de archivo contiene caracteres prohibidos, por favor, elija uno otro. + + + + + This name is already in use in this folder. Please use a different name. + Este nombre ya está en uso. Por favor, use un nombre diferente. + + + + The folder could not be renamed + No se puede cambiar el nombre de archivo + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 disponible después de descargar el torrent) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (Se necesitan más %1) + + + + Empty save path + Ruta de destino vacía + + + + Please enter a save path + Por favor introduzca un directorio de destino + + + + Save path creation error + Error en la creación del directorio de destino + + + + Could not create the save path + Imposible crear el directorio de destino + + + + Invalid label name + Nombre de Etiqueta no válido + + + + Please don't use any special characters in the label name. + Por favor, no utilice caracteres especiales para el nombre de la Etiqueta. + + + + Seeding mode error + Error en la Siembra + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Usted ha decidido ignorar la verificación de archivos. Sin embargo, los archivos locales no parecen existir en la carpeta destino actual. Por favor, desactive esta función o actualice la ruta de destino. + + + + Invalid file selection + Selección de archivo inválida + + + + You must select at least one file in the torrent + Debe seleccionar al menos un archivo torrent + + + + Priority + Prioridad + + + diff --git a/src/lang/qbittorrent_fi.qm b/src/lang/qbittorrent_fi.qm new file mode 100644 index 0000000000000000000000000000000000000000..8825892dd6d3f258e3c5f34d0b383b3deb4930f1 GIT binary patch literal 79692 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 u^>>5LQ~`l|ntu_|GCYbBI@g + + + + AboutDlg + + + About + Yleistä + + + + About qBittorrent + Tietoja qBittorrentista + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + + Author + Kehittäjä + + + + chris@qbittorrent.org + chris@qbittorrent.org + + + + Christophe Dumez + Christophe Dumez + + + + Country: + Maa: + + + + E-mail: + Sähköposti: + + + + France + Ranska + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + + License + Lisenssi + + + + Name: + Nimi: + + + + Translation + Käännökset + + + + Thanks to + Kiitokset + + + + AdvancedSettings + + Property + Ominaisuus + + + Value + Arvo + + + + Disk write cache size + Levykirjoituksen välimuistin koko + + + + MiB + MiB + + + + Outgoing ports (Min) [0: Disabled] + Uloslähtevät portit (minimi) [0: ei käytössä] + + + + Outgoing ports (Max) [0: Disabled] + Uloslähtevät portit (maksimi) [0: ei käytössä] + + + + Recheck torrents on completion + Tarkista torrentit uudelleen niiden valmistuttua + + + + Transfer list refresh interval + Siirtolistan päivitystiheys + + + + ms + milliseconds + ms + + + + Setting + + + + + Value + Value set for this setting + Arvo + + + + Resolve peer countries (GeoIP) + Selvitä asiakkaiden kotimaat (GeoIP) + + + + Resolve peer host names + Selvitä asiakkaiden palvelinnimet + + + + Maximum number of half-open connections [0: Disabled] + Puoliavointen yhteyksien enimmäismäärä [0: ei käytössä] + + + + Strict super seeding + Tiukka super seed + + + + Network Interface (requires restart) + Verkkoliitäntä (vaatii uudelleenkäynnistyksen) + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + Mikä tahansa liitäntä + + + + IP Address to report to trackers (requires restart) + + + + + Display program on-screen notifications + + + + + Enable embedded tracker + + + + + Embedded tracker port + + + + + Check for software updates + + + + + Use system icon theme + + + + + Confirm torrent deletion + + + + + Ignore transfer limits on local network + Ohita siirtorajoitukset lähiverkossa + + + Include TCP/IP overhead in transfer limits + Huomioi TCP/IP:n lisäkuorma siirtorajoituksissa + + + + AutomatedRssDownloader + + + Automated RSS Downloader + + + + + Enable the automated RSS downloader + + + + + Download rules + + + + + Rule definition + + + + + Must contain: + + + + + Must not contain: + + + + + Use regular expressions + + + + + Import... + Tuo... + + + + Export... + Vie... + + + + ... + ... + + + + Assign label: + + + + + Save to a different directory + + + + + Save to: + + + + + Apply rule to feeds: + + + + + Matching RSS articles + + + + + New rule name + + + + + Please type the name of the new download rule. + + + + + + Rule name conflict + + + + + + A rule with this name already exists, please choose another name. + + + + + Are you sure you want to remove the download rule named %1? + + + + + Are you sure you want to remove the selected download rules? + + + + + Rule deletion confirmation + + + + + Destination directory + + + + + Invalid action + + + + + The list is empty, there is nothing to export. + + + + + Where would you like to save the list? + + + + + Rules list (*.rssrules) + + + + + I/O Error + I/O-virhe + + + + Failed to create the destination file + + + + + Please point to the RSS download rules file + + + + + Rules list (*.rssrules *.filters) + + + + + Import Error + + + + + Failed to import the selected rules file + + + + + Add new rule... + + + + + Delete rule + + + + + Rename rule... + + + + + Delete selected rules + + + + + Rule renaming + + + + + Please type the new rule name + + + + + Regex mode: use Perl-like regular expressions + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 on saavuttanut asetetun jakosuhdeluvun. + + + Removing torrent %1... + Poistetaan torrent %1... + + + Pausing torrent %1... + Keskeytetään torrent %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent käyttää porttia: TCP/%1 + + + UPnP support [ON] + UPnP-tuki [KÄYTÖSSÄ] + + + UPnP support [OFF] + UPnP-tuki [EI KÄYTÖSSÄ] + + + NAT-PMP support [ON] + NAT-PMP-tuki [KÄYTÖSSÄ] + + + NAT-PMP support [OFF] + NAT-PMP-tuki [EI KÄYTÖSSÄ] + + + HTTP user agent is %1 + HTTP-agentti on %1 + + + Using a disk cache size of %1 MiB + Käytetään %1 MiB levyvälimuistia + + + DHT support [ON], port: UDP/%1 + DHT-tuki [KÄYTÖSSÄ], portti: UDP/%1 + + + DHT support [OFF] + DHT-tuki [EI KÄYTÖSSÄ] + + + PeX support [ON] + PeX-tuki [KÄYTÖSSÄ] + + + PeX support [OFF] + PeX-tuki [EI KÄYTÖSSÄ] + + + Restart is required to toggle PeX support + PeX-tuen tilan muuttaminen vaatii uudelleenkäynnistyksen + + + Local Peer Discovery [ON] + Paikallinen käyttäjien löytäminen [KÄYTÖSSÄ] + + + Local Peer Discovery support [OFF] + Paikallinen käyttäjien löytäminen [EI KÄYTÖSSÄ] + + + Encryption support [ON] + Salaus [KÄYTÖSSÄ] + + + Encryption support [FORCED] + Salaus [PAKOTETTU] + + + Encryption support [OFF] + Salaus [EI KÄYTÖSSÄ] + + + The Web UI is listening on port %1 + Web-käyttöliittymä kuuntelee porttia %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Web-käyttöliittymävirhe - web-liittymää ei voitu liittää porttiin %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + ”%1” poistettiin siirrettävien listalta ja kovalevyltä. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + ”%1” poistettiin siirrettävien listalta. + + + '%1' is not a valid magnet URI. + ”%1” ei kelpaa magnet-URI:ksi. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + ”%1” on jo latauslistalla. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + Torrentin "%1” latausta jatkettiin. (nopea palautuminen) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + ”%1” lisättiin latauslistalle. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Viallinen torrent-tiedosto: ”%1” + + + This file is either corrupted or this isn't a torrent. + Tiedosto on joko rikkonainen tai se ei ole torrent-tiedosto. + + + Note: new trackers were added to the existing torrent. + Huomaa: torrenttiin lisättiin uusia seurantapalvelimia. + + + Note: new URL seeds were added to the existing torrent. + Huomaa: torrenttiin lisättiin uusia URL-syötteitä. + + + Error: The torrent %1 does not contain any file. + Virhe: torrentissa %1 ei ole tiedostoja. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <i>IP-suodatin on estänyt osoitteen</i> <font color='red'>%1</font> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>on estetty korruptuneiden osien takia</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekursiivinen tiedoston %1 lataus torrentissa %2 + + + Unable to decode %1 torrent file. + Torrent-tiedostoa %1 ei voitu tulkita. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: portin määritys epäonnistui virhe: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PP: portin määritys onnistui, viesti: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Nopean jatkamisen tiedot eivät kelpaa torrentille %1. Tarkistetaan uudestaan... + + + Reason: %1 + Syy: %1 + + + An I/O error occured, '%1' paused. + Tapahtui I/O-virhe, ”%1” pysäytettiin. + + + File sizes mismatch for torrent %1, pausing it. + Torrentin %1 tiedostokoot eivät täsmää, keskeytetään. + + + Url seed lookup failed for url: %1, message: %2 + Jakajien haku osoitteesta %1 epäonnistui: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Ladataan torrenttia ”%1”. Odota... + + + + ConsoleDlg + + qBittorrent log viewer + qBittorrentin lokin katselu + + + General + Yleistä tietoa + + + Blocked IPs + Estetyt IP-osoitteet + + + + CookiesDlg + + + Cookies management + Evästeiden hallinta + + + + Key + As in Key/Value pair + Avain + + + + Value + As in Key/Value pair + Arvo + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Evästeiden vakioavaimet ovat: ”%1”, ”%2”. +Sinun pitäisi löytää nämä tiedot web-selaimesi asetuksista. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + + + + + Dynamic DNS error: Invalid username/password. + + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: Your username was blocked due to abuse. + + + + + Dynamic DNS error: supplied domain name is invalid. + + + + + Dynamic DNS error: supplied username is too short. + + + + + Dynamic DNS error: supplied password is too short. + + + + + DownloadThread + + + + I/O Error + I/O-virhe + + + + The remote host name was not found (invalid hostname) + Kohdekoneen nimeä ei löytynyt (epäkelpo palvelinnimi) + + + + The operation was canceled + Toiminto peruttiin + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Vastapää katkaisi yhteyden ennenaikaisesti, ennenkuin vastaus saatiin eheänä ja käsiteltiin + + + + The connection to the remote server timed out + Yhteys vastapäähän aikakatkaistiin + + + + SSL/TLS handshake failed + SSL/TLS-kättely epäonnistui + + + + The remote server refused the connection + Vastapää ei hyväksynyt yhteyttä + + + + The connection to the proxy server was refused + Välityspalvelin ei hyväksynyt yhteyttä + + + + The proxy server closed the connection prematurely + Välityspalvelin sulki yhteyden ennenaikaisesti + + + + The proxy host name was not found + Välityspalvelimen nimeä ei voitu ratkaista + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Yhteys välityspalvelimeen aikakatkaistiin tai välityspalvlein ei vastannut ajoissa lähetettyyn pyyntöön + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Välityspalvelin vaatii autentikoinnin vastatakseen pyyntöön mutta ei hyväksynyt annettuja tietoja + + + + The access to the remote content was denied (401) + Pääsy sisältöön estettiin (401) + + + + The operation requested on the remote content is not permitted + Sisältöön pyydetty toiminto ei ole sallittu + + + + The remote content was not found at the server (404) + Sisältöä ei löytynyt palvelimelta (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Palvelin vaatii autentikoinnin tarjotakseen sisältöä mutta annettuja tietoja ei hyyväksytty + + + + The Network Access API cannot honor the request because the protocol is not known + Verkkoyhteys-API ei palvele koska yhteyskäytäntöä ei tunneta + + + + The requested operation is invalid for this protocol + Pyydetty toiminto ei käy tällä yhteyskäytännöllä + + + + An unknown network-related error was detected + Tuntematon verkko-ongelma + + + + An unknown proxy-related error was detected + Tuntematon välityspalvelinongelma + + + + An unknown error related to the remote content was detected + Tuntematon sisältöongelma + + + + A breakdown in protocol was detected + Virhe yhteyskäytännössä + + + + Unknown error + Tuntematon virhe + + + + EventManager + + + + Working + Työstetään + + + + Updating... + Päivitetään... + + + + + Not working + Ei toimi + + + + + Not contacted yet + Ei ole vielä yheyttä + + + + + this session + tämä istunto + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + jaettu %1 + + + + %1 max + e.g. 10 max + korkeintaan %1 + + + + + %1/s + e.g. 120 KiB/s + %1/s + + + + ExecutionLog + + + General + + + + + Blocked IPs + Estetyt IP-osoitteet + + + + FeedDownloader + + RSS Feed downloader + RSS-lataaja + + + RSS feed: + RSS-syöte: + + + Feed name + Syötteen nimi + + + Automatically download torrents from this feed + Lataa tämän syötteen torrentit automaattisesti + + + Download filters + Lataussuodattimet + + + Filters: + Suodattimet: + + + Filter settings + Suodatusasetukset + + + Matches: + Sopii: + + + Does not match: + Ei sovi: + + + Destination folder: + Kohdekansio: + + + ... + ... + + + Filter testing + Suotimen testaus + + + Torrent title: + Torrentin nimike: + + + Result: + Tulos: + + + Test + Testaa + + + Import... + Tuo... + + + Export... + Vie... + + + Rename filter + Nimeä suodatin + + + Remove filter + Poista suodatin + + + Add filter + Lisää suodatin + + + + FeedDownloaderDlg + + New filter + Uusi suodatin + + + Please choose a name for this filter + Nimeä suodatin + + + Filter name: + Suodattimen nimi: + + + Invalid filter name + Virheellinen suodattimen nimi + + + The filter name cannot be left empty. + Nimeä ei voi jättää tyhjäksi. + + + This filter name is already in use. + Suodatinnimi on jo käytössä. + + + Choose save path + Valitse tallennuskansio + + + Filter testing error + Suodattimen testausvirhe + + + Please specify a test torrent name. + Anna testitorrentin nimi. + + + matches + sopii + + + does not match + ei sovi + + + Select file to import + Valitse tuotava tiedosto + + + Filters Files + Suodatintiedostot + + + Import successful + Tuonti onnistui + + + Filters import was successful. + Suodattimien tuonti onnistui. + + + Import failure + Tuonti epäonnistui + + + Filters could not be imported due to an I/O error. + Suodattimia ei voitu tuoda I/O-virheen vuoksi. + + + Select destination file + Valitse kohdetiedosto + + + Export successful + Vienti onnistui + + + Filters export was successful. + Suodattimien viesti onnistui. + + + Export failure + Vientivirhe + + + Filters could not be exported due to an I/O error. + Suodattimia ei voitu viedä I/O-virheen vuoksi. + + + + FeedList + + Unread + Lukematon + + + + FeedListWidget + + + RSS feeds + RSS-syötteet + + + + Unread + Lukematon + + + + GUI + + Open Torrent Files + Avaa torrent-tiedostoja + + + Torrent Files + Torrent-tiedostot + + + Transfers + Siirrot + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Vahvistus rekursiiviseen lataukseen + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torentti %1 sisältää torrent-tiedostoja, jatketaanko latausta? + + + Yes + Kyllä + + + No + Ei + + + Never + Ei koskaan + + + Global Upload Speed Limit + Yleinen lähetysnopeusrajoitus + + + Global Download Speed Limit + Yleinen latausnopeusrajoitus + + + Exiting qBittorrent + Lopetetaan qBittorrent + + + qBittorrent + qBittorrent + + + Always + Aina + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Latausnopeus: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Lähetysnopeus: %1 KiB/s + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Lataus: %2/s, lähetys: %3/s) + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Lataus ”%1” tuli valmiiksi. + + + I/O Error + i.e: Input/Output Error + I/O-virhe + + + Search + Etsi + + + Torrent file association + Torrent-tiedoston liittäminen + + + RSS + RSS + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Download completion + Latauksen valmistuminen + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent ei ole torrent-tiedostojen tai Magnet-linkkien oletusohjelmisto. +Haluatko, että qBittorrent käsittelee nämä oletusarvoisesti? + + + Transfers (%1) + Siirrot (%1) + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Torrentissa %1 tapahtui I/O-virhe. + Syy: %2 + + + Url download error + Latausvirhe + + + Couldn't download file at url: %1, reason: %2. + Tiedoston lataaminen osoitteesta %1 epäonnistui: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Tiedostoja on siirrotta. +Haluatko varmasti lopettaa qBittorrentin? + + + Options were saved successfully. + Valinnat tallennettiin. + + + + GeoIP + + Australia + Austraalia + + + Argentina + Argentiina + + + Austria + Itävalta + + + United Arab Emirates + Yhdistyneet Arabiemiraatit + + + Brazil + Brasilia + + + Bulgaria + Bulgaaria + + + Belarus + Valko-Venäjä + + + Belgium + Belgia + + + Bosnia + Bosnia + + + Canada + Kanada + + + Czech Republic + Tšekki + + + China + Kiina + + + Costa Rica + Costa Rica + + + Switzerland + Sveitsi + + + Germany + Saksa + + + Denmark + Tanska + + + Algeria + Algeria + + + Spain + Espanja + + + Egypt + Egypti + + + Finland + Suomi + + + France + Ranska + + + United Kingdom + Yhdistynyt kuningaskunta + + + Greece + Kreikka + + + Georgia + Georgia + + + Hungary + Unkari + + + Croatia + Kroatia + + + Italy + Italia + + + India + Intia + + + Israel + Israel + + + Ireland + Irlanti + + + Iceland + Islanti + + + Indonesia + Indonesia + + + Japan + Japani + + + South Korea + Etelä-Korea + + + Luxembourg + Luxemburg + + + Malaysia + Malesia + + + Mexico + Meksiko + + + Serbia + Serbia + + + Morocco + Marokko + + + Netherlands + Alankomaat + + + Norway + Norja + + + New Zealand + Uusi-Seelanti + + + Portugal + Portugali + + + Poland + Puola + + + Pakistan + Pakistani + + + Philippines + Filippiinit + + + Russia + Venäjä + + + Romania + Romania + + + France (Reunion Island) + Ranska (Reunion-saari) + + + Saudi Arabia + Saudi-Arabia + + + Sweden + Ruotsi + + + Slovakia + Slovakia + + + Singapore + Singapore + + + Slovenia + Slovenia + + + Taiwan + Taiwan + + + Turkey + Turkki + + + Thailand + Thaimaa + + + USA + USA + + + Ukraine + Ukraina + + + South Africa + Etelä-Afrikka + + + + HeadlessLoader + + + Information + Tiedot + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Käytä web-käyttöliittymää osoitteessa http://localhost:%1 ohjataksesi qBittorrenttia + + + + The Web UI administrator user name is: %1 + Web-käyttöliittymän ylläpitäjän käyttäjätunnus on: %1 + + + + The Web UI administrator password is still the default one: %1 + Web-käyttöliittymän ylläpitäjän salasana on edelleen oletus: %1 + + + + This is a security risk, please consider changing your password from program preferences. + Tämä on turvallisuusriski, harkitse salasanasi vaihtamista ohjelman asetuksista. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + IP-osoitteesi on hylätty liian monen epäonnistuneen autentikointiyrityksen vuoksi. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + LaN: %1/s - S: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + LäN: %1/s - S: %2 + + + + HttpServer + + + File + Tiedosto + + + + Edit + Muokkaa + + + + Help + Opaste + + + Delete from HD + Poista kovalevyltä + + + + Download Torrents from their URL or Magnet link + Lataa torrentit URL:ista tai magnetic linkistä + + + + Only one link per line + Yksi linkki riville + + + + Download local torrent + Lataa paikallinen torrentti + + + + Torrent files were correctly added to download list. + Torrentti-tiedostojen lisäys latauslistalle onnistui. + + + + Point to torrent file + Osoita torrenttitiedosto + + + + Download + Lataa + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Haluatko poistaa valitut torrentit siirtolistalta ja kovalevyltä? + + + + Download rate limit must be greater than 0 or disabled. + Latauksen rajan pitää olla suurempi kuin 0 tai poistettu käytöstä. + + + + Upload rate limit must be greater than 0 or disabled. + Lähetyksen rajan pitää olla suurempi kuin 0 tai poistettu käytöstä. + + + + Maximum number of connections limit must be greater than 0 or disabled. + Yhteyksien enimmäismäärän pitää olla suurempi kuin 0 tai poistettu käytöstä. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Yhteyksien torrenttikohtaisen maksimimäärän pitää olla suurempi kuin 0 tai poistettu käytöstä. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Lähetyslohkojen torrenttikohtaisen enimmäismäärän pitää olla suurempi kuin 0 tai poistettu käytöstä. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Asetuksia ei voitu tallentaa, qBittorrenttiin ei todennäköisesti saada yhteyttä. + + + + Language + Kieli + + + + Downloaded + Is the file downloaded or not? + Ladattu + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Sisääntuleville yhteyksille tarkoitetun portin numeron pitää olla suurempi kuin 1024 ja pienempi kuin 65535. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Web-käyttöliittymälle varatun portin pitää olla suurempi kuin 1024 ja pienempi kuin 65535. + + + + The Web UI username must be at least 3 characters long. + Web-käyttöliittymän käyttäjätunnuksen pitää olla vähintään kolme merkkiä pitkä. + + + + The Web UI password must be at least 3 characters long. + Web-käyttöliittymän salasanan pitää olla vähintään kolme merkkiä pitkä. + + + + Save + + + + + qBittorrent client is not reachable + + + + + HTTP Server + HTTP-palvelin + + + + The following parameters are supported: + + + + + Torrent path + + + + + Torrent name + + + + + LegalNotice + + + Legal Notice + Oikeudellinen huomautus + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent on tiedostonjako-ohjelma. Kun ajat torrenttia, sen tiedot ovat muiden saatavilla. Olet vastuussa kaikesta jakamastasi. + +Muita varoituksia ei anneta. + + + + Press %1 key to accept and continue... + Paina %1-näppäintä hyväksyäksesi ja jatkaaksesi... + + + + Legal notice + Oikeudellinen huomautus + + + + Cancel + Peruuta + + + + I Agree + Hyväksyn + + + + LineEdit + + + Clear the text + + + + + MainWindow + + Clear log + Tyhjennä loki + + + + &Edit + &Muokkaa + + + + &File + &Tiedosto + + + + &Help + &Ohje + + + + Add &link to torrent... + + + + Preview file + Esikatsele + + + + &Tools + &Työkalut + + + + &View + &Näytä + + + &Add File... + &Lisää tiedosto... + + + E&xit + &Poistu + + + + &Options... + V&alinnat... + + + + &About + &Tietoja + + + + &Pause + &Pysäytä + + + + &Delete + &Poista + + + + P&ause All + P&ysäytä kaikki + + + + &Resume + + + + + Auto-Shutdown on downloads completion + + + + + &Add torrent file... + + + + + + Exit + + + + + R&esume All + + + + + Visit &Website + Käy &web-sivustolla + + + Add &URL... + Lisää &Url... + + + + Torrent &creator + Torrentin &valmistaja + + + + Report a &bug + Ilmoita &virheestä + + + + Set upload limit... + Aseta lähetysnopeusrajoitus... + + + + Set download limit... + Aseta latausnopeusrajoitus... + + + + &Documentation + &Dokumentaatio + + + + Set global download limit... + Aseta yleinen latausnopeusrajoitus... + + + + Set global upload limit... + Aseta yleinen lähetysnopeusrajoitus... + + + + Decrease priority + Laske prioriteettia + + + + Increase priority + Nosta prioriteettia + + + + Exit qBittorrent + + + + + Suspend system + + + + + Shutdown system + + + + + Disabled + + + + &Log viewer... + &Lokin katselu... + + + Log viewer + Lokin katselu + + + + + Alternative speed limits + Vaihtoehtoiset nopeusrajoitukset + + + + Top &tool bar + &Ylätyökalupalkki + + + + Display top tool bar + Näytä ylätyökalupalkki + + + + &Speed in title bar + &Nopeus otsikkorivillä + + + + Show transfer speed in title bar + Näytä nopeus otsikkorivillä + + + + &RSS reader + &RSS-lukija + + + + Search &engine + &Hakupalvelu + + + + + Lock qBittorrent + + + + + Ctrl+L + + + + + Import existing torrent... + + + + + Import torrent... + + + + + Donate money + + + + + If you like qBittorrent, please donate! + + + + + Execution &Log + + + + + + Execution Log + + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + + + + + Transfers + Siirrot + + + + Torrent file association + Torrent-tiedoston liittäminen + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent ei ole torrent-tiedostojen tai Magnet-linkkien oletusohjelmisto. +Haluatko, että qBittorrent käsittelee nämä oletusarvoisesti? + + + + + + UI lock password + + + + + + + Please type the UI lock password: + + + + + The password should contain at least 3 characters + + + + + Password update + + + + + The UI lock password has been successfully updated + + + + + RSS + RSS + + + + Search + Etsi + + + + Transfers (%1) + Siirrot (%1) + + + + Download completion + Latauksen valmistuminen + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Lataus ”%1” tuli valmiiksi. + + + + I/O Error + i.e: Input/Output Error + I/O-virhe + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Torrentissa %1 tapahtui I/O-virhe. + Syy: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Vahvistus rekursiiviseen lataukseen + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torentti %1 sisältää torrent-tiedostoja, jatketaanko latausta? + + + + + Yes + Kyllä + + + + + No + Ei + + + + Never + Ei koskaan + + + + Url download error + Latausvirhe + + + + Couldn't download file at url: %1, reason: %2. + Tiedoston lataaminen osoitteesta %1 epäonnistui: %2. + + + + Global Upload Speed Limit + Yleinen lähetysnopeusrajoitus + + + + Global Download Speed Limit + Yleinen latausnopeusrajoitus + + + + + Invalid password + + + + + The password is invalid + + + + + Exiting qBittorrent + Lopetetaan qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Tiedostoja on siirrotta. +Haluatko varmasti lopettaa qBittorrentin? + + + + Always + Aina + + + + Open Torrent Files + Avaa torrent-tiedostoja + + + + Torrent Files + Torrent-tiedostot + + + + Options were saved successfully. + Valinnat tallennettiin. + + + + qBittorrent + + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Latausnopeus: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Lähetysnopeus: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Lataus: %2/s, lähetys: %3/s) + + + + A newer version is available + + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + + + + + Impossible to update qBittorrent + + + + + qBittorrent failed to update, reason: %1 + + + + + PeerAdditionDlg + + + Invalid IP + Virheellinen IP + + + + The IP you provided is invalid. + Antamasi IP-osoite ei kelpaa. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + IP + + + + Connection + Yhteys + + + + Client + i.e.: Client application + Asiakas + + + + Progress + i.e: % downloaded + Edistyminen + + + + Down Speed + i.e: Download speed + Latausnopeus + + + + Up Speed + i.e: Upload speed + Lähetysnopeus + + + + Downloaded + i.e: total data downloaded + Ladattu + + + + Uploaded + i.e: total data uploaded + Lähetetty + + + + Add a new peer... + Lisää uusi asiakas... + + + + Copy IP + + + + + Limit download rate... + Rajoita latausnopeus... + + + + Limit upload rate... + Rajoita lähetysnopeus... + + + + Ban peer permanently + Poista asiakas pysyvästi + + + + + Peer addition + Asiakkaan lisäys + + + + The peer was added to this torrent. + Asiakas lisättiin tähän torrenttiin. + + + + The peer could not be added to this torrent. + Asiakasta ei voitu lisätä tähän torrenttiin. + + + + Are you sure? -- qBittorrent + Oletko varma? — qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Haluatko varmasti poistaa valitut asiakkaat pysyvästi? + + + + &Yes + &Kyllä + + + + &No + &Ei + + + + Manually banning peer %1... + Poistetaan käsin asiakas %1... + + + + Upload rate limiting + Lähetysnopeuden rajoittaminen + + + + Download rate limiting + Latausnopeuden rajoittaminen + + + + Preferences + + UI + User Interface + Käyttöliittymä + + + + Downloads + Lataukset + + + + Connection + Yhteys + + + + Speed + Nopeus + + + Bittorrent + Bittorrent + + + Proxy + Välityspalvelin + + + + Web UI + Web-käyttöliittymä + + + + Advanced + Edistyneet + + + Language: + Kieli: + + + + (Requires restart) + (Vaatii uudelleenkäynnistyksen) + + + Visual style: + Ulkoasu: + + + Transfer list + Siirrot + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Käytä vaihtelevia rivivärejä + + + + + Start / Stop Torrent + + + + + + No action + Ei toimintoa + + + File system + Tiedostojärjestelmä + + + + Copy .torrent files to: + Kopioi .torrent-tiedostot kohteeseen: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + + + + Torrent queueing + Torrenttien jonotus + + + + Maximum active downloads: + Aktiivisia latauksia enintään: + + + + Maximum active uploads: + Aktiivisia lähetettäviä torrentteja enintään: + + + + Maximum active torrents: + Aktiivisia torrentteja enintään: + + + + When adding a torrent + Kun lisätään torrent-tiedostoa + + + + + Options + Valinnat + + + Visual Appearance + Ulkoasu + + + + Action on double-click + Toiminta tuplanapsautuksella + + + + Downloading torrents: + Ladataan torrentteja: + + + Start / Stop + Aloita / lopeta + + + + + Open destination folder + Avaa kohdekansio + + + + Completed torrents: + Valmistuneet torrentit: + + + + Desktop + Työpöytä + + + + Show splash screen on start up + Näytä aloituskuva käynnistettäessä + + + + Start qBittorrent minimized + Käynnistä qBittorrent minimoituna + + + Show qBittorrent icon in notification area + Näytä qBittorrentin kuvake ilmoitusalueella + + + + Minimize qBittorrent to notification area + Minimoi qBittorrent ilmoitusalueelle + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Sulje qBittorrent ilmoitusalueelle + + + + Tray icon style: + + + + + Normal + Normaali + + + + Monochrome (Dark theme) + + + + + Monochrome (Light theme) + + + + + Ask for program exit confirmation + + + + + User Interface Language: + + + + + Transfer List + + + + + Show qBittorrent in notification area + + + + + Power Management + + + + + Inhibit system sleep when torrents are active + + + + + Display torrent content and some options + Näytä torrentin sisältö ja joitakin valintoja + + + + Do not start the download automatically + The torrent will be added to download list in pause state + Älä aloita lataamista automaattisesti + + + + Hard Disk + + + + + Save files to location: + Tallenna tiedostot kohteeseen: + + + + Append the label of the torrent to the save path + Lisää torrentin nimike tallennuspolkuun + + + + Pre-allocate disk space for all files + Varaa kaikille tiedostoille levytila ennakkoon + + + + Keep incomplete torrents in: + Tallenna puolivalmiit torrentit kohteeseen: + + + Append .!qB extension to incomplete files' names + Lisää .!qB-tarkenne puolivalmiitten tiedostojen nimiin + + + + Automatically add torrents from: + Lisää torrentit automaattisesti kohteesta: + + + + Add folder... + Lisää kansio... + + + + Email notification upon download completion + + + + + Destination email: + + + + + SMTP server: + + + + + This server requires a secure connection (SSL) + + + + + Run an external program on torrent completion + + + + + Listening Port + + + + + Use UPnP / NAT-PMP port forwarding from my router + + + + + Otherwise, the proxy server is only used for tracker connections + + + + + Use proxy for peer connections + + + + + Reload the filter + + + + + Enable bandwidth management (uTP) + + + + + Privacy + + + + + Enable DHT (decentralized network) to find more peers + + + + + Use a different port for DHT and BitTorrent + + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Vaihta asiakastietoja yhteensopivien Bittorrent-asiakkaiden (µTorrent, Vuze, ...) kanssa + + + + Enable Peer Exchange (PeX) to find more peers + + + + + Enable Local Peer Discovery to find more peers + + + + + Encryption mode: + + + + + Prefer encryption + + + + + Require encryption + + + + + Disable encryption + + + + + Use HTTPS instead of HTTP + + + + + Import SSL Certificate + + + + + Import SSL Key + + + + + Certificate: + + + + + Key: + + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + Update my dynamic domain name + + + + + Service: + + + + + Register + + + + + Domain name: + + + + Share ratio limiting + Jakosuhteen rajoitus + + + + Seed torrents until their ratio reaches + Jatka torrenttien jakamista kunnes jakosuhde saavuttaa + + + + then + sitten + + + + Pause them + Pysäytä ne + + + + Remove them + Poista ne + + + + Enable Web User Interface (Remote control) + Ota web-käyttöliittymä käyttöön (etäyhteys) + + + + Use UPnP / NAT-PMP to forward the port from my router + + + + + Bypass authentication for localhost + + + + Listening port + Kuuntele porttia + + + + Port used for incoming connections: + Portti sisääntuleville yhteyksille: + + + + Random + Satunnainen + + + Enable UPnP port mapping + Käytä UPnP-porttivarausta + + + Enable NAT-PMP port mapping + Käytä NAT-PMP-porttivarausta + + + Connections limit + Yhteyksien enimmäismäärä + + + + Global maximum number of connections: + Kaikkien yhteyksien enimmäismäärä: + + + + Maximum number of connections per torrent: + Yhteyksien enimmäismäärä torrenttia kohden: + + + + Maximum number of upload slots per torrent: + Lähetyspaikkoja torrentia kohden: + + + + + Upload: + Lähetys: + + + + + Download: + Lataus: + + + + + + + KiB/s + KiB/s + + + + BitTorrent + + + + Global speed limits + Yleiset nopeusrajoitukset + + + Alternative global speed limits + Vaihtoehtoiset nopeusrajoitukset + + + + to + time1 to time2 + + + + + Every day + Joka päivä + + + + Week days + Arkipäivinä + + + + Week ends + Viikonloppuisin + + + Bittorrent features + Bittorrent-piirteet + + + Enable DHT network (decentralized) + Käytä hajautettua DHT-verkkoa + + + Use a different port for DHT and Bittorrent + Käytä eri porttia DHT:lle ja Bittorrentille + + + + DHT port: + DHT-portti: + + + Enable Peer Exchange / PeX (requires restart) + Ota PeX käyttöön (vaatii uudelleenkäynnistyksen) + + + Enable Local Peer Discovery + Käytä paikallista käyttäjien löytämistä + + + Enabled + Käytössä + + + Forced + Pakotettu + + + Disabled + Poistettu käytöstä + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP-yhteydet (seurantapalvelimet, web-syötteet, hakukone) + + + + Host: + Isäntä: + + + Peer Communications + Asiakastietoliikenne + + + + SOCKS4 + SOCKS4 + + + + Type: + Tyyppi: + + + + + Behavior + + + + + Language + Kieli + + + + Remove folder + Poista kansio + + + + Connections Limits + + + + + Proxy Server + + + + + IP Filtering + IP-suodatus + + + Schedule the use of alternative speed limits + Ajasta vaihtoehtoisten nopeusrajoitusten käyttö + + + + from + from (time1 to time2) + alkaen + + + + When: + Koska: + + + + Look for peers on your local network + Etsi asiakkaita paikallisverkostasi + + + Protocol encryption: + Protokollan salaus: + + + + (None) + (Ei mikään) + + + + HTTP + HTTP + + + + + Port: + Portti: + + + + + + Authentication + Sisäänkirjautuminen + + + + Append .!qB extension to incomplete files + + + + + + + + Username: + Tunnus: + + + + + + + Password: + Salasana: + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + Suodatustiedoston sijainti (.dat, .p2p, p2b): + + + + Global Rate Limits + + + + + Apply rate limit to uTP connections + + + + + Apply rate limit to transport overhead + + + + + Alternative Global Rate Limits + + + + + Schedule the use of alternative rate limits + + + + + Torrent Queueing + + + + + Share Ratio Limiting + + + + HTTP Server + HTTP-palvelin + + + + PreviewSelect + + + Name + Nimi + + + + Size + Koko + + + + Progress + Edistyminen + + + + + + Preview impossible + Esikatselu ei ole mahdollista + + + + + + Sorry, we can't preview this file + Tätä tiedostoa ei voi esikatsella + + + + PropListDelegate + + + Not downloaded + Ei ladattu + + + + + Normal + Normal (priority) + Normaali + + + + + High + High (priority) + Korkea + + + + Mixed + Mixed (priorities + + + + + + Maximum + Maximum (priority) + Korkein + + + + PropTabBar + + + General + + + + + Trackers + Seurantapalvelimet + + + + Peers + + + + + HTTP Sources + + + + + Content + + + + Files + Tiedostot + + + + PropertiesWidget + + + Save path: + Tallennuskansio: + + + + Torrent hash: + Tarkistustiiviste: + + + + Comment: + Kommentti: + + + + Share ratio: + Jakosuhde: + + + + + Downloaded: + Ladattu: + + + + Availability: + Saatavuus: + + + + Transfer + Siirto + + + + Uploaded: + Lähetetty: + + + + Wasted: + Hukattu: + + + + Time active: + Time (duration) the torrent is active (not paused) + + + + + Pieces size: + + + + + Torrent content: + Torrentin sisältö: + + + + Select All + Valitse kaikki + + + + Select None + Poista valinnat + + + + + Do not download + Älä lataa + + + + UP limit: + Lähetysraja: + + + + DL limit: + Latausraja: + + + Time elapsed: + Aikaa kulunut: + + + + Connections: + Yhteydet: + + + + Reannounce in: + Julkaise uudelleen: + + + + Information + Tiedot + + + + Created on: + Luotu: + + + General + Yleistä + + + Trackers + Seurantapalvelimet + + + Peers + Asiakkaat + + + URL seeds + URL-jaot + + + Files + Tiedostot + + + + Priority + Prioriteetti + + + + Normal + Normaali + + + + Maximum + Korkein + + + + High + Korkea + + + + + this session + tämä istunto + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Jaettu %1 + + + + %1 max + e.g. 10 max + korkeintaan %1 + + + + + I/O Error + I/O-virhe + + + + This file does not exist yet. + Tiedostoa ei ole vielä. + + + + This folder does not exist yet. + Kansiota ei ole vielä. + + + + Rename... + Nimeä uudelleen... + + + + Rename the file + Nimeä tiedosto uudelleen + + + + New name: + Uusi nimi: + + + + + The file could not be renamed + Tiedostoa ei voitu nimetä uudelleen + + + + This file name contains forbidden characters, please choose a different one. + Tiedostonimi sisältää kiellettyjä merkkejä, valitse toinen. + + + + + This name is already in use in this folder. Please use a different name. + Nimi on jo käytössä tässä kansiossa. Käytä toista nimeä. + + + + The folder could not be renamed + Kansiota ei voitu nimetä uudelleen + + + + New url seed + New HTTP source + Uusi URL-lähde + + + + New url seed: + Uusi URL-lähde: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + URL-jakaja on jo listalla. + + + + + Choose save path + Valitse tallennuskansio + + + Save path creation error + Tallennuskansion luominen epäonnistui + + + Could not create the save path + Tallennuskansion luominen epäonnistui + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 on saavuttanut asetetun jakosuhdeluvun. + + + + Removing torrent %1... + Poistetaan torrent %1... + + + + Pausing torrent %1... + Keskeytetään torrent %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent käyttää porttia: TCP/%1 + + + UPnP support [ON] + UPnP-tuki [KÄYTÖSSÄ] + + + UPnP support [OFF] + UPnP-tuki [EI KÄYTÖSSÄ] + + + NAT-PMP support [ON] + NAT-PMP-tuki [KÄYTÖSSÄ] + + + NAT-PMP support [OFF] + NAT-PMP-tuki [EI KÄYTÖSSÄ] + + + + HTTP user agent is %1 + HTTP-agentti on %1 + + + Using a disk cache size of %1 MiB + Käytetään %1 MiB levyvälimuistia + + + + DHT support [ON], port: UDP/%1 + DHT-tuki [KÄYTÖSSÄ], portti: UDP/%1 + + + + + DHT support [OFF] + DHT-tuki [EI KÄYTÖSSÄ] + + + + PeX support [ON] + PeX-tuki [KÄYTÖSSÄ] + + + + PeX support [OFF] + PeX-tuki [EI KÄYTÖSSÄ] + + + + Restart is required to toggle PeX support + PeX-tuen tilan muuttaminen vaatii uudelleenkäynnistyksen + + + Local Peer Discovery [ON] + Paikallinen käyttäjien löytäminen [KÄYTÖSSÄ] + + + + Local Peer Discovery support [OFF] + Paikallinen käyttäjien löytäminen [EI KÄYTÖSSÄ] + + + + Encryption support [ON] + Salaus [KÄYTÖSSÄ] + + + + Encryption support [FORCED] + Salaus [PAKOTETTU] + + + + Encryption support [OFF] + Salaus [EI KÄYTÖSSÄ] + + + + Embedded Tracker [ON] + + + + + Failed to start the embedded tracker! + + + + + Embedded Tracker [OFF] + + + + + The Web UI is listening on port %1 + Web-käyttöliittymä kuuntelee porttia %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Web-käyttöliittymävirhe - web-liittymää ei voitu liittää porttiin %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + ”%1” poistettiin siirrettävien listalta ja kovalevyltä. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + ”%1” poistettiin siirrettävien listalta. + + + + '%1' is not a valid magnet URI. + ”%1” ei kelpaa magnet-URI:ksi. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + ”%1” on jo latauslistalla. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + Torrentin "%1” latausta jatkettiin. (nopea palautuminen) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + ”%1” lisättiin latauslistalle. + + + + UPnP / NAT-PMP support [ON] + + + + + UPnP / NAT-PMP support [OFF] + + + + + Reporting IP address %1 to trackers... + + + + + Local Peer Discovery support [ON] + + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Viallinen torrent-tiedosto: ”%1” + + + + This file is either corrupted or this isn't a torrent. + Tiedosto on joko rikkonainen tai se ei ole torrent-tiedosto. + + + + Error: The torrent %1 does not contain any file. + Virhe: torrentissa %1 ei ole tiedostoja. + + + + Note: new trackers were added to the existing torrent. + Huomaa: torrenttiin lisättiin uusia seurantapalvelimia. + + + + Note: new URL seeds were added to the existing torrent. + Huomaa: torrenttiin lisättiin uusia URL-syötteitä. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <i>IP-suodatin on estänyt osoitteen</i> <font color='red'>%1</font> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>on estetty korruptuneiden osien takia</i> + + + + The network interface defined is invalid: %1 + + + + + Trying any other network interface available instead. + + + + + Listening on IP address %1 on network interface %2... + + + + + Failed to listen on network interface %1 + + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekursiivinen tiedoston %1 lataus torrentissa %2 + + + + + Unable to decode %1 torrent file. + Torrent-tiedostoa %1 ei voitu tulkita. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + + + + + Error: Failed to parse the provided IP filter. + + + + + Torrent name: %1 + + + + + Torrent size: %1 + + + + + Save path: %1 + + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + + + + + Thank you for using qBittorrent. + + + + + [qBittorrent] %1 has finished downloading + + + + + An I/O error occured, '%1' paused. + Tapahtui I/O-virhe, ”%1” pysäytettiin. + + + + + Reason: %1 + Syy: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: portin määritys epäonnistui virhe: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PP: portin määritys onnistui, viesti: %1 + + + + File sizes mismatch for torrent %1, pausing it. + Torrentin %1 tiedostokoot eivät täsmää, keskeytetään. + + + + Fast resume data was rejected for torrent %1, checking again... + Nopean jatkamisen tiedot eivät kelpaa torrentille %1. Tarkistetaan uudestaan... + + + + Url seed lookup failed for url: %1, message: %2 + Jakajien haku osoitteesta %1 epäonnistui: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Ladataan torrenttia ”%1”. Odota... + + + + RSS + + + Search + Etsi + + + + New subscription + Uusi tilaus + + + + + + Mark items read + Merkitse lukemattomaksi + + + + Update all + Päivitä kaikki + + + + RSS Downloader... + + + + + Settings... + Asetukset... + + + RSS feed downloader... + RSS-lataaja... + + + + New folder... + Uusi kansio... + + + + Manage cookies... + Evästeiden hallinta... + + + Feed URL + Syötteen URL + + + + Rename... + Nimeä uudelleen... + + + + + Update + Päivitä + + + RSS feeds + RSS-syötteet + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrentit:</span> <span style=" font-style:italic;">(lataa tuplanapsauttamalla)</span></p></body></html> + + + Article title + Nimike + + + + New subscription... + Uusi tilaus... + + + + + Update all feeds + Päivitä syötteet + + + + + Delete + Poista + + + + Rename + Nimeä uudelleen + + + + Download torrent + Lataa torrentti + + + + Open news URL + Avaa uusi URL + + + + Copy feed URL + Kopioi syöte-URL + + + + Refresh RSS streams + Päivitä syötteet + + + + RSSImp + + + Please type a rss stream url + Osoite + + + + Stream URL: + Syötteen osoite: + + + + + Are you sure? -- qBittorrent + Oletko varma? — qBittorrent + + + + + &Yes + &Kyllä + + + + + &No + &Ei + + + + Please choose a folder name + Valitse kansion nimi + + + + Folder name: + Kansion nimi: + + + + New folder + Uusi kansio + + + + Overwrite attempt + Päällekirjoitusyritys + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Et voi kirjoittaa kohteen %1 päälle. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + RSS-syöte on jo listassa. + + + + Are you sure you want to delete these elements from the list? + Haluatko poistaa nämä listasta? + + + + Are you sure you want to delete this element from the list? + Haluatko poistaa tämän listasta? + + + + Please choose a new name for this RSS feed + Valitse uusi nimi tälle RSS-syötteelle + + + + New feed name: + Uusi syötteen nimi: + + + + Name already in use + Nimi on jo käytössä + + + + This name is already used by another item, please choose another one. + Tämä nimi on jo käytössä, valitse toinen. + + + + Date: + Päivä: + + + + Author: + Tekijä: + + + + Unread + Lukematon + + + + RssArticle + + No description available + Ei kuvausta + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Ladataan automaattisesti %1 torrentti RSS-syötteestä %2... + + + + RssItem + + No description available + Ei kuvausta + + + + RssSettings + + RSS Reader Settings + RSS-lukijan asetukset + + + RSS feeds refresh interval: + RSS-syötteen päivitystiheys: + + + minutes + minuuttia + + + Maximum number of articles per feed: + Artikkeleiden enimmäismäärä syötettä kohden: + + + + RssSettingsDlg + + + RSS Reader Settings + RSS-lukijan asetukset + + + + RSS feeds refresh interval: + RSS-syötteen päivitystiheys: + + + + minutes + minuuttia + + + + Maximum number of articles per feed: + Artikkeleiden enimmäismäärä syötettä kohden: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Ladataan automaattisesti %1 torrentti RSS-syötteestä %2... + + + + ScanFoldersModel + + + Watched Folder + Seurattu kansio + + + + Download here + Lataa tänne + + + + SearchCategories + + + All categories + Kaikki luokat + + + + Movies + Elokuvat + + + + TV shows + TV-ohjelmat + + + + Music + Musiikki + + + + Games + Pelit + + + + Anime + Anime + + + + Software + Ohjelmat + + + + Pictures + Kuvat + + + + Books + Kirjat + + + + SearchEngine + + + Empty search pattern + Tyhjä hakulauseke + + + + Please type a search pattern first + Kirjoita ensin hakulauseke + + + + + Results + Tulokset + + + + Searching... + Etsitään... + + + + Cut + Leikkaa + + + + Copy + Kopioi + + + + Paste + Liitä + + + + Clear field + Tyhjennä kenttä + + + + Clear completion history + Tyhjennä hakuhistoria + + + + Confirmation + Vahvistus + + + + Are you sure you want to clear the history? + Haluatko varmasti poistaa historiatiedot? + + + + + + Search + Etsi + + + + Missing Python Interpreter + Python-tulkki puuttuu + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Hakukone tarvitsee Python 2.x:n, mutta sitä ei ole asennettu. +Haluatko asentaa sen nyt? + + + + Search Engine + Hakupalvelu + + + + + Search has finished + Haku on päättynyt + + + + An error occured during search... + Haun aikana tapahtui virhe... + + + + + Search aborted + Haku keskeytetty + + + + Download error + Latausvirhe + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Pythonin asennuspakettia ei voitu ladata, syy: %1. +Asenna se itse. + + + + Search returned no results + Haku ei palauttanut tuloksia + + + + Results + i.e: Search results + Tulokset + + + + + Unknown + Tuntematon + + + + SearchTab + + + Name + i.e: file name + Nimi + + + + Size + i.e: file size + Koko + + + + Seeders + i.e: Number of full sources + Jakajia + + + + Leechers + i.e: Number of partial sources + Lataajia + + + + Search engine + Hakupalvelu + + + + ShutdownConfirmDlg + + + Shutdown confirmation + + + + + SpeedLimitDialog + + + KiB/s + KiB/s + + + + StatusBar + + + + Connection status: + Yhteyden tila: + + + + + No direct connections. This may indicate network configuration problems. + Ei suoria yhteyksiä. Tämä voi olla merkki verkko-ongelmista. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + LaN: %1 KiB/s - S: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + LäN: %1 B/s - S: %2 + + + + + DHT: %1 nodes + DHT: %1 solmua + + + + qBittorrent needs to be restarted + + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + + + + + + Connection Status: + Yhteyden tila: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Ei yhteyttä. Yleensä tämä tarkoittaa, että qBittorrent ei pystynyt kuuntelemaan sisääntulevien yhteyksien porttia. + + + + Online + Verkkoyhteydessä + + + + + %1/s + Per second + %1/s + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + LaN: %1/s - S: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + LäN: %1/s - S: %2 + + + + Click to switch to alternative speed limits + + + + + Click to switch to regular speed limits + + + + Click to disable alternative speed limits + Napsauta poistaaksesi vaihtoehtoinen nopeusrajoitus + + + Click to enable alternative speed limits + Napsauta ottaaksesi vaihtoehtoinen nopeusrajoitus käyttöön + + + + Global Download Speed Limit + Yleinen latausnopeusrajoitus + + + + Global Upload Speed Limit + Yleinen lähetysnopeusrajoitus + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Valitse kohdekansio + + + + Select a file to add to the torrent + Valitse torrentiin lisättävä tiedosto + + + Please type an announce URL + Anna julkaisusoite + + + Announce URL: + Tracker URL + Julkaisuosoite: + + + Please type a web seed url + Anna verkkojako-osoite + + + Web seed URL: + Verkkojako-osoite: + + + + No input path set + Lähdekansiota ei ole asetettu + + + + Please type an input path first + Anna ensin lähdekansio + + + + Select destination torrent file + Valitse kohde-torrent-tiedosto + + + + Torrent Files + Torrent-tiedostot + + + + + + Torrent creation + Torrentin luominen + + + + Torrent creation was unsuccessful, reason: %1 + Torrentin luominen epäonnistui: %1 + + + + Created torrent file is invalid. It won't be added to download list. + Luotu torrentti ei kelpaa. Sitä ei lisätä latauslistaan. + + + + Torrent was created successfully: + Torrent luotiin: + + + + TorrentFilesModel + + + Name + Nimi + + + + Size + Koko + + + + Progress + Edistyminen + + + + Priority + Prioriteetti + + + + TorrentImportDlg + + + Torrent Import + + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + + + + + Torrent file to import: + + + + + + ... + ... + + + + Content location: + + + + + Skip the data checking stage and start seeding immediately + + + + + Import + + + + + Torrent file to import + + + + + Torrent files (*.torrent) + + + + + %1 Files + %1 is a file extension (e.g. PDF) + + + + + Please provide the location of %1 + %1 is a file name + + + + + Please point to the location of the torrent: %1 + + + + + Invalid torrent file + + + + + This is not a valid torrent file. + + + + + TorrentModel + + + Name + i.e: torrent name + Nimi + + + + Size + i.e: torrent size + Koko + + + + Done + % Done + Valmis + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Tila + + + + Seeds + i.e. full sources (often untranslated) + Jakajia + + + + Peers + i.e. partial sources (often untranslated) + + + + + Down Speed + i.e: Download speed + Latausnopeus + + + + Up Speed + i.e: Upload speed + Lähetysnopeus + + + + Ratio + Share ratio + Jakosuhde + + + + ETA + i.e: Estimated Time of Arrival / Time left + Aikaa jäljellä + + + + Label + Nimike + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Lisätty + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Valmistui + + + + Tracker + + + + + Down Limit + i.e: Download limit + Latausraja + + + + Up Limit + i.e: Upload limit + Lähetysraja + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + + + + + Amount left + Amount of data left to download (e.g. in MB) + + + + + Time Active + Time (duration) the torrent is active (not paused) + + + + + TrackerList + + + URL + URL + + + + Status + Tila + + + + Peers + Asiakkaat + + + + Message + Viesti + + + + [DHT] + [DHT] + + + + [PeX] + [PeX] + + + + [LSD] + [LSD] + + + + + + + + Working + Toiminnassa + + + + + + Disabled + Ei käytössä + + + + This torrent is private + Torrentti on yksityinen + + + + Updating... + Päivitetään... + + + + + Not working + Ei toiminnassa + + + + + Not contacted yet + Ei ole vielä yhteyttä + + + + Add a new tracker... + Lisää uusi seurantapalvelin... + + + + Remove tracker + Poista seurantapalvelin + + + + Force reannounce + Pakota uudelleenjulkaisu + + + + TrackersAdditionDlg + + + Trackers addition dialog + Seurantapalvelimien lisäys + + + + List of trackers to add (one per line): + Seurantapalvelimet jokainen omalla rivillään: + + + + µTorrent compatible list URL: + µTorrent-yhteensopivan listan URL: + + + + I/O Error + I/O-virhe + + + + Error while trying to open the downloaded file. + Virhe avattaessa ladattua tiedostoa. + + + + No change + Ei muutosta + + + + No additional trackers were found. + Lisää seurantapalvelimia ei löytynyt. + + + + Download error + Latausvirhe + + + + The trackers list could not be downloaded, reason: %1 + Seurantapalvelinlistaa ei voitu ladata, syy: %1 + + + + TransferListDelegate + + + Downloading + Ladataan + + + + Paused + Pysäytetty + + + + Queued + i.e. torrent is queued + Jonossa + + + + Seeding + Torrent is complete and in upload-only mode + Jaetaan + + + + Stalled + Torrent is waiting for download to begin + Seisahtunut + + + + Checking + Torrent local data is being checked + Tarkastetaan + + + + /s + /second (.i.e per second) + /s + + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + + Seeded for %1 + e.g. Seeded for 3m10s + + + + + TransferListFiltersWidget + + + + All + Kaikki + + + + + Downloading + Ladataan + + + + + Completed + Valmiina + + + + + Paused + Pysäytetty + + + + + Active + Aktiivinen + + + + + Inactive + Epäaktiivinen + + + + + All labels + Kaikki nimikkeet + + + + + Unlabeled + Nimikkeetön + + + + Remove label + Poista nimike + + + + Add label... + Lisää nimike... + + + + Resume torrents + + + + + Pause torrents + + + + + Delete torrents + + + + + New Label + Uusi nimike + + + + Label: + Nimike: + + + + Invalid label name + Virheellinen nimike + + + + Please don't use any special characters in the label name. + Älä käytä erikoismerkkejä nimikkeessä. + + + + TransferListWidget + + Down Speed + i.e: Download speed + Latausnopeus + + + Up Speed + i.e: Upload speed + Lähetysnopeus + + + ETA + i.e: Estimated Time of Arrival / Time left + Aikaa jäljellä + + + + Column visibility + Sarakkeen näkyvyys + + + Name + i.e: torrent name + Nimi + + + Size + i.e: torrent size + Koko + + + Done + % Done + Valmis + + + Status + Torrent status (e.g. downloading, seeding, paused) + Tila + + + Seeds + i.e. full sources (often untranslated) + Jakajia + + + Peers + i.e. partial sources (often untranslated) + Asiakkaita + + + Ratio + Share ratio + Jakosuhde + + + + Label + Nimike + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Lisätty + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Valmistui + + + Down Limit + i.e: Download limit + Latausraja + + + Up Limit + i.e: Upload limit + Lähetysraja + + + + Choose save path + Valitse tallennuskansio + + + Save path creation error + Tallennuskansion luominen epäonnistui + + + Could not create the save path + Tallennuskansion luominen epäonnistui + + + + Torrent Download Speed Limiting + Torrentin latausnopeuden rajoitus + + + + Torrent Upload Speed Limiting + Torrentin lähetysnopeuden rajoitin + + + + New Label + Uusi nimike + + + + Label: + Nimike: + + + + Invalid label name + Virheellinen nimike + + + + Please don't use any special characters in the label name. + Älä käytä erikoismerkkejä nimikkeessä. + + + + Rename + Nimeä uudelleen + + + + New name: + Uusi nimi: + + + + Resume + Resume/start the torrent + + + + + Pause + Pause the torrent + Pysäytä + + + + Delete + Delete the torrent + Poista + + + + Preview file... + Esikatsele... + + + + Limit share ratio... + + + + + Limit upload rate... + Rajoita lähetysnopeus... + + + + Limit download rate... + Rajoita latausnopeus... + + + + Priority + Prioriteetti + + + + Open destination folder + Avaa kohdekansio + + + + Move up + i.e. move up in the queue + + + + + Move down + i.e. Move down in the queue + + + + + Move to top + i.e. Move to top of the queue + + + + + Move to bottom + i.e. Move to bottom of the queue + + + + + Set location... + Aseta kohde... + + + + Force recheck + Pakota tarkistamaan uudelleen + + + + Copy magnet link + Kopioi magnet-linkki + + + + Super seeding mode + super seed -tila + + + + Rename... + Nimeä uudelleen... + + + + Download in sequential order + Lataa järjestyksessä + + + + Download first and last piece first + Lataa ensin ensimmäinen ja viimeinen osa + + + + New... + New label... + Uusi... + + + + Reset + Reset label + Palauta + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + + + + + Use global ratio limit + + + + + + + buttonGroup + + + + + Set no ratio limit + + + + + Set ratio limit to + + + + + UsageDisplay + + + Usage: + Käyttö: + + + + displays program version + näyttää ohjelman version + + + + disable splash screen + poista aloituskuva käytöstä + + + + displays this help message + näyttää tämän avusteen + + + + changes the webui port (current: %1) + vaihtaa web-äyttöliittymän portin (nykyinen: %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [tiedostot tai URL:it]: lataa käyttäjän antamat torrentit (valinnainen) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Haluan kiittää seuraavia henkilöitä, jotka ovat vapaaehtoisesti kääntäneet qBittorrentin: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Ota yhteyttä minuun, jos haluat kääntää qBittorentin omalle kielellesi. + + + + addPeerDialog + + + Peer addition + Asiakkaan lisäys + + + + IP + IP + + + + Port + Portti + + + + addTorrentDialog + + + ... + ... + + + + Torrent size: + Torrentin koko: + + + + + Unknown + Tuntematon + + + + Free disk space: + Vapaa levytila: + + + + Label: + Nimike: + + + + Select All + Valitse kaikki + + + + Select None + Poista valinnat + + + + Download in sequential order (slower but good for previewing) + Lataa järjestyksessä (hitaampi, mutta mahdollistaa aikaisemman esikatselun) + + + + Skip file checking and start seeding immediately + Ohita tiedoston tarkistaminen ja aloita jakaminen välittömästi + + + + Add + Lisää + + + + + Do not download + Älä lataa + + + + Add to download list in paused state + Lisää latauslistaan pysäytettynä + + + + Cancel + Peru + + + + Save path: + Tallennuskansio: + + + + Torrent addition dialog + Torrentinlisäämisikkuna + + + + Torrent content: + Torrentin sisältö: + + + + Normal + Normaali + + + + High + Korkea + + + + Maximum + Korkein + + + + authentication + + + Cancel + Peru + + + + Login + Sisäänkirjautuminen + + + + Log in + Kirjaudu sisään + + + + Password: + Salasana: + + + + Tracker: + Seurantapalvelin: + + + + + Tracker authentication + Seurantapalvelimen todennus + + + + Username: + Tunnus: + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Poistamisvahvistus - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Haluatko poistaa valitut torrentit siirtolistalta? + + + + Remember choice + Muista valinta + + + + Also delete the files on the hard disk + Poista tiedostot myös kovalevyltä + + + + createTorrentDialog + + + Cancel + Peru + + + + Torrent Creation Tool + Torrentinluontityökalu + + + + Torrent file creation + Torrent-tiedoston luominen + + + + Add file + Lisää tiedosto + + + + Add folder + Lisää kansio + + + Announce urls (trackers): + Julkaisuosoitteet (seurantapalvelimet): + + + Comment (optional): + Kommentti (valinnainen): + + + Web seeds urls (optional): + Verkkojako-osoitteet (valinnainen): + + + + File or folder to add to the torrent: + Torrentiin lisättävä tiedosto tai kansio: + + + + Tracker URLs: + + + + + Web seeds urls: + + + + + Comment: + Kommentti: + + + + Piece size: + Osakoko: + + + + 32 KiB + 32 KiB + + + + 64 KiB + 64 KiB + + + + 128 KiB + 128 KiB + + + + 256 KiB + 256 KiB + + + + 512 KiB + 512 KiB + + + + 1 MiB + 1 MiB + + + + 2 MiB + 2 MiB + + + + 4 MiB + 4 MiB + + + + Auto + + + + + Private (won't be distributed on DHT network if enabled) + Yksityinen (ei jaeta DHT-verkossa) + + + + Start seeding after creation + Aloita jakaminen luomisen jälkeen + + + + Create and save... + Luo ja tallenna... + + + + Progress: + Edistyminen: + + + + createtorrent + + No input path set + Lähdekansiota ei ole asetettu + + + Please type an input path first + Anna ensin lähdekansio + + + Select destination torrent file + Valitse kohde-torrent-tiedosto + + + Torrent creation + Torrentin luominen + + + Torrent Files + Torrent-tiedostot + + + Torrent was created successfully: + Torrent luotiin: + + + Select a folder to add to the torrent + Valitse kohdekansio + + + Please type an announce URL + Anna julkaisusoite + + + Torrent creation was unsuccessful, reason: %1 + Torrentin luominen epäonnistui: %1 + + + Announce URL: + Tracker URL + Julkaisuosoite: + + + Please type a web seed url + Anna verkkojako-osoite + + + Web seed URL: + Verkkojako-osoite: + + + Select a file to add to the torrent + Valitse torrentiin lisättävä tiedosto + + + Created torrent file is invalid. It won't be added to download list. + Luotu torrentti ei kelpaa. Sitä ei lisätä latauslistaan. + + + + downloadFromURL + + + Cancel + Peru + + + + Download + Lataa + + + + Download from urls + Lataa URL-osoitteista + + + + Add torrent links + + + + + Both HTTP and Magnet links are supported + + + + Download Torrents from URLs + Lataa torrentteja URL-osoitteista + + + Only one URL per line + Yksi URL riville + + + + No URL entered + Et antanut URL-osoitetta + + + + Please type at least one URL. + Anna vähintään yksi URL-osoite. + + + + downloadThread + + I/O Error + I/O-virhe + + + The remote host name was not found (invalid hostname) + Kohdekoneen nimeä ei löytynyt (epäkelpo palvelinnimi) + + + The operation was canceled + Toiminto peruttiin + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Vastapää katkaisi yhteyden ennenaikaisesti, ennenkuin vastaus saatiin eheänä ja käsiteltiin + + + The connection to the remote server timed out + Yhteys vastapäähän aikakatkaistiin + + + SSL/TLS handshake failed + SSL/TLS-kättely epäonnistui + + + The remote server refused the connection + Vastapää ei hyväksynyt yhteyttä + + + The connection to the proxy server was refused + Välityspalvelin ei hyväksynyt yhteyttä + + + The proxy server closed the connection prematurely + Välityspalvelin sulki yhteyden ennenaikaisesti + + + The proxy host name was not found + Välityspalvelimen nimeä ei voitu ratkaista + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Yhteys välityspalvelimeen aikakatkaistiin tai välityspalvlein ei vastannut ajoissa lähetettyyn pyyntöön + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Välityspalvelin vaatii autentikoinnin vastatakseen pyyntöön mutta ei hyväksynyt annettuja tietoja + + + The access to the remote content was denied (401) + Pääsy sisältöön estettiin (401) + + + The operation requested on the remote content is not permitted + Sisältöön pyydetty toiminto ei ole sallittu + + + The remote content was not found at the server (404) + Sisältöä ei löytynyt palvelimelta (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Palvelin vaatii autentikoinnin tarjotakseen sisältöä mutta annettuja tietoja ei hyyväksytty + + + The Network Access API cannot honor the request because the protocol is not known + Verkkoyhteys-API ei palvele koska yhteyskäytäntöä ei tunneta + + + The requested operation is invalid for this protocol + Pyydetty toiminto ei käy tällä yhteyskäytännöllä + + + An unknown network-related error was detected + Tuntematon verkko-ongelma + + + An unknown proxy-related error was detected + Tuntematon välityspalvelinongelma + + + An unknown error related to the remote content was detected + Tuntematon sisältöongelma + + + A breakdown in protocol was detected + Virhe yhteyskäytännössä + + + Unknown error + Tuntematon virhe + + + + engineSelect + + + Search plugins + Hakuliitännäiset + + + + Installed search engines: + Asennetut hakuliitännäiset: + + + + Name + Nimi + + + + Url + URL + + + + + Enabled + Käytössä + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Voit hakea uusia hakukoneliitännäisiä täältä: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Asenna uusi + + + + Check for updates + Tarkista päivitykset + + + + Close + Sulje + + + Enable + Käytä + + + Disable + Älä käytä + + + + Uninstall + Poista + + + + engineSelectDlg + + + Uninstall warning + Poistovaroitus + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Joitakin liitännäisiä ei voitu poistaa, koska ne tulevat qBittorrentin mukana. + Vain asennettuja liitännäisiä voi poistaa. +Kyseiset liitänäiset poistettiin kuitenkin käytöstä. + + + + Uninstall success + Poisto onnistui + + + + Select search plugins + Valitse hakuliitännäiset + + + + qBittorrent search plugins + qBittorrentin hakuliitännäiset + + + + + + + + Search plugin install + Hakuliitännäisen asennus + + + + + + Yes + Kyllä + + + + + + + No + Ei + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Uudempi versio hakuliitännäisestä %1 on jo asennettu. + + + + + + + Search plugin update + Hakuliitännäisen päivitys + + + + + Sorry, update server is temporarily unavailable. + Päivityspalvelin ei ole tällä hetkellä saavutettavissa. + + + + All your plugins are already up to date. + Kaikki liitännäiset ovat ajan tasalla. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + Hakuliitännäisen %1 päivitys epäonnistui. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Hakuliitännäisen %1 asennus epäonnistui. + + + + All selected plugins were uninstalled successfully + Kaikki valitut liitännäiset poistettiin + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + Hakuliitännäinen %1 päivitettiin. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Hakuliitännäinen %1 asennettiin. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Hakuliitännäisen %1 asennus epäonnistui. + + + + New search engine plugin URL + Uusi hakukoneliitännäisen osoite + + + + URL: + URL: + + + + misc + + + B + bytes + B + + + + GiB + gibibytes (1024 mibibytes) + GiB + + + + KiB + kibibytes (1024 bytes) + KiB + + + + MiB + mebibytes (1024 kibibytes) + MiB + + + + TiB + tebibytes (1024 gibibytes) + TiB + + + + + + + + + Unknown + Tuntematon + + + + %1h %2m + e.g: 3hours 5minutes + %1 h %2 min + + + + %1d %2h + e.g: 2days 10hours + %1 d %2 h + + + + Unknown + Unknown (size) + Tuntematon + + + + qBittorrent will shutdown the computer now because all downloads are complete. + + + + + < 1m + < 1 minute + alle minuutti + + + + %1m + e.g: 10minutes + %1 min + + + + options_imp + + + + + + Choose a save directory + Valitse tallennuskansio + + + + Add directory to scan + Lisää seurattava hakemisto + + + + Folder is already being watched. + Kansio on jo seurannassa. + + + + Folder does not exist. + Kansiota ei ole. + + + + Folder is not readable. + Kansiota ei voida lukea. + + + + Failure + Virhe + + + + Failed to add Scan Folder '%1': %2 + Kansiota "%1" ei voitu lisätä seurattavien joukkoon: %2 + + + + + Choose export directory + Valitse vientihakemisto + + + + + Choose an ip filter file + Valitse IP-suodatintiedosto + + + + + Filters + Suotimet + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + + + + + Failed to parse the provided IP filter + + + + + Successfully refreshed + + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + + pluginSourceDlg + + + Plugin source + Lähde + + + + Search plugin source: + Lähde: + + + + Local file + Paikallinen tiedosto + + + + Web link + Web-linkki + + + + preview + + + Cancel + Peru + + + + File preview + Tiedoston esikatselu + + + + Preview + Esikatsele + + + + Preview selection + Esikatsele valinta + + + + The following files support previewing, <br>please select one of them: + Seuraavia tiedostoja voi esiketsella, <br>valitse yksi seuraavista: + + + + previewSelect + + Preview impossible + Esikatselu ei ole mahdollista + + + Sorry, we can't preview this file + Tätä tiedostoa ei voi esikatsella + + + Name + Nimi + + + Size + Koko + + + Progress + Edistyminen + + + + search_engine + + + + Search + Etsi + + + + Status: + Tila: + + + + Stopped + Pysäytetty + + + + Download + Lataa + + + + Go to description page + + + + + Search engines... + Hakukoneet... + + + + torrentAdditionDialog + + + + + Choose save path + Valitse tallennuskansio + + + + Could not create the save path + Tallennuskansion luominen ei onnistunut + + + + Empty save path + Ei tallennuskansiota + + + + Invalid file selection + Virheellinen tiedostovalinta + + + + Please enter a save path + Anna tallennuskansio + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 torrentin lataamisen jälkeen) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (tarvitaan %1 lisää lataamiseen) + + + + Save path creation error + Tallennuskansion luominen ei onnistunut + + + + Unable to decode magnet link: + Magnet-linkin purkaminen ei onnistunut: + + + + Magnet Link + Magnet-linkki + + + + + Unable to decode torrent file: + Torrent-tiedoston purkaminen ei onnistunut: + + + + Rename... + Nimeä uudelleen... + + + + Rename the file + Nimeä tiedosto uudelleen + + + + New name: + Uusi nimi: + + + + + The file could not be renamed + Tiedostoa ei voitu nimetä uudelleen + + + + This file name contains forbidden characters, please choose a different one. + Tiedostonimi sisältää kiellettyjä merkkejä, valitse toinen. + + + + + This name is already in use in this folder. Please use a different name. + Nimi on jo käytössä tässä kansiossa. Käytä toista nimeä. + + + + The folder could not be renamed + Kansiota ei voitu nimetä uudelleen + + + + Invalid label name + Virheellinen nimike + + + + Please don't use any special characters in the label name. + Älä käytä erikoismerkkejä nimikkeessä. + + + + Seeding mode error + Jakamistilavirhe + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Valitsit tiedoston tarkistamisen ohittamisen. Paikalliset tiedostot eivät näytä olevan nykyisessä kohdekansiossa. Ota tämä piirre käytöstä tai päivitä tallennuspolku. + + + + You must select at least one file in the torrent + Valitse ainakin yksi torrent-tiedosto + + + + Priority + Prioriteetti + + + diff --git a/src/lang/qbittorrent_fr.qm b/src/lang/qbittorrent_fr.qm new file mode 100644 index 0000000000000000000000000000000000000000..99d0a0d83dbc44cf1e5f21d3a8c40593a9e1106c GIT binary patch literal 125389 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 + + + + AboutDlg + + + About qBittorrent + A Propos de qBittorrent + + + + About + A Propos + + + + Author + Auteur + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Un client Bittorrent programmé C++, basé sur la bibliothèque Qt4 </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">et la biliothèque libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Site officiel :</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum :</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC :</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent sur Freenode</span></p></body></html> + + + + Name: + Nom : + + + + Country: + Nationalité : + + + + E-mail: + Courriel : + + + + Christophe Dumez + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Un client BitTorrent avancé programmé en C++, basé sur la bibliothèque Qt4 et libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Site Officiel :</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent sur Freenode</span></p></body></html> + + + + France + + + + + Translation + Traduction + + + + License + Licence + + + + <h3><b>qBittorrent</b></h3> + + + + + chris@qbittorrent.org + + + + + Thanks to + Remerciements + + + + AdvancedSettings + + Property + Propriété + + + Value + Valeur + + + + Disk write cache size + Taille du tampon disque + + + + MiB + Mo + + + + Outgoing ports (Min) [0: Disabled] + Ports sortants (Min) [0: Désactivé] + + + + Outgoing ports (Max) [0: Disabled] + Ports sortants (Max) [0: Désactivé] + + + + Recheck torrents on completion + Revérifier les torrents lorsqu'ils sont terminés + + + + Transfer list refresh interval + Intervalle de rafraîchissement de la liste de transfert + + + + ms + milliseconds + + + + + Setting + Paramètre + + + + Value + Value set for this setting + Valeur + + + + Resolve peer countries (GeoIP) + Afficher le pays des peers (GeoIP) + + + + Resolve peer host names + Afficher le nom d'hôte des peers + + + + Maximum number of half-open connections [0: Disabled] + Nombre maximum de connexions à moitié ouvertes [0: Désactivé] + + + + Strict super seeding + Super seeding strict + + + + Network Interface (requires restart) + Interface réseau (redémarrage requis) + + + + Exchange trackers with other peers + Echange de trackers avec les autres utilisateurs + + + + Any interface + i.e. Any network interface + N'importe laquelle + + + + IP Address to report to trackers (requires restart) + Adresse IP annoncée aux trackers (Redémarrage requis) + + + + Display program on-screen notifications + Afficher les messages de notification à l'écran + + + Display program notification balloons + Afficher les messages de notification à l'écran + + + + Enable embedded tracker + Activer the tracker intégré + + + + Embedded tracker port + Port du tracker intégré + + + + Check for software updates + Vérifier la disponibilité de mises à jour + + + + Use system icon theme + Utiliser le thème d'icônes du système + + + + Confirm torrent deletion + Confirmer la suppression de torrents + + + Display program notification baloons + Afficher les messages de notification à l'écran + + + + Ignore transfer limits on local network + Ignorer les limites de transfert sur le réseau local + + + Include TCP/IP overhead in transfer limits + Inclure les entêtes TCP/IP dans les limites de transfert + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Outils de téléchargement RSS + + + + Enable the automated RSS downloader + activer le téléchargement depuis le RSS + + + + Download rules + Règles de téléchargement + + + + Rule definition + Définition de la règle + + + + Must contain: + Doit contenir : + + + + Must not contain: + Ne doit pas contenir : + + + + Use regular expressions + Utiliser des expressions régulières + + + + Import... + Importer... + + + + Export... + Exporter... + + + + ... + ... + + + + Assign label: + Catégorie : + + + + Save to a different directory + Sauvegarder dans un dossier différent + + + + Save to: + Destination : + + + + Apply rule to feeds: + Appliquer la règle aux flux : + + + + Matching RSS articles + Articles RSS correspondants + + + + New rule name + Nouveau nom pour la règle + + + + Please type the name of the new download rule. + Veuillez entrer le nom de la nouvelle règle de téléchargement. + + + + + Rule name conflict + Conflit dans les noms de règle + + + + + A rule with this name already exists, please choose another name. + Une règle avec ce nom existe déjà, veuillez en choisir un autre. + + + + Are you sure you want to remove the download rule named %1? + Etes-vous certain de vouloir supprimer la règle nommée %1 ? + + + + Are you sure you want to remove the selected download rules? + Etes-vous certain de vouloir supprimer les règles sélectionnées ? + + + + Rule deletion confirmation + Confirmation de la suppression + + + + Destination directory + Répertoire de destination + + + + Invalid action + Action invalide + + + + The list is empty, there is nothing to export. + La liste est vide, il n'y a rien à exporter. + + + + Where would you like to save the list? + Où désirez-vous sauvegarder cette liste ? + + + + Rules list (*.rssrules) + Liste de règles (*.rssrules) + + + + I/O Error + Erreur E/S + + + + Failed to create the destination file + Impossible de créer le fichier de destination + + + + Please point to the RSS download rules file + Veuillez indiquer le fichier contenant les règles de téléchargement RSS + + + + Rules list (*.rssrules *.filters) + Liste de règles (*.rssrules *.filters) + + + + Import Error + Erreur lors de l'import + + + + Failed to import the selected rules file + Impossible d'importer le fichier de règles sélectionné + + + + Add new rule... + Ajouter une nouvelle règle... + + + + Delete rule + Supprimer la règle + + + + Rename rule... + Renommer la règle... + + + + Delete selected rules + Supprimer les règles sélectionnées + + + + Rule renaming + Renommage de la règle + + + + Please type the new rule name + Veuillez enter le nouveau nom pour la règle + + + + Regex mode: use Perl-like regular expressions + Mode regex : Utiliser des expressions régulières similaires à celles de Perl + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Mode simplifié : vous pouvez utiliser<ul><li>? pour remplacer n'importe quel caractère</li><li>* pour remplacer zéro ou plusieurs caractères</li><li>Les espaces sont considérés équivalent à des opérateurs ET</li></ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Mode simplifié : vous pouvez utiliser<ul><li>? pour remplacer n'importe quel caractère</li><li>* pour remplacer zéro ou plusieurs caractères</li><li>| est utilisé comme opérateur OU</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 a atteint le ratio maximum défini. + + + Removing torrent %1... + Suppression du torrent %1... + + + Pausing torrent %1... + Mise en pause du torrent %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent écoute sur le port : TCP/%1 + + + UPnP support [ON] + Support UPnP [ON] + + + UPnP support [OFF] + Support UPNP [OFF] + + + NAT-PMP support [ON] + Support NAT-PMP [ON] + + + NAT-PMP support [OFF] + Support NAT-PMP [OFF] + + + HTTP user agent is %1 + User agent HTTP: %1 + + + Using a disk cache size of %1 MiB + Utilisation d'un tampon disque de %1 Mo + + + DHT support [ON], port: UDP/%1 + Support DHT [ON], port : UDP/%1 + + + DHT support [OFF] + Support DHT [OFF] + + + PeX support [ON] + Support PeX [ON] + + + PeX support [OFF] + Support PeX [OFF] + + + Restart is required to toggle PeX support + Un redémarrage est nécessaire afin de changer l'état du support PeX + + + Local Peer Discovery [ON] + Découverte locale de sources [ON] + + + Local Peer Discovery support [OFF] + Découverte locale de sources [OFF] + + + Encryption support [ON] + Support cryptage [ON] + + + Encryption support [FORCED] + Support cryptage [Forcé] + + + Encryption support [OFF] + Support cryptage [OFF] + + + The Web UI is listening on port %1 + L'interface Web ecoute sur le port %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Erreur interface Web - Impossible d'associer l'interface Web au port %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' a été supprimé de la liste et du disque dur. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' a été supprimé de la liste. + + + '%1' is not a valid magnet URI. + '%1' n'est pas un lien magnet valide. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' est déjà présent dans la liste de téléchargement. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' a été relancé. (relancement rapide) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' a été ajouté à la liste de téléchargement. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Impossible de décoder le torrent : '%1' + + + This file is either corrupted or this isn't a torrent. + Ce fichier est corrompu ou il ne s'agit pas d'un torrent. + + + Note: new trackers were added to the existing torrent. + Remarque : Les nouveaux trackers ont été ajoutés au torrent existant. + + + Note: new URL seeds were added to the existing torrent. + Remarque : Les nouvelles sources HTTP sont été ajoutées au torrent existant. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>a été bloqué par votre filtrage IP</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>a été banni suite à l'envoi de données corrompues</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Téléchargement récursif du fichier %1 au sein du torrent %2 + + + Unable to decode %1 torrent file. + Impossible de décoder le torrent %1. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP : Echec de mapping du port, message : %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP : Réussite du mapping de port, message : %1 + + + Fast resume data was rejected for torrent %1, checking again... + Le relancement rapide a échoué pour le torrent %1, revérification... + + + Reason: %1 + Raison : %1 + + + Error: The torrent %1 does not contain any file. + Erreur : Le torrent %1 ne contient aucun fichier. + + + Torrent name: %1 + Nom du torrent : %1 + + + Torrent size: %1 + Taille du torrent : %1 + + + Save path: %1 + Chemin de sauvegarde : %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Le torrent a été téléchargé en %1. + + + Thank you for using qBittorrent. + Nous vous remercions d'utiliser qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 est terminé + + + An I/O error occured, '%1' paused. + Une erreur E/S s'est produite, '%1' a été mis en pause. + + + File sizes mismatch for torrent %1, pausing it. + Les tailles de fichiers ne correspondent pas pour le torrent %1, mise en pause. + + + Url seed lookup failed for url: %1, message: %2 + Le contact de la source HTTP a échoué à l'url : %1, message : %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Téléchargement de '%1', veuillez patienter... + + + + ConsoleDlg + + qBittorrent log viewer + Journal d'exécution + + + General + Général + + + Blocked IPs + IPs bloquées + + + + CookiesDlg + + + Cookies management + Gestion des cookies + + + + Key + As in Key/Value pair + Clée + + + + Value + As in Key/Value pair + Valeur + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Les valeurs habituelles des clées des cookies sont : '%1', '%2'. +Vous pouvez récupérer ces informations à partir des préférences de votre navigateur Internet. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + Votre DNS dynamique à été mis à jour avec succès. + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Erreur DNS dynamique : Le service est temporairement indisponible, un nouvel essai sera tenté dans 30 minutes. + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Erreur DNS (dynamique) : the nom de domaine fourni n'existe pas pour ce compte. + + + + Dynamic DNS error: Invalid username/password. + Erreur DNS (dynamique) : Nom d'utilisateur / mot de passe invalide. + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Erreur DNS (dynamique) : qBittorrent a été bloqué par le service, veuillez rapporter le problème via http://bugs.qbittorrent.org. + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Erreur DNS (dynamique) : Le service a retourné %1, veuillez rapporter le problème via http://bugs.qbittorrent.org. + + + + Dynamic DNS error: Your username was blocked due to abuse. + Erreur DNS (dynamique) : Votre nom d'utilisateur a été bloqué pour abus. + + + + Dynamic DNS error: supplied domain name is invalid. + Erreur DNS (dynamique) : Le nom de domaine fourni est invalide. + + + + Dynamic DNS error: supplied username is too short. + Erreur DNS (dynamique) : Le nom d'utilisateur fourni est trop court. + + + + Dynamic DNS error: supplied password is too short. + Erreur DNS (dynamique) : Le mot de passe fourni est trop court. + + + + DownloadThread + + + + I/O Error + Erreur E/S + + + + The remote host name was not found (invalid hostname) + Hôte distant introuvable (Nom d'hôte invalide) + + + + The operation was canceled + Opération annulée + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Connexion fermée prématurément par le serveur distant, avant la réception complète de sa réponse + + + + The connection to the remote server timed out + Délai de connexion au serveur distant écoulée + + + + SSL/TLS handshake failed + Erreur poignée de main SSL/TLS + + + + The remote server refused the connection + Connexion refusée par le serveur distant + + + + The connection to the proxy server was refused + Connexion refusée par le serveur mandataire + + + + The proxy server closed the connection prematurely + Connexion fermée prématurément par le serveur mandataire + + + + The proxy host name was not found + Nom d'hôte du serveur mandataire introuvable + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Délai de connexion au serveur mandataire écoulée + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Echec d'authentification auprès du serveur mandataire + + + + The access to the remote content was denied (401) + Accès au contenu distant refusé (401) + + + + The operation requested on the remote content is not permitted + L'opération sur le contenu distant n'est pas permise + + + + The remote content was not found at the server (404) + Contenu distant introuvable (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Echec d'authentification avec le serveur distant + + + + The Network Access API cannot honor the request because the protocol is not known + Protocole inconnu + + + + The requested operation is invalid for this protocol + Opération invalide pour ce protocole + + + + An unknown network-related error was detected + Erreur inconnue relative au réseau + + + + An unknown proxy-related error was detected + Erreur inconnue relative au serveur mandataire + + + + An unknown error related to the remote content was detected + Erreur inconnue relative au serveur distant + + + + A breakdown in protocol was detected + Erreur du protocole + + + + Unknown error + Erreur inconnue + + + + EventManager + + + + Working + Fonctionne + + + + Updating... + Mise à jour... + + + + + Not working + Indisponible + + + + + Not contacted yet + Pas encore contacté + + + + + this session + cette session + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Complet depuis %1 + + + + %1 max + e.g. 10 max + %1 max + + + + + %1/s + e.g. 120 KiB/s + %1/s + + + + ExecutionLog + + + General + Général + + + + Blocked IPs + IPs bloquées + + + + FeedDownloader + + RSS Feed downloader + Téléchargement du flux RSS + + + RSS feed: + Flux RSS : + + + Feed name + Nom du flux + + + Automatically download torrents from this feed + Télécharger automatiquement les torrents depuis ce flux + + + Download filters + Filtres pour le téléchargement + + + Filters: + Filtres : + + + Filter settings + Attributs du filtre + + + Matches: + Contient : + + + Does not match: + Ne contient pas : + + + Destination folder: + Dossier de destination : + + + ... + ... + + + Filter testing + test du flitre + + + Torrent title: + Titre du torrent : + + + Result: + Résultat : + + + Test + Test + + + Import... + Importer... + + + Export... + Exporter... + + + Rename filter + Renommer le filtre + + + Remove filter + Supprimer le filtre + + + Add filter + Ajouter un filtre + + + + FeedDownloaderDlg + + New filter + Nouveau filtre + + + Please choose a name for this filter + Veuillez choisir un nom pour ce filtre + + + Filter name: + Nom du filtre : + + + Invalid filter name + Nom de filtre non valide + + + The filter name cannot be left empty. + Le nom du filtre ne peut pas être vide. + + + This filter name is already in use. + Ce nom de filtre est déjà utilisé. + + + Choose save path + Choix du répertoire de destination + + + Filter testing error + Essai du filtre impossible + + + Please specify a test torrent name. + Veuillez spécifier un exemple de nom de torrent. + + + matches + Reconnu + + + does not match + Non reconnu + + + Select file to import + Sélection du fichier à importer + + + Filters Files + Fichiers de filtrage + + + Import successful + Importation réussie + + + Filters import was successful. + L'importation s'est correctement déroulée. + + + Import failure + Echec importation + + + Filters could not be imported due to an I/O error. + Les filtres n'ont pas pu être importés suite à une erreur E/S. + + + Select destination file + Sélectionner le fichier de destination + + + Export successful + Exportation réussie + + + Filters export was successful. + L'exportation des filtres s'est correctement déroulée. + + + Export failure + Echec de l'exportation + + + Filters could not be exported due to an I/O error. + Les filtres n'ont pas pu être exportés suite à une erreur E/S. + + + + FeedList + + Unread + Non lu + + + + FeedListWidget + + + RSS feeds + Flux RSS + + + + Unread + Non lu + + + + GUI + + Open Torrent Files + Ouvrir fichiers torrent + + + Torrent Files + Fichiers Torrent + + + Transfers + Transferts + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Vitesse DL : %1 Ko/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Vitesse UP : %1 Ko/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Le téléchargement de %1 est terminé. + + + I/O Error + i.e: Input/Output Error + Erreur E/S + + + Search + Recherche + + + Torrent file association + Association aux fichiers Torrent + + + Set the password... + Définir le mot de passe... + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent n'est pas l'application utilisée pour ouvrir les fichiers torrent ou les liens Magnet. +Voulez-vous corriger cela ? + + + Password update + Mise à jour du mot de passe + + + The UI lock password has been successfully updated + Le mot de passe de verrouillage a été mis à jour + + + Transfers (%1) + Transferts (%1) + + + Download completion + Fin du téléchargement + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + En erreur E/S s'est produite pour le torrent %1 +Raison : %2 + + + Alt+2 + shortcut to switch to third tab + Alt+é + + + Recursive download confirmation + Confirmation pour téléchargement récursif + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Le torrent %1 contients des fichiers torrents, desirez-vous les mettre en téléchargement ? + + + Yes + Oui + + + No + Non + + + Never + Jamais + + + A newer version is available + Une nouvelle version est disponible + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Une nouvelle version de qBittorrent est disponible sur Sourceforge. +Voulez-vous effectuer la mise à jour à la version %1 ? + + + Impossible to update qBittorrent + Impossible de mettre à jour qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent n'a pas pu être mis à jour, raison : %1 + + + UI lock password + Mot de passe de verrouillage + + + Please type the UI lock password: + Veuillez entrer le mot de passe de verrouillage : + + + Invalid password + Mot de passe invalide + + + The password is invalid + Le mot de passe fourni est invalide + + + Exiting qBittorrent + Fermeture de qBittorrent + + + Always + Toujours + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Réception : %2/s, Envoi : %3/s) + + + Alt+1 + shortcut to switch to first tab + Alt+& + + + Url download error + Erreur téléchargement url + + + Couldn't download file at url: %1, reason: %2. + Impossible de télécharger le fichier à l'url : %1, raison : %2. + + + Alt+3 + shortcut to switch to fourth tab + Alt+" + + + Global Upload Speed Limit + Limite globale de la vitesse d'envoi + + + Global Download Speed Limit + Limite globale de la vitesse de réception + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Certains fichiers sont en cours de transfert. +Etes-vous certain de vouloir quitter qBittorrent ? + + + Options were saved successfully. + Préférences sauvegardées avec succès. + + + + GeoIP + + Australia + Australie + + + Argentina + Argentine + + + Austria + Autriche + + + United Arab Emirates + Emirats Arabes Unis + + + Brazil + Brésil + + + Bulgaria + Bulgarie + + + Belarus + Biélorussie + + + Belgium + Belgique + + + Bosnia + Bosnie + + + Canada + Canada + + + Czech Republic + République Tchèque + + + China + Chine + + + Costa Rica + Costa Rica + + + Switzerland + Suisse + + + Germany + Allemagne + + + Denmark + Danemark + + + Algeria + Algérie + + + Spain + Espagne + + + Egypt + Egypte + + + Finland + Finlande + + + France + France + + + United Kingdom + Royaume Uni + + + Greece + Grêce + + + Georgia + Géorgie + + + Hungary + Hongrie + + + Croatia + Croatie + + + Italy + Italie + + + India + Inde + + + Israel + Israël + + + Ireland + Irelande + + + Iceland + Islande + + + Indonesia + Indonésie + + + Japan + Japon + + + South Korea + Corée du Sud + + + Luxembourg + Luxembourg + + + Malaysia + Malaisie + + + Mexico + Mexique + + + Serbia + Serbie + + + Morocco + Maroc + + + Netherlands + Pays Bas + + + Norway + Norvège + + + New Zealand + Nouvelle-Zélande + + + Portugal + Portugal + + + Poland + Pologne + + + Philippines + Philippines + + + Russia + Russie + + + Romania + Roumanie + + + France (Reunion Island) + France (île de la réunion) + + + Saudi Arabia + Arabie Saoudite + + + Sweden + Suède + + + Slovakia + Slovaquie + + + Singapore + Singapour + + + Slovenia + Slovénie + + + Taiwan + Taïwan + + + Turkey + Turquie + + + Thailand + Thaïlande + + + USA + USA + + + Ukraine + Ukraine + + + South Africa + Afrique du Sud + + + + HeadlessLoader + + + Information + Informations + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Pour contrôler qBittorrent, accéder à l'interface Web via http://localhost:%1 + + + + The Web UI administrator user name is: %1 + Le nom d'utilisateur de l'administrateur de l'interface Web est : %1 + + + + The Web UI administrator password is still the default one: %1 + Le mot de passe de l'administrateur de l'interface Web est toujours celui par défaut : %1 + + + + This is a security risk, please consider changing your password from program preferences. + Ceci peut être dangereux, veuillez penser à changer votre mot de passe dans les options. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + Votre addresse IP a été bloquée car vous avez dépassé le nombre de tentative d'authentification autorisé. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + R : %1/s - T : %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + E : %1/s - T : %2 + + + + HttpServer + + + File + Fichier + + + + Edit + Edition + + + + Help + Aide + + + Delete from HD + Supprimer du disque dur + + + + Download Torrents from their URL or Magnet link + Téléchargement de torrents depuis leur URL ou lien Magnet + + + + Only one link per line + Un seul lien par ligne + + + + Download local torrent + Téléchargement d'un torrent local + + + + Torrent files were correctly added to download list. + Les fichiers torrents ont été mis en téléchargement. + + + + Point to torrent file + Indiquer un fichier torrent + + + + Download + Télécharger + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Etes-vous certain de vouloir supprimer les torrents sélectionnés de la liste et du disque dur ? + + + + Download rate limit must be greater than 0 or disabled. + La limite pour la vitesse de réception doit être supérieure à 0 ou désactivée. + + + + Upload rate limit must be greater than 0 or disabled. + La limite pour la vitesse d'envoi doit être supérieure à 0 ou désactivée. + + + + Maximum number of connections limit must be greater than 0 or disabled. + Le nombre maximum de connexions doit être supérieur à 0 ou désactivé. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Le nombre maximum de connexions par torrent doit être supérieur à 0 ou désactivé. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Le nombre maximum de slots d'envoi par torrent doit être supérieur à 0 ou désactivé. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Impossible de sauvegarder les préférences, qBittorrent est probablement injoignable. + + + + Language + Langue + + + + Downloaded + Is the file downloaded or not? + Téléchargé + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Le port utilisé pour les connexions entrantes doit être compris entre 1025 et 65535. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Le port utilisé pour l'interface Web doit être compris entre 1025 et 65535. + + + + The Web UI username must be at least 3 characters long. + Le nom d'utilisateur pour l'interface Web doit contenir au moins 3 caractères. + + + + The Web UI password must be at least 3 characters long. + Le mot de passe pour l'interface Web doit contenir au moins 3 caractères. + + + + Save + Sauvegarder + + + + qBittorrent client is not reachable + Le logiciel qBittorrent est injoignable + + + + HTTP Server + Serveur HTTP + + + + The following parameters are supported: + Les paramètres suivants sont pris en charge : + + + + Torrent path + Chemin du torrent + + + + Torrent name + Nom du torrent + + + + LegalNotice + + + Legal Notice + Information légale + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent est un logiciel de partage de fichiers. Lors de l'ajout d'un torrent, ses données seront mises à la disposition des autres utilisateurs par le biais de leur envoi ("upload"). Vous seul pourrez être tenu responsable du contenu que vous partagez. + +Ce message d'avertissement ne sera plus affiché. + + + + Press %1 key to accept and continue... + Appuyez sur la touche %1 pour accepter et continuer... + + + + Legal notice + Information légale + + + + Cancel + Annuler + + + + I Agree + J'accepte + + + + LineEdit + + + Clear the text + Effacer le texte + + + + MainWindow + + + &Edit + &Edition + + + + &Tools + Ou&tils + + + + &File + &Fichier + + + + &Help + &Aide + + + + &View + A&ffichage + + + &Add File... + &Ajouter un fichier... + + + E&xit + &Quitter + + + + &Options... + &Options... + + + + &About + &A Propos + + + + &Pause + Mettre en &pause + + + + &Delete + &Supprimer + + + + P&ause All + Tout &mettre en pause + + + + &Resume + &Démarrer + + + + &Add torrent file... + &Ajouter un fichier torrent... + + + + + Exit + Quitter + + + + R&esume All + Dé&marrer + + + + Visit &Website + &Visiter le site officiel + + + Add &URL... + Ajouter une &URL... + + + + Torrent &creator + &Créateur de torrent + + + + Report a &bug + Signaler un &bogue + + + + Set upload limit... + Définir limite d'envoi... + + + + Set download limit... + Définir limite de réception... + + + + &Documentation + &Documentation + + + + Set global download limit... + Définir limite globale de réception... + + + + Set global upload limit... + Définir limite globale d'envoi... + + + + Exit qBittorrent + Quitter qBittorrent + + + + Suspend system + Mettre le système en veille + + + + Shutdown system + Arrêter le système + + + + Disabled + Désactivé + + + &Log viewer... + &Journal d'exécution... + + + Log viewer + Journal d'exécution + + + Shutdown computer when downloads complete + Eteindre l'ordinateur lors que les téléchargements sont terminés + + + + + Lock qBittorrent + Verrouiller qBittorrent + + + + Ctrl+L + Ctrl+L + + + Shutdown qBittorrent when downloads complete + Fermer qBittorrent lorsque les téléchargements sont terminés + + + + Import existing torrent... + Importer un torrent existant... + + + + Import torrent... + Importer un torrent... + + + + Donate money + Faire un don + + + + If you like qBittorrent, please donate! + Si vous aimez qBittorrent, faites-un don SVP ! + + + + Execution &Log + Journa&l d'exécution + + + + + Execution Log + Journal d'exécution + + + + + Alternative speed limits + Vitesses limites alternatives + + + + &RSS reader + Lecteur &RSS + + + + Search &engine + &Moteur de recherche + + + + Top &tool bar + Barre d'ou&tils + + + + Auto-Shutdown on downloads completion + Extinction auto en fin de téléchargement + + + + Add &link to torrent... + Ajouter &lien vers un torrent... + + + + Display top tool bar + Afficher la barre d'outils + + + + &Speed in title bar + &Vitesses dans le titre de la fenêtre + + + + Show transfer speed in title bar + Afficher les vitesses de transfert dans le titre de la fenêtre + + + Preview file + Prévisualiser fichier + + + Clear log + Effacer journal + + + + Decrease priority + Diminuer la priorité + + + + Increase priority + Augmenter la priorité + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + Définir le mot de passe... + + + + Transfers + Transferts + + + + Torrent file association + Association aux fichiers Torrent + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent n'est pas l'application utilisée pour ouvrir les fichiers torrent ou les liens Magnet. +Voulez-vous corriger cela ? + + + + + + UI lock password + Mot de passe de verrouillage + + + + + + Please type the UI lock password: + Veuillez entrer le mot de passe de verrouillage : + + + + The password should contain at least 3 characters + The mot de passe doit contenir au moins 3 caractères + + + + Password update + Mise à jour du mot de passe + + + + The UI lock password has been successfully updated + Le mot de passe de verrouillage a été mis à jour + + + + RSS + RSS + + + + Search + Recherche + + + + Transfers (%1) + Transferts (%1) + + + + Download completion + Fin du téléchargement + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Le téléchargement de %1 est terminé. + + + + I/O Error + i.e: Input/Output Error + Erreur E/S + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + En erreur E/S s'est produite pour le torrent %1 +Raison : %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+& + + + + Alt+2 + shortcut to switch to third tab + Alt+é + + + + Ctrl+F + shortcut to switch to search tab + + + + + Alt+3 + shortcut to switch to fourth tab + Alt+" + + + + Recursive download confirmation + Confirmation pour téléchargement récursif + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Le torrent %1 contients des fichiers torrents, desirez-vous les mettre en téléchargement ? + + + + + Yes + Oui + + + + + No + Non + + + + Never + Jamais + + + + Url download error + Erreur téléchargement URL + + + + Couldn't download file at url: %1, reason: %2. + Impossible de télécharger le fichier à l'url : %1, raison : %2. + + + + Global Upload Speed Limit + Limite globale de la vitesse d'envoi + + + + Global Download Speed Limit + Limite globale de la vitesse de réception + + + + + Invalid password + Mot de passe invalide + + + + The password is invalid + Le mot de passe fourni est invalide + + + + Exiting qBittorrent + Fermeture de qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Certains fichiers sont en cours de transfert. +Etes-vous certain de vouloir quitter qBittorrent ? + + + + Always + Toujours + + + + Open Torrent Files + Ouvrir fichiers torrent + + + + Torrent Files + Fichiers Torrent + + + + Options were saved successfully. + Préférences sauvegardées avec succès. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Vitesse DL : %1 Ko/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Vitesse UP : %1 Ko/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Réception : %2/s, Envoi : %3/s) + + + + A newer version is available + Une nouvelle version est disponible + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Une nouvelle version de qBittorrent est disponible sur Sourceforge. +Voulez-vous effectuer la mise à jour à la version %1 ? + + + + Impossible to update qBittorrent + Impossible de mettre à jour qBittorrent + + + + qBittorrent failed to update, reason: %1 + qBittorrent n'a pas pu être mis à jour, raison : %1 + + + + PeerAdditionDlg + + + Invalid IP + IP Incorrecte + + + + The IP you provided is invalid. + L'IP entrée est incorrecte. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + IP + + + + Connection + Connexion + + + + Client + i.e.: Client application + Logiciel + + + + Progress + i.e: % downloaded + Progression + + + + Down Speed + i.e: Download speed + Vitesse DL + + + + Up Speed + i.e: Upload speed + Vitesse UP + + + + Downloaded + i.e: total data downloaded + Téléchargé + + + + Uploaded + i.e: total data uploaded + Envoyé + + + + Add a new peer... + Ajouter un nouveau peer... + + + + Copy IP + Copier adresse IP + + + + Limit download rate... + Limiter vitesse de réception... + + + + Limit upload rate... + Limiter vitesse d'envoi... + + + + Ban peer permanently + Bannir le peer + + + + + Peer addition + Ajout d'un peer + + + + The peer was added to this torrent. + Le peer a été ajouté pour ce torrent. + + + + The peer could not be added to this torrent. + Le peer n'a pas pu être ajouté pour ce torrent. + + + + Are you sure? -- qBittorrent + Etes vous sûr ? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Etes-vous sûr de vouloir bannir les peers sélectionnés? + + + + &Yes + &Oui + + + + &No + &Non + + + + Manually banning peer %1... + Bannissement manuel du peer %1... + + + + Upload rate limiting + Limitation de la vitesse d'envoi + + + + Download rate limiting + Limitation de la vitesse de réception + + + + Preferences + + UI + User Interface + Interface + + + + Downloads + Téléchargements + + + + Connection + Connexion + + + + Speed + Vitesse + + + Bittorrent + Bittorrent + + + Proxy + Serveur mandataire + + + + Web UI + Interface Web + + + + Advanced + Avancé + + + Language: + Langue : + + + + (Requires restart) + Redémarrage nécessaire) + + + Visual style: + Style visuel : + + + Transfer list + Liste de transferts + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Alterner la couleur des lignes + + + + + Start / Stop Torrent + Démarrer / Stopper torrent + + + + + No action + Aucune action + + + File system + Système de fichiers + + + + Copy .torrent files to: + Copier les fichier .torrent dans : + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Les paramètres suivants sont pris en charge: +<ul> +<li>%f: Chemin du torrent</li> +<li>%n: Nom du torrent</li> +</ul> + + + + Listening Port + Port d'écoute + + + + Connections Limits + Limites de connexions + + + + Proxy Server + Serveur mandataire (Proxy) + + + + Enable bandwidth management (uTP) + Activer la gestion de bande passante (uTP) + + + + Enable Peer Exchange (PeX) to find more peers + Activer l'échange de sources (PeX) avec les autres utilisateurs + + + + Enable Local Peer Discovery to find more peers + Activer la découverte de sources sur le réseau local + + + + Encryption mode: + Mode de chiffrement : + + + + Prefer encryption + Chiffrement préféré + + + + Require encryption + Chiffrement requis + + + + Disable encryption + Chiffrement désactivé + + + Torrent queueing + Mise en attente des torrents + + + + Maximum active downloads: + Nombre maximum de téléchargements actifs : + + + + Maximum active uploads: + Nombre maximum d'envois actifs : + + + + Maximum active torrents: + Nombre maximum de torrents actifs : + + + + When adding a torrent + A l'ajout d'un torrent + + + + + Options + Options + + + Visual Appearance + Apparence visuelle + + + + Action on double-click + Action du double-clic + + + + Downloading torrents: + Torrents incomplets : + + + Start / Stop + Démarrer / Stopper + + + + + Open destination folder + Ouvrir le répertoire de destination + + + + Completed torrents: + Torrents complets : + + + + Desktop + Bureau + + + + Show splash screen on start up + Afficher l'écran de démarrage + + + + Start qBittorrent minimized + Démarrer qBittorrent avec la fenêtre réduite + + + Show qBittorrent icon in notification area + Afficher l'icône de qBittorrent dans la zone de notification + + + Use monochrome system tray icon (requires restart) + Utiliser une icône monochrome dans la barre des tâches (redémarrage requis) + + + + Minimize qBittorrent to notification area + Réduire qBittorrent dans la zone de notification + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Conserver dans la zone de notification à la fermeture + + + + Tray icon style: + Style de l'icône : + + + + Normal + Normale + + + + Monochrome (Dark theme) + Monochrome (Thème foncé) + + + + Monochrome (Light theme) + Monochrome (Thème clair) + + + + Ask for program exit confirmation + Confirmer l'extinction du programme + + + + User Interface Language: + Langue de l'interface utilisateur : + + + + Transfer List + Liste des transferts + + + + Show qBittorrent in notification area + Afficher l'icône de qBittorrent dans la zone de notification + + + + Power Management + Gestion de l'énergie + + + + Inhibit system sleep when torrents are active + Empêcher la mise en veille lorsque des torrents sont actifs + + + + Display torrent content and some options + Afficher le contenu du torrent et quelques paramètres + + + + Do not start the download automatically + The torrent will be added to download list in pause state + Ne pas démarrer le téléchargement automatiquement + + + + Hard Disk + Disque dur + + + + Save files to location: + Sauvegarder les fichiers vers : + + + + Append the label of the torrent to the save path + Ajouter à la fin du chemin la catégorie du torrent + + + + Pre-allocate disk space for all files + Pré-allouer l'espace disque pour tous les fichiers + + + + Keep incomplete torrents in: + Conserver les torrents incomplets dans : + + + Append .!qB extension to incomplete files' names + Ajouter l'extension .!qB aux noms des fichiers incomplets + + + + Automatically add torrents from: + Ajouter automatiquement les torrents présents dans : + + + + Add folder... + Ajouter dossier... + + + + Email notification upon download completion + Notification par e-mail de fin de téléchargement + + + + Destination email: + E-mail de destination : + + + + SMTP server: + Serveur SMTP : + + + + This server requires a secure connection (SSL) + Ce serveur nécessite une connexion sécurisée (SSL) + + + + Run an external program on torrent completion + Lancer un programme externe à la fin d'un téléchargement + + + + Otherwise, the proxy server is only used for tracker connections + Dans le cas contraire, le proxy sera uniquement utilisé pour contacter les trackers + + + + Use proxy for peer connections + Utiliser le serveur mandataire pour se connecter aux utilisateurs (peers) + + + + Global Rate Limits + Limites de vitesse globales + + + + Apply rate limit to uTP connections + Appliquer les limites de vitesse aux connexions uTP + + + + Apply rate limit to transport overhead + Appliquer les limites de vitesse au surplus généré par le protocole + + + + Alternative Global Rate Limits + Limites de vitesse globales alternatives + + + + Schedule the use of alternative rate limits + Plannifier l'utilisation des vitesses limites alternatives + + + + Use HTTPS instead of HTTP + Utiliser HTTPS au lieu de HTTP (Sécurisé) + + + + Import SSL Certificate + Importer un certificat SSL + + + + Import SSL Key + Importer une clé SSL + + + + Certificate: + Certificat : + + + + Key: + Clé : + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Plus d'information sur les certificats</a> + + + + Update my dynamic domain name + Mettre à jour mon nom de domaine dynamique + + + + Service: + Service : + + + + Register + Créer un compte + + + + Domain name: + Nom de domaine : + + + Use %f to pass the torrent path in parameters + Utiliser %f pour passer le chemin du torrent en paramètre + + + + Use UPnP / NAT-PMP port forwarding from my router + Utiliser la redirection de port sur mon routeur via UPnP / NAT-PMP + + + Proxy server + Serveur mandataire (Proxy) + + + + IP Filtering + Filtrage IP + + + + Reload the filter + Recharger le filtre + + + Schedule the use of alternative speed limits + Plannifier l'utilisation des vitesses limites alternatives + + + + from + from (time1 to time2) + de + + + + When: + Quand : + + + + Privacy + Vie privée + + + + Enable DHT (decentralized network) to find more peers + Activer le DHT (réseau décentralisé) pour trouver plus de sources + + + + Use a different port for DHT and BitTorrent + Utiliser un port différent pour le DHT et BitTorrent + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Echanger des peers avec les applications compatibles (µTorrent, Vuze, ...) + + + + Torrent Queueing + Priorisation des torrents + + + + Share Ratio Limiting + Limitation du ratio de partage + + + + Use UPnP / NAT-PMP to forward the port from my router + Utiliser la redirection de port sur mon routeur via UPnP / NAT-PMP + + + + Bypass authentication for localhost + Contourner l'authentification pour localhost + + + Protocol encryption: + Brouillage de protocole : + + + Share ratio limiting + Limitation du ratio de partage + + + + Seed torrents until their ratio reaches + Partager les torrents jusqu'à un ratio de + + + + then + puis + + + + Pause them + Les mettre en pause + + + + Remove them + Les supprimer + + + + Enable Web User Interface (Remote control) + Activer l'interface Web (Contrôle distant) + + + Listening port + Port d'écoute + + + + Port used for incoming connections: + Port pour les connexions entrantes : + + + + Random + Aléatoire + + + Enable UPnP port mapping + Activer l'UPnP + + + Enable NAT-PMP port mapping + Activer le NAT-PMP + + + Connections limit + Limite de connections + + + + Global maximum number of connections: + Nombre global maximum de connexions : + + + + Maximum number of connections per torrent: + Nombre maximum de connexions par torrent : + + + + Maximum number of upload slots per torrent: + Nombre maximum de slots d'envoi par torrent : + + + + + Upload: + Envoi : + + + + + Download: + Réception : + + + + + + + KiB/s + Ko/s + + + User Interface + Interface utilisateur + + + + BitTorrent + BitTorrent + + + Global speed limits + Limites de vitesse globales + + + Alternative global speed limits + Limites de vitesse globales alternatives + + + + to + time1 to time2 + à + + + + Every day + Tous les jours + + + + Week days + Jours ouvrables + + + + Week ends + Week ends + + + Bittorrent features + Fonctionnalités Bittorrent + + + Enable DHT network (decentralized) + Activer le réseau DHT (décentralisé) + + + Use a different port for DHT and Bittorrent + Utiliser un port différent pour le DHT et Bittorrent + + + + DHT port: + Port DHT : + + + Enable Peer Exchange / PeX (requires restart) + Activer l'échange de sources / PeX (redémarrage nécessaire) + + + + Look for peers on your local network + Rechercher des peers sur votre réseau local + + + Enable Local Peer Discovery + Activer la recherche locale de sources + + + + Remove folder + Supprimer dossier + + + Enabled + Activé + + + Forced + Forcé + + + Disabled + Désactivé + + + HTTP Communications (trackers, Web seeds, search engine) + Communications HTTP (trackers, sources HTTP, moteur de recherche) + + + + Host: + Hôte : + + + Peer Communications + Communications avec les peers + + + + SOCKS4 + SOCKS4 + + + + Type: + Type : + + + + + Behavior + Comportement + + + + Language + Langue + + + + Append .!qB extension to incomplete files + Ajouter l'extension .!qB aux noms des fichiers incomplets + + + + (None) + (Aucun) + + + + HTTP + + + + + + Port: + Port : + + + + + + Authentication + Authentification + + + + + + + Username: + Nom d'utilisateur : + + + + + + + Password: + Mot de passe : + + + + SOCKS5 + + + + + Filter path (.dat, .p2p, .p2b): + Chemin du filtre (.dat, .p2p, .p2b) : + + + HTTP Server + Serveur HTTP + + + + PreviewSelect + + + Name + Nom + + + + Size + Taille + + + + Progress + Avancement + + + + + + Preview impossible + Prévisualisation impossible + + + + + + Sorry, we can't preview this file + Désolé, il est impossible de prévisualiser ce fichier + + + + ProgramUpdater + + Could not create the file %1 + Impossible de créer le fichier %1 + + + Failed to download the update at %1 + %1 is an URL + Impossible de télécharger la mise à jour depuis %1 + + + + PropListDelegate + + + Not downloaded + Non téléchargé + + + + + Normal + Normal (priority) + Normale + + + + + High + High (priority) + Haute + + + + Mixed + Mixed (priorities + Mixtes + + + + + Maximum + Maximum (priority) + Maximale + + + + PropTabBar + + + General + Général + + + + Trackers + Trackers + + + + Peers + Peers + + + + HTTP Sources + Sources HTTP + + + + Content + Contenu + + + URL Seeds + Sources HTTP + + + Files + Fichiers + + + + PropertiesWidget + + + Save path: + Répertoire de destination : + + + + Torrent hash: + Hash du torrent : + + + + Comment: + Commentaire : + + + + Share ratio: + Ratio partage : + + + + + Downloaded: + Téléchargé : + + + + Availability: + Disponibilité : + + + + Transfer + Transfert + + + + Uploaded: + Envoyé : + + + + Wasted: + Gaspillé : + + + + Time active: + Time (duration) the torrent is active (not paused) + Actif pendant : + + + + Pieces size: + Taille des morceaux : + + + + Torrent content: + Contenu du torrent : + + + + Select All + Tout sélectionner + + + + Select None + Ne rien sélectionner + + + + + Do not download + Ne pas télécharger + + + + UP limit: + Limite envoi : + + + + DL limit: + Limite réception : + + + Time elapsed: + Temps écoulé : + + + + Connections: + Connexions : + + + + Reannounce in: + Annonce dans : + + + + Information + Informations + + + + Created on: + Créé le : + + + General + Général + + + Trackers + Trackers + + + Peers + Peers + + + URL seeds + Sources HTTP + + + Files + Fichiers + + + + Priority + Priorité + + + + Normal + Normale + + + + Maximum + Maximale + + + + High + Haute + + + + + this session + cette session + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Complet depuis %1 + + + + %1 max + e.g. 10 max + %1 max + + + + + I/O Error + Erreur E/S + + + + This file does not exist yet. + Ce fichier n'existe pas encore. + + + + This folder does not exist yet. + Ce dossier n'existe pas encore. + + + + Rename... + Renommer... + + + + Rename the file + Renommer le fichier + + + + New name: + Nouveau nom : + + + + + The file could not be renamed + Le fichier n'a pas pu être renommé + + + + This file name contains forbidden characters, please choose a different one. + Ce nom de fichier contient des caractères interdits, veuillez en choisir un autre. + + + + + This name is already in use in this folder. Please use a different name. + Ce nom est déjà utilisé au sein de ce dossier. Veuillez choisir un nom différent. + + + + The folder could not be renamed + Le dossier n'a pas pu être renommé + + + + New url seed + New HTTP source + Nouvelle source HTTP + + + + New url seed: + Nouvelle source HTTP : + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Cette source HTTP est déjà dans la liste. + + + + + Choose save path + Choix du répertoire de destination + + + Save path creation error + Erreur lors de la création du répertoire de destination + + + Could not create the save path + Impossible de créer le répertoire de destination + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 a atteint le ratio maximum défini. + + + + Removing torrent %1... + Suppression du torrent %1... + + + + Pausing torrent %1... + Mise en pause du torrent %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent est associé au port : TCP/%1 + + + UPnP support [ON] + Support UPnP [ON] + + + UPnP support [OFF] + Support UPNP [OFF] + + + NAT-PMP support [ON] + Support NAT-PMP [ON] + + + NAT-PMP support [OFF] + Support NAT-PMP [OFF] + + + + HTTP user agent is %1 + User agent HTTP: %1 + + + Using a disk cache size of %1 MiB + Utilisation d'un tampon disque de %1 Mo + + + + DHT support [ON], port: UDP/%1 + Prise en charge DHT [ON], port : UDP/%1 + + + + + DHT support [OFF] + Prise en charge DHT [OFF] + + + + PeX support [ON] + Echange des sources avec les autres clients (PeX) [ON] + + + + PeX support [OFF] + Echange des sources avec les autres clients (PeX) [OFF] + + + + Restart is required to toggle PeX support + Un redémarrage est nécessaire afin de changer l'état du support PeX + + + Local Peer Discovery [ON] + Découverte locale de sources [ON] + + + + Local Peer Discovery support [OFF] + Découverte locale de sources [OFF] + + + + Encryption support [ON] + Brouillage de protocôle [ON] + + + + Encryption support [FORCED] + Brouillage de protocole [Forcé] + + + + Encryption support [OFF] + Brouillage de protocole [OFF] + + + + Embedded Tracker [ON] + Tracker intégré [ON] + + + + Failed to start the embedded tracker! + Impossible de démarrer le tracker intégré ! + + + + Embedded Tracker [OFF] + Tracker intégré [OFF] + + + + The Web UI is listening on port %1 + L'interface Web est associée au port %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Erreur interface Web - Impossible d'associer l'interface Web au port %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' a été supprimé de la liste et du disque dur. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' a été supprimé de la liste. + + + + '%1' is not a valid magnet URI. + '%1' n'est pas un lien magnet valide. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' est déjà présent dans la liste de téléchargement. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' a été relancé. (relancement rapide) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' a été ajouté à la liste de téléchargement. + + + + UPnP / NAT-PMP support [ON] + Prise en charge UPnP / NAT-PMP [ON] + + + + UPnP / NAT-PMP support [OFF] + Prise en charge UPnP / NAT-PMP [OFF] + + + + Reporting IP address %1 to trackers... + Annonce de l'adresse IP %1 aux trackers... + + + + Local Peer Discovery support [ON] + Découverte de sources sur le réseau local [ON] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Impossible de décoder le torrent : '%1' + + + + This file is either corrupted or this isn't a torrent. + Ce fichier est corrompu ou il ne s'agit pas d'un torrent. + + + + Error: The torrent %1 does not contain any file. + Erreur : Le torrent %1 ne contient aucun fichier. + + + + Note: new trackers were added to the existing torrent. + Remarque : Les nouveaux trackers ont été ajoutés au torrent existant. + + + + Note: new URL seeds were added to the existing torrent. + Remarque : Les nouvelles sources HTTP sont été ajoutées au torrent existant. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>a été bloqué par votre filtrage IP</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>a été banni suite à l'envoi de données corrompues</i> + + + + The network interface defined is invalid: %1 + L'interface réseau définie est invalide : %1 + + + + Trying any other network interface available instead. + Utilisation de n'importe quelle interface réseau à la place. + + + + Listening on IP address %1 on network interface %2... + Ecoute sur l'adresse IP %1 sur l'interface réseau %2... + + + + Failed to listen on network interface %1 + Impossible d'écouter sur l'interface réseau %1 + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Téléchargement récursif du fichier %1 au sein du torrent %2 + + + + + Unable to decode %1 torrent file. + Impossible de décoder le torrent %1. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + L'ordinateur va maintenant être mis en veille à moins que vous annuliez dans les 15 prochaines secondes... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + L'ordinateur va maintenant être éteint à moins que vous annuliez dans les 15 prochaines secondes... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent va maintenant être arrêté à moins que vous annuliez dans les 15 prochaines secondes... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Le filtre IP a été correctement chargé : %1 règles ont été appliquées. + + + + Error: Failed to parse the provided IP filter. + Erreur : Impossible de charge le filtre IP fourni. + + + + Torrent name: %1 + Nom du torrent : %1 + + + + Torrent size: %1 + Taille du torrent : %1 + + + + Save path: %1 + Répertoire de destination : %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Le torrent a été téléchargé en %1. + + + + Thank you for using qBittorrent. + Nous vous remercions d'utiliser qBittorrent. + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] Le téléchargement de %1 est terminé + + + + An I/O error occured, '%1' paused. + Une erreur E/S s'est produite, '%1' a été mis en pause. + + + + + Reason: %1 + Raison : %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP : Impossible de rediriger le port sur le routeur, message : %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP : La redirection du port sur le routeur a réussi, message : %1 + + + + File sizes mismatch for torrent %1, pausing it. + Les tailles de fichiers ne correspondent pas pour le torrent %1, mise en pause. + + + + Fast resume data was rejected for torrent %1, checking again... + Le relancement rapide a échoué pour le torrent %1, revérification... + + + + Url seed lookup failed for url: %1, message: %2 + Le contact de la source HTTP a échoué à l'url : %1, message : %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Téléchargement de '%1', veuillez patienter... + + + + RSS + + + Search + Recherche + + + + New subscription + Nouveau flux + + + + + + Mark items read + Marquer comme lu + + + + Update all + Tout mettre à jour + + + + RSS Downloader... + Téléchargement RSS... + + + + Settings... + Paramètres... + + + Feed URL + URL du flux + + + + Rename... + Renommer... + + + + + Update + Mettre à jour + + + RSS feed downloader... + Téléchargement du flux RSS... + + + + New folder... + Nouveau dossier... + + + + Manage cookies... + Gestion des cookies... + + + RSS feeds + Flux RSS + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents :</span> <span style=" font-style:italic;">(double-clic pour télécharger)</span></p></body></html> + + + Article title + Titre de l'article + + + + New subscription... + Nouvelle souscription... + + + + + Update all feeds + Tout mettre à jour + + + + + Delete + Supprimer + + + + Rename + Renommer + + + + Download torrent + Télécharger le torrent + + + + Open news URL + Ouvrir l'URL de l'article + + + + Copy feed URL + Copier l'URL du flux + + + + Refresh RSS streams + Rafraîchir les flux RSS + + + + RSSImp + + + Please type a rss stream url + Veuillez entrer l'url du flux RSS + + + + Stream URL: + URL du flux : + + + + + Are you sure? -- qBittorrent + Etes vous sûr ? -- qBittorrent + + + + + &Yes + &Oui + + + + + &No + &Non + + + + Please choose a folder name + Veuillez indiquer un nom de dossier + + + + Folder name: + Nom du dossier : + + + + New folder + Nouveau dossier + + + + Overwrite attempt + Tentative d'écrasement + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Vous ne pouvez pas écraser l'élément %1. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Cette source RSS est déjà dans votre liste. + + + + Are you sure you want to delete these elements from the list? + Etes-vous certain de vouloir supprimer ces éléments de la liste ? + + + + Are you sure you want to delete this element from the list? + Etes-vous certain de vouloir supprimer cet élément de la liste ? + + + + Please choose a new name for this RSS feed + Veuillez choisir un nouveau nom pour ce flux RSS + + + + New feed name: + Nouveau nom du flux : + + + + Name already in use + Nom déjà utilisé + + + + This name is already used by another item, please choose another one. + Ce nom est déjà utilisé par un autre élément, veuillez en choisir un autre. + + + + Date: + Date : + + + + Author: + Auteur : + + + + Unread + Non lu + + + + RssArticle + + No description available + Aucune description disponible + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Téléchargement automatique du torrent %1 depuis le flux RSS %2... + + + + RssItem + + No description available + Aucune description disponible + + + + RssSettings + + RSS Reader Settings + Paramètres du lecteur RSS + + + RSS feeds refresh interval: + Intervalle de rafraîchissement des flux RSS : + + + minutes + minutes + + + Maximum number of articles per feed: + Numbre maximum d'articles par flux : + + + + RssSettingsDlg + + + RSS Reader Settings + Paramètres du lecteur RSS + + + + RSS feeds refresh interval: + Intervalle de rafraîchissement des flux RSS : + + + + minutes + minutes + + + + Maximum number of articles per feed: + Numbre maximum d'articles par flux : + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Téléchargement automatique du torrent %1 depuis le flux RSS %2... + + + + ScanFoldersModel + + + Watched Folder + Répertoire surveillé + + + + Download here + Télécharger ici + + + + SearchCategories + + + All categories + Toutes catégories + + + + Movies + Films + + + + TV shows + Séries TV + + + + Music + Musique + + + + Games + Jeux + + + + Anime + Animé + + + + Software + Logiciels + + + + Pictures + Photos + + + + Books + Livres + + + + SearchEngine + + + Empty search pattern + Motif de recherche vide + + + + Please type a search pattern first + Veuillez entrer un motif de recherche d'abord + + + + + Results + Résultats + + + + Searching... + Recherche en cours... + + + + Cut + Couper + + + + Copy + Copier + + + + Paste + Coller + + + + Clear field + Vider le champ + + + + Clear completion history + Vider l'historique d'autocomplétion + + + + Confirmation + Confirmation + + + + Are you sure you want to clear the history? + Est-vous certain de vouloir effacer l'historique ? + + + + + + Search + Recherche + + + + Missing Python Interpreter + Interpréteur Python manquant + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x est requis par le moteur de recherche mais celui-ci ne semble pas être installé. +Voulez-vous l'installer maintenant ? + + + + Search Engine + Moteur de recherche + + + + + Search has finished + Fin de la recherche + + + + An error occured during search... + Une erreur s'est produite lors de la recherche... + + + + + Search aborted + La recherche a été interrompue + + + + Download error + Erreur de téléchargement + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Le programme d'installation de Python n'a pas pu être téléchargé, raison : %1. +Veuillez l'installer manuellement. + + + + Search returned no results + La recherche n'a retourné aucun résultat + + + + Results + i.e: Search results + Résultats + + + + + Unknown + Inconnu + + + + SearchTab + + + Name + i.e: file name + Nom + + + + Size + i.e: file size + Taille + + + + Seeders + i.e: Number of full sources + Sources complètes + + + + Leechers + i.e: Number of partial sources + Sources partielles + + + + Search engine + Moteur de recherche + + + + ShutdownConfirmDlg + + + Shutdown confirmation + Confirmation de l'extinction + + + + SpeedLimitDialog + + + KiB/s + Ko/s + + + + StatusBar + + + + Connection status: + Statut de la connexion : + + + + + No direct connections. This may indicate network configuration problems. + Aucune connexion directe. Ceci peut être signe d'une mauvaise configuration réseau. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + R : %1 o/s - T : %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + E : %1 o/s - T : %2 + + + + + DHT: %1 nodes + DHT : %1 noeuds + + + + qBittorrent needs to be restarted + qBittorrent doit être redémarré + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent vient d'être mis à jour et doit être redémarré pour que les changements soient pris en compte. + + + + + Connection Status: + Etat de la connexion : + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Hors ligne. Ceci signifie généralement que qBittorrent s'a pas pu se mettre en écoute sur le port défini pour les connexions entrantes. + + + + Online + Connecté + + + + + %1/s + Per second + %1/s + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + R : %1/s - T : %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + E : %1/s - T : %2 + + + + Click to switch to alternative speed limits + Cliquer pour utiliser les limites de vitesse alternatives + + + + Click to switch to regular speed limits + Cliquer pour utiliser les limites de vitesse normales + + + Click to disable alternative speed limits + Cliquer pour désactiver les limites de vitesse alternatives + + + Click to enable alternative speed limits + Cliquer pour activer les limites de vitesse alternatives + + + + Global Download Speed Limit + Limite globale de la vitesse de réception + + + + Global Upload Speed Limit + Limite globale de la vitesse d'envoi + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Sélectionner un dossier à ajouter au torrent + + + + Select a file to add to the torrent + Sélectionner un fichier à ajouter au torrent + + + Please type an announce URL + Veuillez entrer l'url du tracker + + + Announce URL: + Tracker URL + URL du tracker : + + + Please type a web seed url + Veuillez entrer l'url de la source web + + + Web seed URL: + URL de la source web : + + + + No input path set + Aucun fichier inclu + + + + Please type an input path first + Veuillez sélectionner un fichier ou un dossier à inclure d'abord + + + + Select destination torrent file + Sélectionner le torrent à créer + + + + Torrent Files + Fichiers Torrent + + + + + + Torrent creation + Création d'un torrent + + + + Torrent creation was unsuccessful, reason: %1 + La création du torrent a échoué, raison : %1 + + + + Created torrent file is invalid. It won't be added to download list. + Le torrent créé est invalide. Il ne sera pas ajouté à la liste de téléchargement. + + + + Torrent was created successfully: + Le torrent a été créé avec succès : + + + + TorrentFilesModel + + + Name + Nom + + + + Size + Taille + + + + Progress + Progression + + + + Priority + Priorité + + + + TorrentImportDlg + + + Torrent Import + Import de torrent + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Cette assistant va vous aider à charger un torrent que vous avez déjà téléchargé. + + + + Torrent file to import: + Fichier Torrent à importer : + + + + + ... + ... + + + + Content location: + Chemin vers le contenu : + + + + Skip the data checking stage and start seeding immediately + Ne pas procéder à la vérification et partager directement le torrent + + + + Import + Importation + + + + Torrent file to import + Fichier Torrent à importer + + + + Torrent files (*.torrent) + Fichiers Torrent (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + Fichiers %1 + + + + Please provide the location of %1 + %1 is a file name + Veuillez indiquer le chemin vers %1 + + + + Please point to the location of the torrent: %1 + Veuillez indiquer le chemin vers le contenu du torrent : %1 + + + + Invalid torrent file + Fichier torrent invalide + + + + This is not a valid torrent file. + Il ne s'agit pas d'un fichier torrent valide. + + + + TorrentModel + + + Name + i.e: torrent name + Nom + + + + Size + i.e: torrent size + Taille + + + + Done + % Done + Avancement + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Etat + + + + Seeds + i.e. full sources (often untranslated) + Seeds + + + + Peers + i.e. partial sources (often untranslated) + Peers + + + + Down Speed + i.e: Download speed + Vitesse DL + + + + Up Speed + i.e: Upload speed + Vitesse UP + + + + Ratio + Share ratio + Ratio + + + + ETA + i.e: Estimated Time of Arrival / Time left + Temps restant + + + + Label + Catégorie + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Ajouté le + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Terminé le + + + + Tracker + + + + + Down Limit + i.e: Download limit + Limite réception + + + + Up Limit + i.e: Upload limit + Limite envoi + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Quantité téléchargée + + + + Amount left + Amount of data left to download (e.g. in MB) + Quantité restante + + + + Time Active + Time (duration) the torrent is active (not paused) + Actif pendant + + + + TrackerList + + + URL + URL + + + + Status + Etat + + + + Peers + Peers + + + + Message + + + + + [DHT] + + + + + [PeX] + + + + + [LSD] + + + + + + + + + Working + Fonctionne + + + + + + Disabled + Désactivé + + + + This torrent is private + Ce torrent est privé + + + + Updating... + Mise à jour... + + + + + Not working + Indisponible + + + + + Not contacted yet + Pas encore contacté + + + + Add a new tracker... + Ajouter nouveau tracker... + + + + Remove tracker + Supprimer tracker + + + + Force reannounce + Forcer nouvelle annonce + + + + TrackersAdditionDlg + + + Trackers addition dialog + Fenêtre d'ajout de trackers + + + + List of trackers to add (one per line): + Liste des trackers à ajouter (un par ligne) : + + + + µTorrent compatible list URL: + URL de la liste compatible avec µTorrent : + + + + I/O Error + Erreur E/S + + + + Error while trying to open the downloaded file. + Erreur à l'ouverture du fichier téléchargé. + + + + No change + Aucun changement + + + + No additional trackers were found. + Aucun tracker supplémentaire n'est disponible. + + + + Download error + Erreur de téléchargement + + + + The trackers list could not be downloaded, reason: %1 + La liste de trackers n'a pas pu être téléchargée, raison : %1 + + + + TransferListDelegate + + + Downloading + En téléchargement + + + + Paused + En pause + + + + Queued + i.e. torrent is queued + En file d'attente + + + + Seeding + Torrent is complete and in upload-only mode + En partage + + + + Stalled + Torrent is waiting for download to begin + En attente + + + + Checking + Torrent local data is being checked + Vérification + + + + /s + /second (.i.e per second) + /s + + + + KiB/s + KiB/second (.i.e per second) + Ko/s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Complet depuis %1 + + + + TransferListFiltersWidget + + + + All + Tous + + + + + Downloading + En téléchargement + + + + + Completed + Complet + + + + + Paused + En pause + + + + + Active + Actif + + + + + Inactive + Inactif + + + + + All labels + Toutes catégories + + + + + Unlabeled + Sans catégorie + + + + Remove label + Supprimer catégorie + + + + Add label... + Nouvelle catégorie... + + + + Resume torrents + Démarrer les torrents + + + + Pause torrents + Mettre en pause les torrents + + + + Delete torrents + Supprimer les torrents + + + + New Label + Nouvelle catégorie + + + + Label: + Catégorie : + + + + Invalid label name + Nom de catégorie incorrect + + + + Please don't use any special characters in the label name. + Veuillez ne pas utiliser de caractères spéciaux dans le nom de catégorie. + + + + TransferListWidget + + Down Speed + i.e: Download speed + Vitesse DL + + + Up Speed + i.e: Upload speed + Vitesse UP + + + ETA + i.e: Estimated Time of Arrival / Time left + Restant + + + + Column visibility + Visibilité des colonnes + + + Name + i.e: torrent name + Nom + + + Size + i.e: torrent size + Taille + + + Done + % Done + Reçu + + + Status + Torrent status (e.g. downloading, seeding, paused) + Etat + + + Seeds + i.e. full sources (often untranslated) + Seeds + + + Peers + i.e. partial sources (often untranslated) + Peers + + + Ratio + Share ratio + Ratio + + + + Label + Catégorie + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Ajouté le + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Terminé le + + + Down Limit + i.e: Download limit + Limite réception + + + Up Limit + i.e: Upload limit + Limite envoi + + + + Choose save path + Choix du répertoire de destination + + + Save path creation error + Erreur lors de la création du répertoire de destination + + + Could not create the save path + Impossible de créer le répertoire de destination + + + + Torrent Download Speed Limiting + Limitation de la vitesse de réception + + + + Torrent Upload Speed Limiting + Limitation de la vitesse d'envoi + + + + New Label + Nouvelle catégorie + + + + Label: + Catégorie : + + + + Invalid label name + Nom de catégorie incorrect + + + + Please don't use any special characters in the label name. + Veuillez ne pas utiliser de caractères spéciaux dans le nom de catégorie. + + + + Rename + Renommer + + + + New name: + Nouveau nom : + + + + Resume + Resume/start the torrent + Démarrer + + + + Pause + Pause the torrent + Mettre en pause + + + + Delete + Delete the torrent + Supprimer + + + + Preview file... + Prévisualiser fichier... + + + + Limit share ratio... + Limiter le ratio de partage... + + + + Limit upload rate... + Limiter vitesse d'envoi... + + + + Limit download rate... + Limiter vitesse de réception... + + + + Priority + Priorité + + + + Open destination folder + Ouvrir le répertoire de destination + + + + Move up + i.e. move up in the queue + Augmenter + + + + Move down + i.e. Move down in the queue + Baisser + + + + Move to top + i.e. Move to top of the queue + Maximum + + + + Move to bottom + i.e. Move to bottom of the queue + Minimum + + + + Set location... + Chemin de sauvegarde... + + + + Force recheck + Forcer revérification + + + + Copy magnet link + Copier le lien magnet + + + + Super seeding mode + Mode de super partage + + + + Rename... + Renommer... + + + + Download in sequential order + Téléchargement séquentiel + + + + Download first and last piece first + Téléchargement prioritaire du début et de la fin + + + + New... + New label... + Nouvelle catégorie... + + + + Reset + Reset label + Réinitialiser catégorie + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Limitation du ratio de partage + + + + Use global ratio limit + Utiliser la limite globale + + + + + + buttonGroup + + + + + Set no ratio limit + Ne pas limiter le ratio + + + + Set ratio limit to + Limiter le ratio à + + + + UsageDisplay + + + Usage: + Utilisation : + + + + displays program version + affichage la version du programme + + + + disable splash screen + désactive l'écran de démarrage + + + + displays this help message + affiche ce message d'aide + + + + changes the webui port (current: %1) + change le port de l'interface Web (actuel : %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [Fichiers ou URLs] : télécharge les torrents passés en paramètre (optionnel) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Je tiens à remercier les personnes suivantes pour avoir traduit qBittorrent : + + + + Please contact me if you would like to translate qBittorrent into your own language. + Veuillez me contacter si vous désirez traduire qBittorrent dans votre langue natale. + + + + addPeerDialog + + + Peer addition + Ajout d'un peer + + + + IP + IP + + + + Port + Port + + + + addTorrentDialog + + + Torrent addition dialog + Dialogue d'ajout de torrent + + + + Save path: + Répertoire de destination : + + + + ... + ... + + + + Torrent size: + Taille du torrent : + + + + + Unknown + Inconnue + + + + Free disk space: + Espace disponible : + + + + Label: + Catégorie : + + + + Torrent content: + Contenu du torrent : + + + + Select All + Tout sélectionner + + + + Select None + Ne rien sélectionner + + + + Download in sequential order (slower but good for previewing) + Téléchargement séquentiel (plus lent mais facilite la prévisualisation) + + + + Skip file checking and start seeding immediately + Ne pas vérifier les fichiers et commencer directement à partager + + + + + Do not download + Ne pas télécharger + + + + Add to download list in paused state + Ajouter à la liste de téléchargement en état de pause + + + + Add + Ajouter + + + + Cancel + Annuler + + + + Normal + Normale + + + + High + Haute + + + + Maximum + Maximale + + + + authentication + + + + Tracker authentication + Authentification Tracker + + + + Tracker: + Tracker : + + + + Login + Autentification + + + + Username: + Nom d'utilisateur : + + + + Password: + Mot de passe : + + + + Log in + S'authentifier + + + + Cancel + Annuler + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Confirmation de la suppression - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Etes-vous sûr de vouloir supprimer les torrents sélectionnés de la liste de transfert ? + + + + Remember choice + Se souvenir du choix + + + + Also delete the files on the hard disk + Supprimer également les fichiers sur le disque + + + + createTorrentDialog + + + Cancel + Annuler + + + + Torrent Creation Tool + Utilitaire de création de torrent + + + + Torrent file creation + Création d'un fichier torrent + + + Announce urls (trackers): + Urls des trackers : + + + Comment (optional): + Commentaire (facultatif) : + + + Web seeds urls (optional): + Urls sources web (facultatif) : + + + + File or folder to add to the torrent: + Fichier ou dossier à ajouter au torrent : + + + + Add file + Ajout fichier + + + + Add folder + Ajout dossier + + + + Tracker URLs: + URLs des trackers : + + + + Web seeds urls: + Sources HTTP : + + + + Comment: + Commentaire : + + + + Piece size: + taille des morceaux : + + + + 32 KiB + 32 Ko + + + + 64 KiB + 64 Ko + + + + 128 KiB + 128 Ko + + + + 256 KiB + 256 Ko + + + + 512 KiB + 512 Ko + + + + 1 MiB + 1 Mo + + + + 2 MiB + 2 Mo + + + + 4 MiB + 4 Mo + + + + Auto + + + + + Private (won't be distributed on DHT network if enabled) + Privé (ne sera pas distribué sur le réseau DHT si activé) + + + + Start seeding after creation + Commencer le partage directement + + + + Create and save... + Créer et sauvegarder... + + + + Progress: + Progression : + + + + createtorrent + + Select destination torrent file + Sélectionner le torrent à créer + + + Torrent Files + Fichiers Torrent + + + No input path set + Aucun fichier inclu + + + Please type an input path first + Veuillez sélectionner un fichier ou un dossier à inclure d'abord + + + Torrent creation + Création d'un torrent + + + Torrent was created successfully: + Le torrent a été créé avec succès : + + + Select a folder to add to the torrent + Sélectionner un dossier à ajouter au torrent + + + Please type an announce URL + Veuillez entrer l'url du tracker + + + Torrent creation was unsuccessful, reason: %1 + La création du torrent a échoué, raison : %1 + + + Announce URL: + Tracker URL + URL du tracker : + + + Please type a web seed url + Veuillez entrer l'url de la source web + + + Web seed URL: + URL de la source web : + + + Select a file to add to the torrent + Sélectionner un fichier à ajouter au torrent + + + Created torrent file is invalid. It won't be added to download list. + Le torrent créé est invalide. Il ne sera pas ajouté à la liste de téléchargement. + + + + downloadFromURL + + Download Torrents from URLs + Téléchargement de torrents depuis des urls + + + Only one URL per line + Une seule URL par ligne + + + + Add torrent links + Ajout de liens vers des torrents + + + + Both HTTP and Magnet links are supported + Les liens HTTP et Magnet sont pris en charge + + + + Download + Télécharger + + + + Cancel + Annuler + + + + Download from urls + Téléchargement depuis des urls + + + + No URL entered + Aucune URL entrée + + + + Please type at least one URL. + Veuillez entrer au moins une URL. + + + + downloadThread + + I/O Error + Erreur E/S + + + The remote host name was not found (invalid hostname) + Hôte distant introuvable (Nom d'hôte invalide) + + + The operation was canceled + Opération annulée + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Connexion fermée prématurément par le serveur distant, avant la réception complète de sa réponse + + + The connection to the remote server timed out + Délai de connexion au serveur distant écoulée + + + SSL/TLS handshake failed + Erreur poignée de main SSL/TLS + + + The remote server refused the connection + Connexion refusée par le serveur distant + + + The connection to the proxy server was refused + Connexion refusée par le serveur mandataire + + + The proxy server closed the connection prematurely + Connexion fermée prématurément par le serveur mandataire + + + The proxy host name was not found + Nom d'hôte du serveur mandataire introuvable + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Délai de connexion au serveur mandataire écoulée + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Echec d'authentification auprès du serveur mandataire + + + The access to the remote content was denied (401) + Accès au contenu distant refusé (401) + + + The operation requested on the remote content is not permitted + L'opération sur le contenu distant n'est pas permise + + + The remote content was not found at the server (404) + Contenu distant introuvable (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Echec d'authentification avec le serveur distant + + + The Network Access API cannot honor the request because the protocol is not known + Protocole inconnu + + + The requested operation is invalid for this protocol + Opération invalide pour ce protocole + + + An unknown network-related error was detected + Erreur inconnue relative au réseau + + + An unknown proxy-related error was detected + Erreur inconnue relative au serveur mandataire + + + An unknown error related to the remote content was detected + Erreur inconnue relative au serveur distant + + + A breakdown in protocol was detected + Erreur du protocole + + + Unknown error + Erreur inconnue + + + + engineSelect + + + Search plugins + Greffons de recherche + + + + Installed search engines: + Moteurs de recherche installés : + + + + Name + Nom + + + + Url + Adresse + + + + + Enabled + Activé + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Autres plugins de recherche ici : <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Installer un nouveau + + + + Check for updates + Mettre à jour + + + + Close + Fermer + + + Enable + Activer + + + Disable + Désactiver + + + + Uninstall + Désinstaller + + + + engineSelectDlg + + + Uninstall warning + Désinstallation + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Quelques greffons de recherche n'ont pas pu être désinstallés car ils sont inclus dans qBittorrent. + Seuls ceux que vous avez installés vous-même sont désinstallables. +Cependant, les greffons en question ont été désactivés. + + + + Uninstall success + Désinstallation réussie + + + + Select search plugins + Sélectionnez les greffons + + + + qBittorrent search plugins + Greffons de recherche de qBittorrent + + + + + + + + Search plugin install + Installation d'un greffon de recherche + + + + + + Yes + Oui + + + + + + + No + Non + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Une version plus récente du greffon %1 est déjà installée. + + + + + + + Search plugin update + Mise à jour du greffon de recherche + + + + + Sorry, update server is temporarily unavailable. + Désolé, le serveur de mise à jour est temporairement indisponible. + + + + All your plugins are already up to date. + Tous vos greffons de recherche sont déjà à jour. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + Le greffon de recherche %1 n'a pas pu être mis à jour, l'ancienne version est conservée. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Le greffon de recherche %1 n'a pas pu être installé. + + + + All selected plugins were uninstalled successfully + Tous les greffons sélectionnés ont été désinstallés avec succès + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + Le greffon %1 a été mis à jour avec succès. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Le greffon %1 a été installé avec succès. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Désolé, l'installation du greffon de recherche %1 a échouée. + + + + New search engine plugin URL + Adresse du nouveau greffon de recherche + + + + URL: + Adresse : + + + + misc + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent va maintenant éteindre l'ordinateur car tous les téléchargements sont terminés. + + + + B + bytes + o + + + + KiB + kibibytes (1024 bytes) + Ko + + + + MiB + mebibytes (1024 kibibytes) + Mo + + + + GiB + gibibytes (1024 mibibytes) + Go + + + + TiB + tebibytes (1024 gibibytes) + To + + + + %1h %2m + e.g: 3hours 5minutes + %1h %2m + + + + %1d %2h + e.g: 2days 10hours + %1j %2h + + + + + + + + + Unknown + Inconnu + + + + Unknown + Unknown (size) + Inconnue + + + + < 1m + < 1 minute + < 1min + + + + %1m + e.g: 10minutes + %1min + + + + options_imp + + + Add directory to scan + Ajouter un dossier à surveiller + + + + Folder is already being watched. + Ce dossier est déjà surveillé. + + + + Folder does not exist. + Ce dossier n'existe pas. + + + + Folder is not readable. + Ce dossier n'est pas accessible en lecture. + + + + Failure + Echec + + + + Failed to add Scan Folder '%1': %2 + Impossible d'ajouter le dossier surveillé '%1' : %2 + + + + + Choose export directory + Choisir un dossier pour l'export + + + + + + + Choose a save directory + Choisir un répertoire de sauvegarde + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + SSL Certificate (*.crt) + Certificat SSL (*.crt) + + + SSL Key (*.key) + Clé SSL (*.key) + + + + Parsing error + Erreur de traitement + + + + Failed to parse the provided IP filter + Impossible de charger le filtre IP fourni + + + + Successfully refreshed + Correctement rechargé + + + + Invalid key + Clé invalide + + + + This is not a valid SSL key. + Ceci n'est pas une clé SSL valide. + + + + Invalid certificate + Certificat invalide + + + + This is not a valid SSL certificate. + Ceci n'est pas un certificat SSL valide. + + + Succesfully refreshed + Correctement rechargé + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Le filtre IP fourni a été correctement chargé : %1 règles ont été appliquées. + + + + + Choose an ip filter file + Choisir un fichier de filtrage IP + + + + + Filters + Filtres + + + + pluginSourceDlg + + + Plugin source + Source du greffon + + + + Search plugin source: + Source du greffon de recherche : + + + + Local file + Fichier local + + + + Web link + Lien internet + + + + preview + + + Preview selection + Selection du fichier à prévisualiser + + + + File preview + Prévisualisation + + + + The following files support previewing, <br>please select one of them: + Les fichiers suivants peuvent être prévisualisés, <br>Veuillez en sélectionner un : + + + + Preview + Prévisualiser + + + + Cancel + Annuler + + + + previewSelect + + Preview impossible + Prévisualisation impossible + + + Sorry, we can't preview this file + Désolé, il est impossible de prévisualiser ce fichier + + + Name + Nom + + + Size + Taille + + + Progress + Progression + + + + search_engine + + + + Search + Recherche + + + + Status: + Statut : + + + + Stopped + Stoppé + + + + Download + Télécharger + + + + Go to description page + Aller à la page de description + + + + Search engines... + Moteurs de recherche... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + Impossible de décoder le fichier torrent : + + + + + + Choose save path + Choix du répertoire de destination + + + + Rename... + Renommer... + + + + Unable to decode magnet link: + Impossible de décoder le lien magnet : + + + + Magnet Link + Lien Magnet + + + + Rename the file + Renommer le fichier + + + + New name: + Nouveau nom : + + + + + The file could not be renamed + Renommage impossible + + + + This file name contains forbidden characters, please choose a different one. + Ce nom de fichier contient des caractères interdits, veuillez en choisir un autre. + + + + + This name is already in use in this folder. Please use a different name. + Ce nom est déjà utilisé au sein de ce dossier. Veuillez choisir un autre nom. + + + + The folder could not be renamed + Renommage du dossier impossible + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 disponible after téléchargement) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 de plus sont nécessaires) + + + + Empty save path + Chemin de destination vide + + + + Please enter a save path + Veuillez entrer un répertoire de destination + + + + Save path creation error + Erreur lors de la création du répertoire de destination + + + + Could not create the save path + Impossible de créer le répertoire de destination + + + + Invalid label name + Nom de catégorie incorrect + + + + Please don't use any special characters in the label name. + Veuillez ne pas utiliser de caractères spéciaux dans le nom de catégorie. + + + + Seeding mode error + Erreur du mode partage + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Vous avez choisir de ne pas vérifier les fichiers locaux. Cependant, les fichiers locaux n'ont pas été trouvé dans le répertoire de destination actuel. Veuillez désactiver cette fonctionnalité ou alors changer de répertoire de destination. + + + + Invalid file selection + Sélection de fichiers invalide + + + + You must select at least one file in the torrent + Veuillez sélectionner au moins un fichier dans le torrent + + + + Priority + Priorité + + + diff --git a/src/lang/qbittorrent_gl.qm b/src/lang/qbittorrent_gl.qm new file mode 100644 index 0000000000000000000000000000000000000000..2feabf591d7b70004a478ce1e2d53bfc2fd8a7a2 GIT binary patch literal 122470 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 + + + + AboutDlg + + + About qBittorrent + Sobre qBittorrent + + + + About + Sobre + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Un cliente Bittorrent escrito en C++, basado en Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">e libtorrent-rasterbar. <br /><br />Dereitos de autor ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Páxina web:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Foro:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + Author + Autor + + + + Name: + Nome: + + + + Country: + País: + + + + E-mail: + Correo-e: + + + + Christophe Dumez + Christophe Dumez + + + + France + Francia + + + + Translation + Tradución + + + + License + Licenza + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Un cliente Bittorrent escrito en C++, basado en Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">e libtorrent-rasterbar. <br /><br />Dereitos de autor ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Páxina web:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Foro:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + chris@qbittorrent.org + chris@qbittorrent.org + + + + Thanks to + Grazas a + + + + AdvancedSettings + + Property + Propiedade + + + Value + Valor + + + + Disk write cache size + Tamaño da caché de escritura no disco + + + + MiB + MiB + + + + Outgoing ports (Min) [0: Disabled] + Portos de saída (Min) [0: Desactivado] + + + + Outgoing ports (Max) [0: Disabled] + Portos de saída (Max) [0: Desactivado] + + + + Recheck torrents on completion + Volver comprobar os torrents ao rematar + + + + Transfer list refresh interval + Intervalo de refresco da lista de transferencias + + + + ms + milliseconds + ms + + + + Setting + Configuración + + + + Value + Value set for this setting + Valor + + + + Resolve peer countries (GeoIP) + Mostrar os países dos pares (Geoip) + + + + Resolve peer host names + Mostrar os servidores dos pares + + + + Maximum number of half-open connections [0: Disabled] + Número máximo de conexións semi-abertas [0: Desactivado] + + + + Strict super seeding + Super sementeira estrita + + + + Network Interface (requires restart) + Interface de rede (necesita reiniciar) + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + Calquera interface + + + + IP Address to report to trackers (requires restart) + Enderezo IP que enviar aos localizadores (necesita reiniciar) + + + + Display program on-screen notifications + Mostrar as notificacións na pantalla + + + Display program notification balloons + Mostrar as notificacións do programa + + + + Enable embedded tracker + Activar o localizador integrado + + + + Embedded tracker port + Porto do localizador integrado + + + + Check for software updates + Comprobar se hai actualizacións + + + + Use system icon theme + Usar o tema das iconas do sistema + + + + Confirm torrent deletion + Confirmar a eliminación do torrent + + + + Ignore transfer limits on local network + Ignorar os límites de transferencia na rede local + + + Include TCP/IP overhead in transfer limits + Incluír a sobrecarga TCP/IP nos límites da transferencia + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Xestor de descargas RSS automático + + + + Enable the automated RSS downloader + Activar o xestor de descargas RSS automático + + + + Download rules + Regras de descarga + + + + Rule definition + Definición da regra + + + + Must contain: + Debe conter: + + + + Must not contain: + Non debe conter: + + + + Use regular expressions + Usar expresións regulares + + + + Import... + Importar... + + + + Export... + Exportar... + + + + ... + ... + + + + Assign label: + Asignar etiqueta: + + + + Save to a different directory + Gardar nun cartafol diferente + + + + Save to: + Gardar en: + + + + Apply rule to feeds: + Aplicar a regra ás fontes: + + + + Matching RSS articles + Artigos RSS coincidintes + + + + New rule name + Nome da regra nova + + + + Please type the name of the new download rule. + Escriba o nome da regra de descarga nova. + + + + + Rule name conflict + Conflito co nome da regra + + + + + A rule with this name already exists, please choose another name. + Xa existe unha regra con este nome. Escolla un diferente. + + + + Are you sure you want to remove the download rule named %1? + Está seguro que desexa eliminar a regra de descarga chamada %1? + + + + Are you sure you want to remove the selected download rules? + Está seguro que desexa eliminar as regras de descarga seleccionadas? + + + + Rule deletion confirmation + Confirmación de eliminación da regra + + + + Destination directory + Cartafol de destino + + + + Invalid action + A acción non é válida + + + + The list is empty, there is nothing to export. + A lista está baleira, non hai nada que exportar. + + + + Where would you like to save the list? + Onde desexa gardar a lista? + + + + Rules list (*.rssrules) + Lista de regras (*.rssrules) + + + + I/O Error + Erro de E/S + + + + Failed to create the destination file + Produciuse un fallo ao crear o cartafol de destino + + + + Please point to the RSS download rules file + Indique o ficheiro de regras de descarga RSS + + + + Rules list (*.rssrules *.filters) + Lista de regras (*.rssrules *.filters) + + + + Import Error + Erro de importación + + + + Failed to import the selected rules file + Produciuse un fallo ao importar o ficheiro de regras seleccionado + + + + Add new rule... + Engadir unha regra nova... + + + + Delete rule + Eliminar a regra + + + + Rename rule... + Cambiar o nome da regra... + + + + Delete selected rules + Eliminar as regras seleccionadas + + + + Rule renaming + Cambio do nome da regra + + + + Please type the new rule name + Escriba o nome da regra nova + + + + Regex mode: use Perl-like regular expressions + Modo Regex: usa Perl como expresións regulares + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Modo comodín: pode usar<ul><li>? para substituír calquera caracter</li><li>* para substituír o cero ou máis dun caracter</li><li>Espazos en branco úsanse como operador AND</li></ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Modo comodín: pode usar<ul><li>? para substituír calquera caracter</li><li>* para substituír o cero ou máis dun caracter</li><li>| úsase como operador OR</li></ul> + + + + CookiesDlg + + + Cookies management + Xestión das cookies + + + + Key + As in Key/Value pair + Chave + + + + Value + As in Key/Value pair + Valor + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + As chaves comúns para as cookies son '%1', '%2'. +Debería obter esta información nas preferencias do navegador. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + O DNS dinámico actualizouse correctamente. + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Erro de DNS dinámico: o servizo non está dispoñíbel temporalmente, intentarase de novo dentro de 30 minutos. + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Erro de DNS dinámico: o nome do servidor indicado non existe nesta conta específica. + + + + Dynamic DNS error: Invalid username/password. + Erro de DNS dinámico: nome do usuario/contrasinal incorrectos. + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Erro de DNS dinámico: o qBittorrent está na lista negra deste servizo, por favor informe deste erro en http://bugs.qbittorrent.org. + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Erro de DNS dinámico: o servizo devolveu %1 , por favor informe deste erro en http://bugs.qbittorrent.org. + + + + Dynamic DNS error: Your username was blocked due to abuse. + Erro de DNS dinámico: o nome do usuario foi bloqueado por un abuso. + + + + Dynamic DNS error: supplied domain name is invalid. + Erro de DNS dinámico: o nome do dominio indicado non é correcto. + + + + Dynamic DNS error: supplied username is too short. + Erro de DNS dinámico: o nome do dominio indicado é curto de máis. + + + + Dynamic DNS error: supplied password is too short. + Erro de DNS dinámico: o contrasinal indicado é curto de máis. + + + + DownloadThread + + + + I/O Error + Erro de E/S + + + + The remote host name was not found (invalid hostname) + Non se encontrou o nome do servidor remoto (nome incorrecto) + + + + The operation was canceled + Cancelouse a operación + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + O servidor remoto pechou a conexión prematuramente, antes de que se recibise e procesase a resposta completa + + + + The connection to the remote server timed out + Excedeuse o tempo para conectar co servidor remoto + + + + SSL/TLS handshake failed + Produciuse un fallo no saúdo do SSL/TLS + + + + The remote server refused the connection + O servidor remoto rexeitou a conexion + + + + The connection to the proxy server was refused + O servidor proxy rexeitou a conexión + + + + The proxy server closed the connection prematurely + O servidor proxy pechou a conexión prematuramente + + + + The proxy host name was not found + Non se encontrou o nome do servidor proxy + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Excedeuse o tempo para conectar co proxy ou este non respondeu en tempo á solicitude enviada + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + O proxy require autenticación para admitir a solicitude pero non aceptou ningunha das credenciais ofrecidas + + + + The access to the remote content was denied (401) + Denegouse o acceso ao contido remoto (401) + + + + The operation requested on the remote content is not permitted + Non se permite a operación solicitada no contido remoto + + + + The remote content was not found at the server (404) + Non se encontrou o contido remoto no servidor (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + O servidor remoto require autenticacion para servir o contido pero non aceptou as credenciais enviadas + + + + The Network Access API cannot honor the request because the protocol is not known + A API de acceso á rede non pode responder á solicitude porque o protocolo é descoñecido + + + + The requested operation is invalid for this protocol + A operación solicitada é incorrecta para este protocolo + + + + An unknown network-related error was detected + Detectouse un erro descoñecido relacionado coa rede + + + + An unknown proxy-related error was detected + Detectouse un erro descoñecido relacionado co proxy + + + + An unknown error related to the remote content was detected + Detectouse un erro descoñecido relacionado co contido remoto + + + + A breakdown in protocol was detected + Detectouse unha interrupción no protocolo + + + + Unknown error + Erro descoñecido + + + + EventManager + + + + Working + Traballando + + + + Updating... + Actualizando... + + + + + Not working + Inactivo + + + + + Not contacted yet + Aínda sen contactar + + + + + this session + esta sesión + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Sementado durante %1 + + + + %1 max + e.g. 10 max + %1 max + + + + + %1/s + e.g. 120 KiB/s + %1/s + + + + ExecutionLog + + + General + Xeral + + + + Blocked IPs + IPs bloqueadas + + + + FeedListWidget + + + RSS feeds + Fontes RSS + + + + Unread + Sen ler + + + + HeadlessLoader + + + Information + Información + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Para controlar o qBittorrent acceda á interface web en http://localhost:%1 + + + + The Web UI administrator user name is: %1 + O nome do administrador da interface web é: %1 + + + + The Web UI administrator password is still the default one: %1 + O contrasinal do administrador da interface web é aínda o predefinido: %1 + + + + This is a security risk, please consider changing your password from program preferences. + Isto é un risco de seguranza, debería cambiar o seu contrasinal nas preferencias do programa. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + A súa IP foi bloqueada despois de varios fallos de autenticación. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + E: %1/s - T: %2 + + + + HttpServer + + + File + Ficheiro + + + + Edit + Editar + + + + Help + Axuda + + + Delete from HD + Eliminar do disco + + + + Download Torrents from their URL or Magnet link + Descargar os torrents desde unha URL ou ligazón Magnet + + + + Only one link per line + Só unha ligazón por liña + + + + Download local torrent + Descargar un torrent local + + + + Torrent files were correctly added to download list. + Os ficheiros torrent engadíronse correctamente á lista de descargas. + + + + Point to torrent file + Indicar o ficheiro torrent + + + + Download + Descargar + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Está seguro que desexa eliminar os torrents seleccionados da lista e do disco? + + + + Download rate limit must be greater than 0 or disabled. + O límite da velocidade de descarga ten que ser superior a 0 ou debe desactivalo. + + + + Upload rate limit must be greater than 0 or disabled. + O límite da velocidade de envío ten que ser superior a 0 ou debe desactivalo. + + + + Maximum number of connections limit must be greater than 0 or disabled. + O límite do número máximo de conexións ten que ser superior a 0 ou debe desactivalo. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + O límite do número máximo de conexións por torrent ten que ser superior a 0 ou debe desactivalo. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + O límite do número máximo de slots de envío por torrent ten que ser superior a 0 ou debe desactivalo. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Non foi posíbel gardar as preferencias do programa, probabelmente o qBittorrent estea inaccesíbel. + + + + Language + Idioma + + + + Downloaded + Is the file downloaded or not? + Descargado + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + O porto usado para as conexións entrantes debe ser superior ao 1024 e inferior ao 65535. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + O porto usado para a interface web debe ser superior ao 1024 e inferior ao 65535. + + + + The Web UI username must be at least 3 characters long. + O nome de usuario da interface web debe ter polo menos 3 caracteres. + + + + The Web UI password must be at least 3 characters long. + O contrasinal da interface web debe ter polo menos 3 caracteres. + + + + Save + Gardar + + + + qBittorrent client is not reachable + O cliente qBittorrent non está accesíbel + + + + HTTP Server + Servidor HTTP + + + + The following parameters are supported: + Os seguintes parámetros non son compatíbeis: + + + + Torrent path + Ruta ao torrent + + + + Torrent name + Nome do torrent + + + + LegalNotice + + + Legal Notice + Aviso legal + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent é un programa para compartir ficheiros. Cando descarga un torrent os seus datos son visíbeis para outros . Calquera contido que comparta é da súa única responsabilidade. + +Non se mostrarán máis avisos. + + + + Press %1 key to accept and continue... + Prema a tecla %1 para aceptar e continuar... + + + + Legal notice + Aviso legal + + + + Cancel + Cancelar + + + + I Agree + Acepto + + + + LineEdit + + + Clear the text + Borrar o texto + + + + MainWindow + + + &Edit + &Editar + + + + &Tools + Ferramen&tas + + + + &File + &Ficheiro + + + + &Help + &Axuda + + + + &View + &Ver + + + + &Options... + &Opcións... + + + + &Resume + Continua&r + + + + R&esume All + Co&ntinuar todo + + + + Torrent &creator + &Crear torrents + + + + + Alternative speed limits + Límites alternativos de velocidade + + + + Top &tool bar + Barra &superior + + + + Display top tool bar + Mostrar a barra superior + + + + &Speed in title bar + &Velocidade na barra do título + + + + Show transfer speed in title bar + Mostrar a velocidade de transferencia na barra do título + + + + &About + &Sobre + + + + &Add torrent file... + Eng&adir un ficheiro torrent... + + + + + Exit + Saír + + + + &Pause + &Pausar + + + + &Delete + &Borrar + + + + P&ause All + P&ausar todo + + + + Visit &Website + Visitar o sitio &web + + + + Auto-Shutdown on downloads completion + Apagar ao completar as descargas + + + + Add &link to torrent... + Engadir unha &ligazón ao torrent... + + + + Report a &bug + Informar dun &fallo + + + + Set upload limit... + Estabelecer o límite de envío... + + + + Set download limit... + Estabelecer o límite de descarga... + + + + &Documentation + &Documentación + + + + Set global download limit... + Estabelecer o límite global de descarga... + + + + Set global upload limit... + Estabelecer o límite global de envío... + + + + &RSS reader + Lector &RSS + + + + Search &engine + M&otor de busca + + + + Exit qBittorrent + Saír do qBittorrent + + + + Suspend system + Suspender o sistema + + + + Shutdown system + Pechar o sistema + + + + Disabled + Desactivado + + + + + Lock qBittorrent + Bloquear o qBittorrent + + + + Ctrl+L + Ctrl+L + + + + Import existing torrent... + Importar un torrent existente... + + + + Import torrent... + Importar un torrent... + + + + Donate money + Facer unha doazón + + + + If you like qBittorrent, please donate! + Se lle gusta o qBittorrent, por favor faga unha doazón! + + + + Execution &Log + &Rexistro de execución + + + + + Execution Log + Rexistro de execución + + + + Decrease priority + Disminuír a prioridade + + + + Increase priority + Aumentar a prioridade + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + Estabelecer o contrasinal... + + + + Transfers + Transferencias + + + + Torrent file association + Asociación cos ficheiros torrent + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent non é o aplicativo predefinido para abrir os ficheiros torrent nin as ligazóns Magnet +Desexa asociar o qBittorrent aos ficheiros torrent e ás ligazóns Magnet? + + + + + + UI lock password + Contrasinal de bloqueo da interface + + + + + + Please type the UI lock password: + Escriba un contrasinal para bloquear a interface: + + + + The password should contain at least 3 characters + O contrasinal debe conter cando menos 3 caracteres + + + + Password update + Actualizar o contrasinal + + + + The UI lock password has been successfully updated + O contrasinal de bloqueo da interface actualizouse correctamente + + + + RSS + RSS + + + + Search + Buscar + + + + Transfers (%1) + Transferencias (%1) + + + + Download completion + FInalización da descarga + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Finalizou a descarga de %1. + + + + I/O Error + i.e: Input/Output Error + Erro de E/S + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Produciuse un erro de E/S no torrent %1 +Razón: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Confirmación de descarga recursiva + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + O torrent %1 contén ficheiros torrent, desexa continuar coa descarga? + + + + + Yes + Si + + + + + No + Non + + + + Never + Nunca + + + + Url download error + Erro na descarga desde o Url + + + + Couldn't download file at url: %1, reason: %2. + Non foi posíbel descargar o ficheiro desde o Url: %1, razón: %2. + + + + Global Upload Speed Limit + Límite global de velocidade de envío + + + + Global Download Speed Limit + Límite global de velocidade de descarga + + + + + Invalid password + Contrasinal incorrecto + + + + The password is invalid + O contrasinal é incorrecto + + + + Exiting qBittorrent + Saíndo do qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Estanse transferindo algúns ficheiros. +Está seguro que desexa saír do qBittorrent? + + + + Always + Sempre + + + + Open Torrent Files + Abrir os ficheiros torrent + + + + Torrent Files + Ficheiros torrent + + + + Options were saved successfully. + Os axustes gardáronse correctamente. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Veloc. de descarga: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Veloc. de envío: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (D: %2/s, E: %3/s) + + + + A newer version is available + Hai dispoñíbel unha nova versión + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Hai dispoñíbel unha nova versión en Sourceforge. +Desexa actualizar o qBittorrent a esta versión %1? + + + + Impossible to update qBittorrent + Non foi posíbel actualizar o qBittorrent + + + + qBittorrent failed to update, reason: %1 + Produciuse un fallo na actualización do qBittorrent, razón: %1 + + + + PeerAdditionDlg + + + Invalid IP + IP incorrecta + + + + The IP you provided is invalid. + A IP indicada é incorrecta. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + IP + + + + Connection + Conexión + + + + Client + i.e.: Client application + Cliente + + + + Progress + i.e: % downloaded + Progreso + + + + Down Speed + i.e: Download speed + Veloc. de descarga + + + + Up Speed + i.e: Upload speed + Veloc. de envío + + + + Downloaded + i.e: total data downloaded + Descargado + + + + Uploaded + i.e: total data uploaded + Enviado + + + + Add a new peer... + Engadir un par novo... + + + + Copy IP + Copiar a IP + + + + Limit download rate... + Límite da velocidade de descarga... + + + + Limit upload rate... + Límite da velocidade de envío... + + + + Ban peer permanently + Bloquear este par pemanentemente + + + + + Peer addition + Adición de pares + + + + The peer was added to this torrent. + O par foi engadido a este torrent. + + + + The peer could not be added to this torrent. + Non foi posíbel engadir o par a este torrent. + + + + Are you sure? -- qBittorrent + Está seguro? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Está seguro que desexa bloquear permantemente os pares seleccionados? + + + + &Yes + &Si + + + + &No + &Non + + + + Manually banning peer %1... + Bloqueando manualmente o par %1... + + + + Upload rate limiting + Límites da velocidade de envío + + + + Download rate limiting + Límites da velocidade de descarga + + + + Preferences + + UI + User Interface + Interface + + + + Downloads + Descargas + + + + Connection + Conexión + + + + Speed + Velocidade + + + + Web UI + Interface web + + + + Advanced + Avanzado + + + Language: + Idioma: + + + + (Requires restart) + (Precisa reiniciar) + + + Visual style: + Estilo visual: + + + Transfer list + Lista de transferencias + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Alternar as cores das filas + + + + + Start / Stop Torrent + Iniciar / Parar o torrent + + + + + No action + Sen acción + + + File system + Sistema de ficheiros + + + + Copy .torrent files to: + Copiar os ficheiros torrent en: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Os seguintes parámetros son compatíbeis: +<ul> +<li>%f: ruta ao torrent</li> +<li>%n: nome ao torrent</li> +</ul> + + + + Listening Port + Porto de escoita + + + + Connections Limits + Límites da conexión + + + + Proxy Server + Servidor proxy + + + + Enable bandwidth management (uTP) + Activar a xestión do largo de banda (uTP) + + + + Enable Local Peer Discovery to find more peers + Activar a busca de pares locais (LPD) para encontrar máis pares + + + + Encryption mode: + Modo cifrado: + + + + Prefer encryption + Preferir cifrado + + + + Require encryption + Precisa cifrado + + + + Disable encryption + Desactivar o cifrado + + + Torrent queueing + Colocar na cola + + + + Maximum active downloads: + Descargas activas máximas: + + + + Maximum active uploads: + Envíos activos máximos: + + + + Maximum active torrents: + Torrents activos máximos: + + + + When adding a torrent + Cando engada un torrent + + + + + Behavior + Comportamento + + + + Language + Idioma + + + + Display torrent content and some options + Mostrar o contido do torrent e algunhas opcións + + + Listening port + Escoitando o porto + + + + Port used for incoming connections: + Porto usado para as conexións entrantes: + + + + Random + Aleatorio + + + Connections limit + Límite de conexións + + + + Global maximum number of connections: + Número máximo global de conexións: + + + + Maximum number of connections per torrent: + Número máximo de conexións por torrent: + + + + Maximum number of upload slots per torrent: + Número máximo de slots de envío por torrent: + + + + + Upload: + Enviar: + + + + + Download: + Descargar: + + + + + + + KiB/s + KiB/s + + + Global speed limits + Límites globais de velocidade + + + + Remove folder + Eliminar o cartafol + + + Alternative global speed limits + Límites alternativos globais de velocidade + + + + to + time1 to time2 + a + + + + Every day + Todos os días + + + + Week days + Días da semana + + + + Week ends + Fins de semana + + + + DHT port: + Porto DHT: + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Clientes de bittorrent compatíbeis co intercambio de pares (µTorrent, Vuze, ...) + + + + Host: + Servidor: + + + + SOCKS4 + SOCKS4 + + + + Type: + Tipo: + + + + + Options + Opcións + + + User Interface + Interface de usuario + + + Visual Appearance + Aparencia visual + + + + Action on double-click + Acción co dobre clic + + + + Downloading torrents: + Descargando os torrents: + + + + + Open destination folder + Abrir o cartafol de destino + + + + Completed torrents: + Torrents completados: + + + + Desktop + Escritorio + + + + Show splash screen on start up + Mostrar a pantalla de presentación ao iniciar + + + + Start qBittorrent minimized + Iniciar o qBittorrent minimizado + + + Show qBittorrent icon in notification area + Mostrar a icona do qBittorrent na área de notificación + + + Use monochrome system tray icon (requires restart) + Usar unha icona monocroma na bandexa do sistema (precisa reiniciar) + + + + Minimize qBittorrent to notification area + Minimizar o qBittorrent á area de notificación + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Pechar o qBittorrent á área de notificación + + + + Tray icon style: + Estilo da icona da bandexa: + + + + Normal + Normal + + + + Monochrome (Dark theme) + Monocromo (tema escuro) + + + + Monochrome (Light theme) + Monocromo (tema claro) + + + + Ask for program exit confirmation + Pedir a confirmación de saída do programa + + + + User Interface Language: + Idioma da interface do usuario: + + + + Transfer List + Lista de transferencias + + + + Show qBittorrent in notification area + Mostrar o qBittorrent na área de notificacións + + + + Power Management + Xestión de enerxía + + + + Inhibit system sleep when torrents are active + Inhibir a suspensión do sistema cando haxa torrents activos + + + + Do not start the download automatically + The torrent will be added to download list in pause state + Non iniciar a descarga automaticamente + + + + Hard Disk + Disco ríxido + + + + Save files to location: + Gardar os ficheiros na localización: + + + + Append the label of the torrent to the save path + Anexar a etiqueta do torrent á ruta onde se garda + + + + Pre-allocate disk space for all files + Pre-asignar o espazo no disco a todos os ficheiros + + + + Keep incomplete torrents in: + Manter os torrents incompletos en: + + + Append .!qB extension to incomplete files' names + Anexar a extensión !qB aos nomes dos ficheiros incompletos + + + + Automatically add torrents from: + Engadir automaticamente os torrents desde: + + + + Add folder... + Engadir un cartafol... + + + + Email notification upon download completion + Enviar un correo-e ao rematar a descarga + + + + Destination email: + Correo-e de destino: + + + + SMTP server: + Servidor SMTP: + + + + This server requires a secure connection (SSL) + Este servidor require unha conexión segura (SSL) + + + + Run an external program on torrent completion + Executar un programa externo ao rematar o torrent + + + + Otherwise, the proxy server is only used for tracker connections + Doutro xeito, o servidor proxy usarase unicamente para conexións co localizador + + + + Use proxy for peer connections + Usar o proxy para conexións cos pares + + + + Global Rate Limits + Límites globais de velocidade + + + + Apply rate limit to uTP connections + Aplicar o límite de velocidade ás conexións uTP + + + + Apply rate limit to transport overhead + Aplicar os límites de velocidade ás sobrecargas do transporte + + + + Alternative Global Rate Limits + Límites alternativos globais de velocidade + + + + Schedule the use of alternative rate limits + Programar o uso de límites alternativos de velocidade + + + + Use HTTPS instead of HTTP + Usar HTTPS no canto de HTTP + + + + Import SSL Certificate + Importar o certificado SSL + + + + Import SSL Key + Importar a chave SSL + + + + Certificate: + Certificado: + + + + Key: + Chave: + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Información sobre certificados</a> + + + + Update my dynamic domain name + Actualizar o nome do dominio dinámico + + + + Service: + Servizo: + + + + Register + Rexistro + + + + Domain name: + Nome do dominio: + + + Use %f to pass the torrent path in parameters + Usar %f para pasar a ruta do torrent a parámetros + + + + Use UPnP / NAT-PMP port forwarding from my router + Usar un porto UPnP / NAT-PMP para reencamiñar desde o router + + + Proxy server + Servidor proxy + + + + IP Filtering + Filtrado de IPs + + + + Reload the filter + Recargar o filtro + + + Schedule the use of alternative speed limits + Programar o uso de límites alternativos de velocidade + + + + from + from (time1 to time2) + desde + + + + When: + Cando: + + + + Privacy + Privacidade + + + + Enable DHT (decentralized network) to find more peers + Activar o DHT (rede descentralizada) para buscar máis pares + + + + Use a different port for DHT and BitTorrent + Usar un porto diferente para DHT e BitTorrent + + + + Enable Peer Exchange (PeX) to find more peers + Activar o intercambio de pares (PeX) para buscar máis pares + + + + Look for peers on your local network + Buscar pares na súa rede local + + + Share ratio limiting + Limitación da taxa de compartición + + + + Seed torrents until their ratio reaches + Sementar os torrents até alcanzar a taxa + + + + then + despois + + + + Pause them + Pausalos + + + + Remove them + Eliminalos + + + + Use UPnP / NAT-PMP to forward the port from my router + Usar un porto UPnP / NAT-PMP para reencamiñar desde o router + + + + Bypass authentication for localhost + Omitir a autenticación no localhost + + + + (None) + (Nada) + + + + BitTorrent + BitTorrent + + + + HTTP + HTTP + + + + + Port: + Porto: + + + + + + Authentication + Autenticación + + + + Append .!qB extension to incomplete files + Anexar a extensión !qB aos nomes dos ficheiros incompletos + + + + + + + Username: + Nome do usuario: + + + + + + + Password: + Contrasinal: + + + + Torrent Queueing + Colocar na cola + + + + Share Ratio Limiting + Limites da taxa de compartición + + + + Enable Web User Interface (Remote control) + Activar a interface de usuario web (control remoto) + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + Ruta do filtro (.dat, .p2p, .p2b): + + + HTTP Server + Servidor HTTP + + + + PreviewSelect + + + Name + Nome + + + + Size + Tamaño + + + + Progress + Progreso + + + + + + Preview impossible + A previsualización non é posíbel + + + + + + Sorry, we can't preview this file + Sentímolo, non se pode previsualizar este ficheiro + + + + PropListDelegate + + + Not downloaded + Non descargado + + + + + Normal + Normal (priority) + Normal + + + + + High + High (priority) + Alta + + + + Mixed + Mixed (priorities + Mixta + + + + + Maximum + Maximum (priority) + Máxima + + + + PropTabBar + + + General + Xeral + + + + Trackers + Localizadores + + + + Peers + Pares + + + + HTTP Sources + Fontes HTTP + + + + Content + Contido + + + + PropertiesWidget + + + Save path: + Ruta: + + + + Torrent hash: + Hash do torrent: + + + + Share ratio: + Taxa de compartición: + + + + + Downloaded: + Descargado: + + + + Availability: + Dispoñíbel: + + + + Transfer + Transferencia + + + + Uploaded: + Enviado: + + + + Wasted: + Desbotado: + + + + UP limit: + Límite de envío: + + + + DL limit: + Límite de descarga: + + + + Connections: + Conexións: + + + + Time active: + Time (duration) the torrent is active (not paused) + Tempo en activo: + + + + Reannounce in: + Publicar de novo en: + + + + Information + Información + + + + Created on: + Creado o: + + + + Pieces size: + Tamaño dos anacos: + + + + Comment: + Comentario: + + + + Torrent content: + Contido do torrent: + + + + Select All + Seleccionar todo + + + + Select None + Non seleccionar nada + + + + Normal + Normal + + + + High + Alta + + + + Maximum + Máxima + + + + + Do not download + Non descargar + + + + + this session + esta sesión + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Sementado durante %1 + + + + %1 max + e.g. 10 max + %1 máx + + + + + I/O Error + Erro de E/S + + + + This file does not exist yet. + Este ficheiro aínda non existe. + + + + This folder does not exist yet. + Este cartafol aínda non existe. + + + + Rename... + Cambiar o nome... + + + + Priority + Prioridade + + + + Rename the file + Cambiar o nome do ficheiro + + + + New name: + Nome novo: + + + + + The file could not be renamed + Non foi posíbel cambiar o nome do ficheiro + + + + This file name contains forbidden characters, please choose a different one. + Este nome de ficheiro contén caracteres prohibidos, escolla un nome diferente. + + + + + This name is already in use in this folder. Please use a different name. + Este nome de ficheiro xa existe neste cartafol. Use un nome diferente. + + + + The folder could not be renamed + Non foi posíbel cambiar o nome do cartafol + + + + New url seed + New HTTP source + Nova semente desde un url + + + + New url seed: + Nova semente desde un url: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Esta semente desde un url xa está na lista. + + + + + Choose save path + Seleccionar unha ruta onde gardar + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 alcanzou a taxa máxima estabelecida. + + + + Removing torrent %1... + Eliminando o torrent %1... + + + + Pausing torrent %1... + Pausando o torrent %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent está conectado ao porto: TCP/%1 + + + + HTTP user agent is %1 + O axente do usuario HTTP é %1 + + + + Reporting IP address %1 to trackers... + Enviando o enderezo IP %1 aos localizadores... + + + + DHT support [ON], port: UDP/%1 + Soporte DHT [Activado], porto: UDP/%1 + + + + + DHT support [OFF] + Soporte DHT [APAGADO] + + + + PeX support [ON] + Soporte PeX [ACTIVADO] + + + + PeX support [OFF] + Soporte PeX [APAGADO] + + + + Restart is required to toggle PeX support + É necesario reiniciar para cambiar o soporte PeX + + + + Local Peer Discovery support [OFF] + Soporte para busca de pares locais (LPD) [APAGADO] + + + + Encryption support [ON] + Soporte de cifrado [ACTIVADO] + + + + Encryption support [FORCED] + Soporte de cifrado [FORZADO] + + + + Encryption support [OFF] + Soporte de cifrado [APAGADO] + + + + Embedded Tracker [ON] + Localizador integrado [ACTIVADO] + + + + Failed to start the embedded tracker! + Produciuse un fallo ao iniciar o localizador integrado! + + + + Embedded Tracker [OFF] + Localizador integrado [APAGADO] + + + + The Web UI is listening on port %1 + A interface web está escoitando no porto %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Erro na interface de usuario web - Non é posíbel conectar a interface web ao porto %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' eliminouse da lista de transferencias e do disco duro. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' eliminouse da lista de transferencias. + + + + '%1' is not a valid magnet URI. + '%1'non é un URI magnet correcto. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1'xa está na lista de descargas. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + Retomouse '%1' (continuación rápida) + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + O computador suspenderase se non o cancela nos próximos 15 segundos... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + O computador apagarase se non o cancela nos próximos 15 segundos... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent pechará se non o cancela nos próximos 15 segundos... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Analizouse correctamente o filtro IP indicado: aplicáronse %1 regras. + + + + Error: Failed to parse the provided IP filter. + Erro: produciuse un fallo ao analizar o filtro IP indicado. + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + Engadiuse %1 á lista de descargas. + + + + UPnP / NAT-PMP support [ON] + Soporte UPnP / NAT-PMP [ACTIVADO] + + + + UPnP / NAT-PMP support [OFF] + Soporte UPnP / NAT-PMP [APAGADO] + + + + Local Peer Discovery support [ON] + Soporte para busca de pares locais (LPD) [ACTIVADO] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Non foi posíbel decodificar o ficheiro torrent: '%1' + + + + This file is either corrupted or this isn't a torrent. + Este ficheiro está corrupto ou non é un torrent. + + + + Error: The torrent %1 does not contain any file. + Erro: o torrent %1 non contén ningún ficheiro. + + + + Note: new trackers were added to the existing torrent. + Aviso: engadíronse novos localizadores ao torrent existente. + + + + Note: new URL seeds were added to the existing torrent. + Aviso: engadíronse novas sementes URL ao torrent existente. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i> foi bloqueado polo filtro IP</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>foi bloqueado debido ao envío de anacos corruptos</i> + + + + The network interface defined is invalid: %1 + A interface indicada para a rede non é válida: %1 + + + + Trying any other network interface available instead. + Probando outra interface de rede dispoñíbel. + + + + Listening on IP address %1 on network interface %2... + Escoitando no enderezo IP %1 na interface de rede %2... + + + + Failed to listen on network interface %1 + Produciuse un fallo ao escoitar na interface de rede %1 + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Descarga recursiva do ficheiro %1 integrado no torrent %2 + + + + + Unable to decode %1 torrent file. + Non foi posíbel decodificar o ficheiro torrent %1. + + + + Torrent name: %1 + Nome do torrent: %1 + + + + Torrent size: %1 + Tamaño do torrent: %1 + + + + Save path: %1 + Ruta onde gardar: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + O torrent descargouse en %1. + + + + Thank you for using qBittorrent. + Grazas por usar o qBittorrent. + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 rematou a descarga + + + + An I/O error occured, '%1' paused. + Produciuse un erro de E/S, '%1' pausado. + + + + + Reason: %1 + Razón: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: produciuse un fallo no mapeado, mensaxe: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: o mapeado do porto foi correcto, mensaxe: %1 + + + + File sizes mismatch for torrent %1, pausing it. + Os tamaños dos ficheiros non coinciden co torrent %1 , pausándoo. + + + + Fast resume data was rejected for torrent %1, checking again... + Os datos para a continuación rápida do torrent %1 foron rexeitados, comprobando de novo... + + + + Url seed lookup failed for url: %1, message: %2 + Fallou a semente url encontrada na url: %1, mensaxe: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Descargando '%1', espere... + + + + RSS + + + Search + Buscar + + + + New subscription + Subscrición nova + + + + + + Mark items read + Marcar como lidos + + + + Update all + Actualizar todos + + + + RSS Downloader... + Xestor de descargas RSS... + + + + Settings... + Axustes... + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(dobre-clic para descargar)</span></p></body></html> + + + Article title + Título do artigo + + + Feed URL + Url da fonte + + + + + Delete + Eliminar + + + + Rename... + Cambiar o nome... + + + + Rename + Cambiar o nome + + + + + Update + Actualizar + + + + New subscription... + Subscrición nova... + + + + + Update all feeds + Actualizar todas as fontes + + + + Download torrent + Descargar o torrent + + + + Open news URL + Abrir o URL + + + + Copy feed URL + Copiar o URL da fonte + + + + New folder... + Cartafol novo... + + + + Manage cookies... + Xestionar as cookies... + + + + Refresh RSS streams + Actualizar os fluxos RSS + + + + RSSImp + + + Please type a rss stream url + Escriba un url de fluxo rss + + + + Stream URL: + URL de fluxo: + + + + + Are you sure? -- qBittorrent + Está seguro? -- qBittorrent + + + + + &Yes + &Si + + + + + &No + &Non + + + + Please choose a folder name + Seleccione un nome de cartafol + + + + Folder name: + Nome do cartafol: + + + + New folder + Cartafol novo + + + + Overwrite attempt + Intento de sobrescritura + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Non pode sobrescribir %1. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + A fonte rss xa está na lista. + + + + Are you sure you want to delete these elements from the list? + Esta seguro que desexa eliminar estes elementos da lista? + + + + Are you sure you want to delete this element from the list? + Esta seguro que desexa eliminar este elemento da lista? + + + + Please choose a new name for this RSS feed + Escolla un nome novo para esta fonte RSS + + + + New feed name: + Nome novo da fonte: + + + + Name already in use + O nome xa existe + + + + This name is already used by another item, please choose another one. + Este nome xa está usado por un elemento, escolla outro. + + + + Date: + Data: + + + + Author: + Autor: + + + + Unread + Sen ler + + + + RssArticle + + No description available + Non hai unha descrición dispoñíbel + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Descargando automaticamente %1 torrent(s) desde %2 fonte(s) RSS... + + + + RssSettingsDlg + + + RSS Reader Settings + Axustes do lector RSS + + + + RSS feeds refresh interval: + Intervalo de actualización de fontes RSS: + + + + minutes + minutos + + + + Maximum number of articles per feed: + Número máximo de artigos por fonte: + + + + ScanFoldersModel + + + Watched Folder + Cartafol explorado + + + + Download here + Descargar aquí + + + + SearchCategories + + + All categories + Todas as categorías + + + + Movies + Películas + + + + TV shows + Programas de TV + + + + Music + Música + + + + Games + Xogos + + + + Anime + Anime + + + + Software + Software + + + + Pictures + Imaxes + + + + Books + Libros + + + + SearchEngine + + + Cut + Cortar + + + + Copy + Copiar + + + + Paste + Pegar + + + + Clear field + Limpar o campo + + + + Clear completion history + Limpar o historial completo + + + + Confirmation + Confirmación + + + + Are you sure you want to clear the history? + Está seguro que desexa limpar o historial? + + + + + + Search + Buscar + + + + Missing Python Interpreter + Falta o intérprete de Python + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Precísase Python 2.x para usar o motor de busca pero non parece que estea instalado. +Desexa instalalo agora? + + + + Empty search pattern + Patrón de busca baleiro + + + + Please type a search pattern first + Escriba primeiro o patrón de busca + + + + + Results + Resultados + + + + Searching... + Buscando... + + + + Search Engine + Motor de busca + + + + + Search has finished + A busca rematou + + + + An error occured during search... + Produciuse un erro durante a busca... + + + + + Search aborted + Busca cancelada + + + + Download error + Erro de descarga + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Non foi posíbel descargar a configuración de Python, razón:%1. +Instálea manualmente. + + + + Search returned no results + A busca non obtivo resultados + + + + Results + i.e: Search results + Resultados + + + + + Unknown + Descoñecido + + + + SearchTab + + + Name + i.e: file name + Nome + + + + Size + i.e: file size + Tamaño + + + + Seeders + i.e: Number of full sources + Sementadores + + + + Leechers + i.e: Number of partial sources + Pares incompletos + + + + Search engine + Motor de busca + + + + ShutdownConfirmDlg + + + Shutdown confirmation + Confirmación de peche + + + + SpeedLimitDialog + + + KiB/s + KiB/s + + + + StatusBar + + + + Connection status: + Estado da conexión: + + + + + No direct connections. This may indicate network configuration problems. + Non hai conexións directas. Isto pode significar que hai problemas na configuración da rede. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + D: %1 B/s - T: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + E: %1 B/s - T: %2 + + + + + DHT: %1 nodes + DHT: %1 nodos + + + + qBittorrent needs to be restarted + É necesario reiniciar o qBittorrent + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + O qBittorrent foi actualizado e necesita reiniciarse para que os cambios sexan efectivos. + + + + + Connection Status: + Estado da conexión: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Desconectado. Isto significa, normalmente, que o programa fallou ao escoitar o porto seleccionado para conexións entrantes. + + + + Online + Conectado + + + + + %1/s + Per second + %1/s + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + E: %1/s - T: %2 + + + + Click to switch to alternative speed limits + Prema para cambiar aos límites alternativos de velocidade + + + + Click to switch to regular speed limits + Prema para cambiar aos límites normais de velocidade + + + Click to disable alternative speed limits + Prema para desactivar os límites alternativos de velocidade + + + Click to enable alternative speed limits + Prema para activar os limites alternativos de velocidade + + + + Global Download Speed Limit + Límite global de velocidade de descarga + + + + Global Upload Speed Limit + Límite global de velocidade de envío + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Seleccionar un cartafol para engadir ao torrent + + + + Select a file to add to the torrent + Seleccionar un ficheiro para engadir ao torrent + + + + No input path set + Non se estabeleceu unha ruta de entrada + + + + Please type an input path first + Escriba primeiro unha ruta de entrada + + + + Select destination torrent file + Seleccionar o ficheiro torrent de destino + + + + Torrent Files + Ficheiros torrent + + + + + + Torrent creation + Crear un torrent + + + + Torrent creation was unsuccessful, reason: %1 + A creación do torrent fallou, razón:%1 + + + + Created torrent file is invalid. It won't be added to download list. + O ficheiro torrent creado non é válido. Non será engadido á lista de descargas. + + + + Torrent was created successfully: + O torrent creouse correctamente: + + + + TorrentFilesModel + + + Name + Nome + + + + Size + Tamaño + + + + Progress + Progreso + + + + Priority + Prioridade + + + + TorrentImportDlg + + + Torrent Import + Importación de torrents + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + O asistente axudárao a compartir co qBittorrent un torrent descargado. + + + + Torrent file to import: + Ficheiro torrent a importar: + + + + + ... + ... + + + + Content location: + Localización do contido: + + + + Skip the data checking stage and start seeding immediately + Ignorar o paso de comprobación de datos e sementar inmediatamente + + + + Import + Importar + + + + Torrent file to import + Ficheiro torrent a importar + + + + Torrent files (*.torrent) + Ficheiros torrent (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + Ficheiros %1 + + + + Please provide the location of %1 + %1 is a file name + Indique a localización de %1 + + + + Please point to the location of the torrent: %1 + Indique a localización do torrent: %1 + + + + Invalid torrent file + Ficheiro torrent incorrecto + + + + This is not a valid torrent file. + Este non é un ficheiro torrent correcto. + + + + TorrentModel + + + Name + i.e: torrent name + Nome + + + + Size + i.e: torrent size + Tamaño + + + + Done + % Done + Feito + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Estado + + + + Seeds + i.e. full sources (often untranslated) + Sementes + + + + Peers + i.e. partial sources (often untranslated) + Pares + + + + Down Speed + i.e: Download speed + Veloc. de descarga + + + + Up Speed + i.e: Upload speed + Veloc. de envío + + + + Ratio + Share ratio + Taxa + + + + ETA + i.e: Estimated Time of Arrival / Time left + Tempo restante + + + + Label + Etiqueta + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Engadido o + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Completado o + + + + Tracker + Localizador + + + + Down Limit + i.e: Download limit + Límite de descarga + + + + Up Limit + i.e: Upload limit + Límite de envío + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Cantidade descargada + + + + Amount left + Amount of data left to download (e.g. in MB) + Cantidade restante + + + + Time Active + Time (duration) the torrent is active (not paused) + Tempo en activo + + + + TrackerList + + + URL + URL + + + + Status + Estado + + + + Peers + Pares + + + + Message + Mensaxe + + + + [DHT] + [DHT] + + + + [PeX] + [PeX] + + + + [LSD] + [LSD] + + + + + + + + Working + Traballando + + + + + + Disabled + Desactivado + + + + This torrent is private + Este torrent é privado + + + + Updating... + Actualizando... + + + + + Not working + Inactivo + + + + + Not contacted yet + Aínda sen conexión + + + + Add a new tracker... + Engadir un novo localizador... + + + + Remove tracker + Eliminar o localizador + + + + Force reannounce + Forzar a publicación + + + + TrackersAdditionDlg + + + Trackers addition dialog + Diálogo de adición de localizadores + + + + List of trackers to add (one per line): + Lista de localizadores a engadir (un por liña): + + + + µTorrent compatible list URL: + URL da lista compatíbel con µTorrent: + + + + I/O Error + Erro de E/S + + + + Error while trying to open the downloaded file. + Produciuse un erro mentres se tentaba abrir o ficheiro descargado. + + + + No change + Sen cambios + + + + No additional trackers were found. + Non se encontraron localizadores novos. + + + + Download error + Erro de descarga + + + + The trackers list could not be downloaded, reason: %1 + Non foi posíbel descargar a lista de localizadores, razón: %1 + + + + TransferListDelegate + + + Downloading + Descargando + + + + Paused + Pausado + + + + Queued + i.e. torrent is queued + Na cola + + + + Seeding + Torrent is complete and in upload-only mode + Sementando + + + + Stalled + Torrent is waiting for download to begin + Á espera + + + + Checking + Torrent local data is being checked + Comprobando + + + + /s + /second (.i.e per second) + /s + + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Sementado durante %1 + + + + TransferListFiltersWidget + + + + All + Todos + + + + + Downloading + Descargando + + + + + Completed + Completados + + + + + Paused + Pausados + + + + + Active + Activos + + + + + Inactive + Inactivos + + + + + All labels + Todas as etiquetas + + + + + Unlabeled + Sen etiquetar + + + + Remove label + Eliminar a etiqueta + + + + Add label... + Engadir unha etiqueta... + + + + Resume torrents + Continuar os torrents + + + + Pause torrents + Pausar os torrents + + + + Delete torrents + Eliminar os torrents + + + + New Label + Etiqueta nova + + + + Label: + Etiqueta: + + + + Invalid label name + O nome da etiqueta non é correcto + + + + Please don't use any special characters in the label name. + Non use ningún caracter especial no nome da etiqueta. + + + + TransferListWidget + + + Column visibility + Visibilidade da columna + + + + Label + Etiqueta + + + + Choose save path + Seleccionar unha ruta onde gardar + + + + Torrent Download Speed Limiting + Límites da velocidade de descarga do torrent + + + + Torrent Upload Speed Limiting + Límites da velocidade de envío do torrent + + + + New Label + Etiqueta nova + + + + Label: + Etiqueta: + + + + Invalid label name + O nome da etiqueta non é correcto + + + + Please don't use any special characters in the label name. + Non use ningún caracter especial no nome da etiqueta. + + + + Rename + Cambiar o nome + + + + New name: + Nome novo: + + + + Resume + Resume/start the torrent + Continuar + + + + Pause + Pause the torrent + Pausar + + + + Delete + Delete the torrent + Eliminar + + + + Preview file... + Previsualizar o ficheiro... + + + + Limit share ratio... + Límite da taxa de compartición... + + + + Limit upload rate... + Límite da velocidade de envío... + + + + Limit download rate... + Límite da velocidade de descarga... + + + + Open destination folder + Abrir o cartafol de destino + + + + Move up + i.e. move up in the queue + Mover arriba + + + + Move down + i.e. Move down in the queue + Mover abaixo + + + + Move to top + i.e. Move to top of the queue + Mover ao principio + + + + Move to bottom + i.e. Move to bottom of the queue + Mover ao final + + + + Set location... + Estabelecer a localización... + + + + Priority + Prioridade + + + + Force recheck + Forzar outra comprobación + + + + Copy magnet link + Copiar a ligazón magnet + + + + Super seeding mode + Modo super-sementeira + + + + Rename... + Cambiar o nome... + + + + Download in sequential order + Descargar en orde secuencial + + + + Download first and last piece first + Descargar primeiro os anacos inicial e final + + + + New... + New label... + Nova... + + + + Reset + Reset label + Restabelecer + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Límites da taxa de Envío/Descarga do torrent + + + + Use global ratio limit + Usar o límite da taxa global + + + + + + buttonGroup + buttonGroup + + + + Set no ratio limit + Non estabelecer límite na taxa + + + + Set ratio limit to + Estabelecer o límite da taxa en + + + + UsageDisplay + + + Usage: + Utilización: + + + + displays program version + mostra a versión do programa + + + + disable splash screen + desactivar a pantalla de presentación + + + + displays this help message + mostra esta mensaxe de axuda + + + + changes the webui port (current: %1) + cambia o porto da interface web (actual: %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [ficheiros ou urls]: descarga os torrents indicados polo usuario (opcional) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Desexo dar as grazas ás persoas seguintes que como voluntarios traduciron o qBittorrent: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Contacte comigo se desexa traducir o qBittorrent ao seu idioma. + + + + addPeerDialog + + + Peer addition + Adición de pares + + + + IP + IP + + + + Port + Porto + + + + addTorrentDialog + + + Torrent addition dialog + Diálogo de adición de torrents + + + + Save path: + Ruta: + + + + ... + ... + + + + Torrent size: + Tamaño do torrent: + + + + + Unknown + Descoñecido + + + + Free disk space: + Espazo libre no disco: + + + + Label: + Etiqueta: + + + + Torrent content: + Contido do torrent: + + + + Select All + Seleccionar todo + + + + Select None + Non seleccionar nada + + + + Download in sequential order (slower but good for previewing) + Descargar en orde secuencial (máis lento pero mellor para previsualizar) + + + + Skip file checking and start seeding immediately + Ignorar a comprobación do ficheiro e sementar inmediatamente + + + + Add to download list in paused state + Engadir en estado pausado á lista de descargas + + + + Add + Engadir + + + + Cancel + Cancelar + + + + Normal + Normal + + + + High + Alta + + + + Maximum + Máxima + + + + + Do not download + Non descargar + + + + authentication + + + + Tracker authentication + Autenticación do localizador + + + + Tracker: + Localizador: + + + + Login + Iniciar sesión + + + + Username: + Nome do usuario: + + + + Password: + Contrasinal: + + + + Log in + Iniciar sesión + + + + Cancel + Cancelar + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Confirmación de eliminación - 'qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Está seguro que desexa eliminar os torrents seleccionados da lista de transferencias? + + + + Remember choice + Lembrar a elección + + + + Also delete the files on the hard disk + Eliminar tamén os ficheiros do disco duro + + + + createTorrentDialog + + + Cancel + Cancelar + + + + Torrent Creation Tool + Ferramenta para a creación de torrents + + + + Torrent file creation + Crear un ficheiro torrent + + + + Add file + Engadir un ficheiro + + + + Add folder + Engadir un cartafol + + + + File or folder to add to the torrent: + Ficheiro ou cartafol para engadir ao torrent: + + + + Tracker URLs: + URLs do localizador: + + + + Web seeds urls: + URLs das sementes web: + + + + Comment: + Comentario: + + + + Piece size: + Tamaño do anaco: + + + + 32 KiB + 32 KiB + + + + 64 KiB + 64 KiB + + + + 128 KiB + 128 KiB + + + + 256 KiB + 256 KiB + + + + 512 KiB + 512 KiB + + + + 1 MiB + 1 MiB + + + + 2 MiB + 2 MiB + + + + 4 MiB + 4 MiB + + + + Auto + Automático + + + + Private (won't be distributed on DHT network if enabled) + Privado (se está activado non se distribuirá na rede DHT) + + + + Start seeding after creation + Iniciar a sementeira despois da creación + + + + Create and save... + Crear e gardar... + + + + Progress: + Progreso: + + + + downloadFromURL + + + Add torrent links + Engadir ligazóns torrent + + + + Both HTTP and Magnet links are supported + Compatíbel con HTTP e ligazóns magnet + + + + Download + Descargar + + + + Cancel + Cancelar + + + + Download from urls + Descargar desde urls + + + + No URL entered + Non se introduciu ningún URL + + + + Please type at least one URL. + Escriba polo menos un URL. + + + + downloadThread + + I/O Error + Erro de E/S + + + The remote host name was not found (invalid hostname) + Non se encontrou o nome do servidor remoto (nome incorrecto) + + + The operation was canceled + Cancelouse a operación + + + The remote server closed the connection prematurely, before the entire reply was received and processed + O servidor remoto pechou a conexión prematuramente, antes de que se recibise e procesase a resposta completa + + + The connection to the remote server timed out + Excedeuse o tempo para conectar co servidor remoto + + + SSL/TLS handshake failed + Produciuse un fallo no saúdo do SSL/TLS + + + The remote server refused the connection + O servidor remoto rexeitou a conexion + + + The connection to the proxy server was refused + O servidor proxy rexeitou a conexión + + + The proxy server closed the connection prematurely + O servidor proxy pechou a conexión prematuramente + + + The proxy host name was not found + Non se encontrou ou nome do servidor proxy + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Excedeuse o tempo para conectar co proxy ou este non respondeu en tempo á solicitude enviada + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + O proxy require autenticación para admitir a solicitude pero non aceptou ningunha das credenciais ofrecidas + + + The access to the remote content was denied (401) + Denegouse o acceso ao contido remoto (401) + + + The operation requested on the remote content is not permitted + Non se permite a operación solicitada no contido remoto + + + The remote content was not found at the server (404) + Non se encontrou o contido remoto no servidor (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + O servidor remoto require autenticacion para servir o contido pero non aceptou as credenciais enviadas + + + The Network Access API cannot honor the request because the protocol is not known + A API de acceso á rede non pode responder á solicitude porque o protocolo é descoñecido + + + The requested operation is invalid for this protocol + A operación solicitada é incorrecta para este protocolo + + + An unknown network-related error was detected + Detectouse un erro descoñecido relacionado coa rede + + + An unknown proxy-related error was detected + Detectouse un erro descoñecido relacionado co proxy + + + An unknown error related to the remote content was detected + Detectouse un erro descoñecido relacionado co contido remoto + + + A breakdown in protocol was detected + Detectouse unha interrupción no protocolo + + + Unknown error + Erro descoñecido + + + + engineSelect + + + Search plugins + Plugins de busca + + + + Installed search engines: + Motores de busca instalados: + + + + Name + Nome + + + + Url + Url + + + + + Enabled + Activado + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Pode obter novos plugins con motores de busca aquí: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Instalar un novo + + + + Check for updates + Buscar actualizacións + + + + Close + Pechar + + + + Uninstall + Desinstalar + + + + engineSelectDlg + + + Uninstall warning + Aviso de desinstalación + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Algúns plugins non se poden desinstalar porque están incluídos no qBittorrent. +Unicamente pode desinstalar os que vostede engada. +Con todo, eses plugins desactiváronse. + + + + Uninstall success + A desinstalación foi correcta + + + + Select search plugins + Seleccionar os plugins de busca + + + + qBittorrent search plugins + Plugins de busca do qBittorrent + + + + + + + + Search plugin install + Instalación de plugins de busca + + + + + + Yes + Si + + + + + + + No + Non + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Xa está instalada unha versión máis recente do plugin co motor de busca %1. + + + + + + + Search plugin update + Actualización do plugin de busca + + + + + Sorry, update server is temporarily unavailable. + Sentímolo, o servidor de actualizacións non está dispoñíbel temporalmente. + + + + All your plugins are already up to date. + Xa están actualizados todos os plugins. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + Non foi posíbel actualizar o plugin co motor de busca %1, mantense a versión antiga. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Non foi posíbel instalar o plugin co motor de busca %1. + + + + All selected plugins were uninstalled successfully + Desistaláronse correctamente todos os plugins seleccionados + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + O plugin co motor de busca %1 actualizouse correctamente. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + O plugin co motor de busca %1 instalouse correctamente. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Sentímolo pero fallou a instalación do plugin de busca %1. + + + + New search engine plugin URL + URL novo do plugin co motor de busca + + + + URL: + URL: + + + + misc + + + B + bytes + B + + + + KiB + kibibytes (1024 bytes) + KiB + + + + MiB + mebibytes (1024 kibibytes) + MiB + + + + GiB + gibibytes (1024 mibibytes) + GiB + + + + TiB + tebibytes (1024 gibibytes) + TiB + + + + %1h %2m + e.g: 3hours 5minutes + %1h %2m + + + + %1d %2h + e.g: 2days 10hours + %1d %2h + + + + Unknown + Unknown (size) + Descoñecido + + + + qBittorrent will shutdown the computer now because all downloads are complete. + O qBittorrent vai apagar o computador porque remataron todas as descargas. + + + + + + + + + Unknown + Descoñecido + + + + < 1m + < 1 minute + < 1 m + + + + %1m + e.g: 10minutes + %1 m + + + + options_imp + + + + Choose export directory + Seleccionar un cartafol de exportación + + + + + + + Choose a save directory + Seleccionar un cartafol onde gardar + + + + + Choose an ip filter file + Seleccionar un ficheiro para os filtros de ip + + + + Add directory to scan + Engadir un cartafol para explorar + + + + Folder is already being watched. + O cartafol xa está sendo explorado. + + + + Folder does not exist. + O cartafol non existe. + + + + Folder is not readable. + O cartafol non se pode ler. + + + + Failure + Fallo + + + + Failed to add Scan Folder '%1': %2 + Produciuse un fallo ao explorar o cartafol '%1': %2 + + + + + Filters + Filtros + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + Erro de análise + + + + Failed to parse the provided IP filter + Produciuse un fallo ao analizar o filtro Ip indicado + + + + Successfully refreshed + Actualizado correctamente + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + Succesfully refreshed + Actualizado correctamente + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Analizouse correctamente o filtro IP indicado: aplicáronse %1 regras. + + + + pluginSourceDlg + + + Plugin source + Fonte do plugin + + + + Search plugin source: + Fonte do plugin de busca: + + + + Local file + Ficheiro local + + + + Web link + Ligazón web + + + + preview + + + Preview selection + Previsualizar a selección + + + + File preview + Previsualización do ficheiro + + + + The following files support previewing, <br>please select one of them: + Estes ficheiros son compatíbeis coa previsualizaciṕon, <br>seleccione un deles: + + + + Preview + Previsualizar + + + + Cancel + Cancelar + + + + search_engine + + + + Search + Buscar + + + + Status: + Estado: + + + + Stopped + Parado + + + + Download + Descargar + + + + Go to description page + Ir á páxina da descrición + + + + Search engines... + Motores de busca... + + + + torrentAdditionDialog + + + Unable to decode magnet link: + Non é posíbel decodificar a ligazón magnet: + + + + Magnet Link + Ligazón magnet + + + + + Unable to decode torrent file: + Non foi posíbel decodificar o ficheiro torrent: + + + + Rename... + Cambiar o nome... + + + + Priority + Prioridade + + + + Rename the file + Cambiar o nome do ficheiro + + + + New name: + Nome novo: + + + + + The file could not be renamed + Non foi posíbel cambiar o nome do ficheiro + + + + This file name contains forbidden characters, please choose a different one. + Este nome de ficheiro contén caracteres prohibidos, escolla un nome diferente. + + + + + This name is already in use in this folder. Please use a different name. + Este nome de ficheiro xa existe neste cartafol. Use un nome diferente. + + + + The folder could not be renamed + Non foi posíbel cambiar o nome do cartafol + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (Quedarán %1 despois da descarga do ficheiro) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (Precísanse %1 máis para poder facer a descarga) + + + + + + Choose save path + Seleccionar a ruta onde gardar + + + + Empty save path + A ruta está baleira + + + + Please enter a save path + Introduza unha ruta onde gardar + + + + Save path creation error + Produciuse un erro na creación da ruta onde gardar + + + + Could not create the save path + Non foi posíbel crear a ruta onde gardar + + + + Invalid label name + O nome da etiqueta non é correcto + + + + Please don't use any special characters in the label name. + Non use caracteres especiais no nome da etiqueta. + + + + Seeding mode error + Produciuse un erro no modo de sementeira + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Escolleu ignorar a comprobación do ficheiro. Con todo, os ficheiros locais non parecen existir no cartafol de destino actual. Desactive esta función ou actualice a ruta onde gardar. + + + + Invalid file selection + A selección do ficheiro é incorrecta + + + + You must select at least one file in the torrent + Debe seleccionar, polo menos, un dos ficheiros do torrent + + + diff --git a/src/lang/qbittorrent_hr.qm b/src/lang/qbittorrent_hr.qm new file mode 100644 index 0000000000000000000000000000000000000000..1e366ce4596d492b28c9ec08a0eed9c50e93adb8 GIT binary patch literal 118476 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 H{?-2ro>M1t literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_hr.ts b/src/lang/qbittorrent_hr.ts new file mode 100644 index 000000000..c7bd35e87 --- /dev/null +++ b/src/lang/qbittorrent_hr.ts @@ -0,0 +1,6173 @@ + + + + + AboutDlg + + About qBittorrent + O programu qBittorrent + + + About + O + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">A Bittorrent client programmed in C++, based on Qt4 toolkit </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2009 Christophe Dumez<br /><br /><span style=" text-decoration: underline;">Home Page:</span> <a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a><br /></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Bittorrent klijent pisan u programskom jeziku C++, baziran na Qt4 toolkitu </p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">i libtorrent-rasterbaru. <br /><br />Copyright ©2006-2009 Christophe Dumez<br /><br /><span style=" text-decoration: underline;">Web stranica:</span> <a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a><br /></p></body></html> + + + Author + Autor + + + Name: + Ime: + + + Country: + Država: + + + E-mail: + E-pošta: + + + Home page: + Stranica: + + + Christophe Dumez + Christophe Dumez + + + France + Francuska + + + Translation + Prijevod + + + License + Licenca + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + chris@qbittorrent.org + chris@qbittorrent.org + + + http://www.dchris.eu + http://www.dchris.eu + + + Birthday: + Rođendan: + + + Occupation: + Zanimanje: + + + 03/05/1985 + 03. svibnja 1985 + + + Student in computer science + Sudent računalnih znanosti + + + Thanks to + Zahvale + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Bittorrent klijent pisan u C++, baziran na Qt4 programskom alatu </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">i libtorrent-rasterbaru. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Službena stranica:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://qbittorrent.sourceforge.net/</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://qbforums.shiki.hu/</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Napredni BitTorrent klijent pisan u C++-u, baziran na Qt4 programskom alatu i libtorrent-rasterbaru. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Prijava greški:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent na Freenode-u</span></p></body></html> + + + + AdvancedSettings + + Property + Svojstvo + + + Value + Vrijednost + + + Disk write cache size + Veličina privremene memorije pisanja diska + + + MiB + MiB + + + Outgoing ports (Min) [0: Disabled] + Izlazni portovi (Min.) [0: Onemogućeni] + + + Outgoing ports (Max) [0: Disabled] + Izlazni portovi (Maks.) [0: Omogućeni] + + + Recheck torrents on completion + Ponovno provjeri torrente pri dopunjavanju + + + Transfer list refresh interval + Interval osvježavanja popisa transfera + + + ms + milliseconds + ms + + + Resolve peer countries (GeoIP) + Razrješi države peerova (GeoIP) + + + Resolve peer host names + Razrješi imena peer hostova + + + Ignore transfer limits on local network + Zanemari limite transfera na lokalnoj mreži + + + Include TCP/IP overhead in transfer limits + Uključi TCP/IP dodatak u limitima transfera + + + Maximum number of half-open connections [0: Disabled] + Najveći broj poluotvorenih veza [0: Disabled] + + + Strict super seeding + Strogo superseedanje + + + Network Interface (requires restart) + Mrežno sučelje (zahtjeva ponovno pokretanje) + + + Any interface + i.e. Any network interface + Bilo koje sučelje + + + Display program notification baloons + Prikazuj balončiće.obavijesti + + + Display program notification balloons + Prikaži obavjesne balončiće + + + Enable embedded tracker + Omogući ugrađeni tracker + + + Embedded tracker port + Port ugrađenog trackera + + + Check for software updates + Provjeri softverska ažuriranja + + + Use system icon theme + Koristi teme ikona sustava + + + Confirm torrent deletion + Potvrdite brisanje torrenta + + + IP Address to report to trackers (requires restart) + IP adresa za prijaviti trackerima (potrebno ponovno pokretanje) + + + Display program on-screen notifications + Prikazuj obavijesti.na ekranu + + + Setting + Postavka + + + Value + Value set for this setting + Vrijednost + + + Exchange trackers with other peers + + + + + AutomatedRssDownloader + + Automated RSS Downloader + Automatizirani RSS Preuzimatelj + + + Enable the automated RSS downloader + Omogući automatiziranog RSS preuzimatelja + + + Download rules + Preuzmi pravila + + + Rule definition + Definicija pravila + + + Must contain: + Mora sadržavati: + + + Must not contain: + Ne mora sadržavati: + + + ... + ... + + + Assign label: + Dodijeli oznaku: + + + Apply rule to feeds: + Primijeni pravilo na kanal: + + + Matching RSS articles + Poklapanje RSS članaka + + + Save to a different directory + Spremi u drugi direktorij + + + Save to: + Spremi u: + + + Import... + Uvezi ... + + + Export... + Izvezi ... + + + New rule name + Ime novog pravila + + + Please type the name of the new download rule. + Upišite ime novog pravila preuzimanja. + + + Rule name conflict + Konflikt imena pravila + + + A rule with this name already exists, please choose another name. + Pravilo s tim imenom već postoji. Izaberite drugo ime. + + + Are you sure you want to remove the download rule named %1? + Jeste li sigurni da želite ukloniti pravilo preuzimanja pod pod imenom %1? + + + Are you sure you want to remove the selected download rules? + Jeste li sigurni da želite ukloniti odabrana pravila preuzimanja? + + + Rule deletion confirmation + Pravilo potvrđivanja brisanja + + + Destination directory + Odredišni direktorij + + + Invalid action + Neispravna radnja + + + The list is empty, there is nothing to export. + Popis je prazan. Nema se što izvesti. + + + Where would you like to save the list? + Gdje želite spremiti popis? + + + Rules list (*.rssrules) + Popis pravila (*.rssrules) + + + I/O Error + I/O greška + + + Failed to create the destination file + Nije uspjelo kreiranje odredišne datoteke + + + Please point to the RSS download rules file + Istaknite RSS datoteku pravila preuzimanja + + + Rules list (*.rssrules *.filters) + Popis pravila (*.rssrules *.filters) + + + Import Error + Greška prilikom uvoza + + + Failed to import the selected rules file + Nije uspio uvoz datoteke s odabranim pravilima + + + Add new rule... + Dodaj novo pravilo + + + Delete rule + Izbriši pravilo + + + Rename rule... + Preimenuj pravilo ... + + + Delete selected rules + Izbriši odabrana pravila + + + Rule renaming + Preimenovanje pravila + + + Please type the new rule name + Upišite ime novog pravila + + + Use regular expressions + Koristi uobičajene izraze + + + Regex mode: use Perl-like regular expressions + Regex mode: koristi Pearl-u slične uobičajene izraze + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Wildcard mode: možete koristiti<ul><li>? za podudaranje s bilo kojim pojedinim znakom</li><li>* za podudaranje s nula ili više drugih znakova</li><li>Prazna mjesta se računaju kao AND operatori</li></ul> + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Wildcard mode: možete koristiti<ul><li>? za podudaranje s bilo kojim pojedinim znakom</li><li>* za podudaranje s nula ili više drugih znakova</li><li>| se koristi kao OR operator</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 dostigao je najveći zadani omjer. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent je povezan s portom: TCP/%1 + + + UPnP support [ON] + Podrška za UPnP [UKLJUČENA] + + + UPnP support [OFF] + Podrška za UPnP [ISKLJUČENA] + + + NAT-PMP support [ON] + Podrška za NAT-PMP [UKLJUČENA] + + + NAT-PMP support [OFF] + Podrška za NAT-PMP [ISKLJUČENA] + + + HTTP user agent is %1 + Agent HTTP korisnika je %1 + + + Using a disk cache size of %1 MiB + Korištenje privremene memorije diska od %1 MiB + + + DHT support [ON], port: UDP/%1 + Podrška za DHT [UKLJUČENA], port: UDP/%1 + + + DHT support [OFF] + Podrška za DHT [ISKLJUČENA] + + + PeX support [ON] + Podrška za PeX [UKLJUČENA] + + + PeX support [OFF] + Podrška za PeX [ISKLJUČENA] + + + Restart is required to toggle PeX support + Potrebno je ponovno pokretanje za uključivanje/isključivanje podrške za PeX + + + Local Peer Discovery [ON] + Otkrivanje lokalnih peerova [UKLJUČENO] + + + Local Peer Discovery support [OFF] + Podrška za otkrivanje lokalnih peerova [ISKLJUČENA] + + + Encryption support [ON] + Podrška za kriptiranje [UKLJUČENA] + + + Encryption support [FORCED] + Podrška za kriptiranje [PRISILNA] + + + Encryption support [OFF] + Podrška za kriptiranje [ISKLJUČENA] + + + The Web UI is listening on port %1 + Web sučelje osluškuje na portu %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Greška web korisničkog sučelja - Nije moguće povezati web korisničko sučelje s portom %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' je uklonjena s popisa transfera i čvrstog diska. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' je uklonjena s popisa transfera. + + + '%1' is not a valid magnet URI. + '%1' nije valjani magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' je već na popisu preuzimanja. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' počinje iznova. (brzo) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' je dodan popisu preuzimanja. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Nije moguće dekodirati torrent datoteku: '%1' + + + This file is either corrupted or this isn't a torrent. + Ta datoteka je i dalje neispravna ili nije torrent. + + + Note: new trackers were added to the existing torrent. + Opaska: novi trackeri su dodani postojećem torrentu. + + + Note: new URL seeds were added to the existing torrent. + Opaska: novi URL seedovi dodani su postojećem torrentu. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>blokirano s obzirom na IP filter</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>zabranjeno zbog neispravnih dijelova</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekurzivno preuzimanje datoteke %1 ugrađeno u torrent %2 + + + Unable to decode %1 torrent file. + Nije moguće dekodirati %1 torrent datoteku. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Mapiranje porta nije uspjelo, poruka: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Mapiranje porta je uspjelo, poruka: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Brzi ponovni početak je odbijen za torrent %1, ponovna provjera ... + + + Reason: %1 + Razlog: %1 + + + Url seed lookup failed for url: %1, message: %2 + Traženje URL seeda nije uspjelo za URL: %1, poruka: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Preuzimanje '%1', pričekajte ... + + + An I/O error occured, '%1' paused. + Dogodila se I/O greška. '%1' pauziran. + + + Removing torrent %1... + Uklanjanje torrenta %1 ... + + + Pausing torrent %1... + Pauziranje torrenta %1 ... + + + Error: The torrent %1 does not contain any file. + Greška: Torrent %1 ne sadrži nikakve datoteke. + + + File sizes mismatch for torrent %1, pausing it. + Veličine datoteka se ne slažu za torrent %1, tako da će biti pauziran. + + + Torrent name: %1 + Ime torrenta: %1 + + + Torrent size: %1 + Veličina torrenta: %1 + + + Save path: %1 + Putanja spremanja: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent je preuzet u %1. + + + Thank you for using qBittorrent. + Hvala vam što ste koristili qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 je preuzet + + + + ConsoleDlg + + qBittorrent console + qBittorrent konzola + + + General + Općenito + + + Blocked IPs + Blokirani IP-ovi + + + qBittorrent log viewer + qBittorrentov preglednik dnevnika + + + + CookiesDlg + + Cookies management + Upravljanje kolačićima + + + Key + As in Key/Value pair + Ključ + + + Value + As in Key/Value pair + Vrijednost + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Javni ključevi za kolačiće su: '%1', '%2'. +Ovu informaciju trebate pribaviti iz postavki vašeg web preglednika. + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + Vaš dinamički DNS je uspješno ažuriran. + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Greška dinamičkog DNS-a: Servis je trenutno nedostupan. Novi pokušaj za 30 minuta. + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Greška dinamičkog DNS-a: Dano ime računala ne postoji pod navedenim računom. + + + Dynamic DNS error: Invalid username/password. + Greška dinamičkog DNS-a: Neispravno korisničko ime ili lozinka. + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Greška dinamičkog DNS-a: Servis je qBittorrent stavio na crnu listu. Prijavite grešku na http://bugs.qbittorrent.org. + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Greška dinamičkog DNS-a: Servis je vratio %1. Prijavite grešku na http://bugs.qbittorrent.org. + + + Dynamic DNS error: Your username was blocked due to abuse. + Greška dinamičkog DNS-a: Vaše korisničko ime je blokirano zbog zloupotrebe. + + + Dynamic DNS error: supplied domain name is invalid. + Greška dinamičkog DNS-a: Dano ime domene nije ispravno. + + + Dynamic DNS error: supplied username is too short. + Greška dinamičkog DNS-a: Dano korisničko ime je prekratko. + + + Dynamic DNS error: supplied password is too short. + Greška dinamičkog DNS-a: Dana lozinka je prekratka. + + + + DownloadThread + + I/O Error + I/O greška + + + The remote host name was not found (invalid hostname) + Ime udaljenog računala nije nađeno (neispravno ime računala) + + + The operation was canceled + Operacija je otkazana + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Udaljeni poslužitelj je prerano prekinuo spajanje, prije nego je primljen i obrađen cijeli odgovor + + + The connection to the remote server timed out + Spajanje s udaljenim poslužiteljem je isteklo + + + SSL/TLS handshake failed + SSL/TLS usklađivanje nije uspjelo + + + The remote server refused the connection + Udaljeni poslužitelj odbija spajanje + + + The connection to the proxy server was refused + Spajanje s proxy poslužiteljem je odbijeno + + + The proxy server closed the connection prematurely + Proxy server je prerano prekinuo spajanje + + + The proxy host name was not found + Ime proxy računala nije nađeno + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Spajanje prema proxyju je isteklo ili proxy nije na vrijeme odgovorio na poslani zahtjev + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Proxy zahtjeva autentifikaciju kako bi prihvatio zahtjev, ali nije prihvatio ponuđene vjerodajnice + + + The access to the remote content was denied (401) + Pristup udaljenom sadržaju je odbijen (401) + + + The operation requested on the remote content is not permitted + Tražena operacija nad udaljenim sadržajem nije dopuštena + + + The remote content was not found at the server (404) + Udaljeni sadržaj nije nađen na poslužitelju (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Udaljeni poslužitelj zahtjeva autentifikaciju kako bi dostavio sadržaj, ali pružene vjerodajnice nisu prihvaćene + + + The Network Access API cannot honor the request because the protocol is not known + Network Access API ne može prihvatiti zahtjev jer protokol nije poznat + + + The requested operation is invalid for this protocol + Tražena operacija je neispravna za ovaj protokol + + + An unknown network-related error was detected + Otkrivena je nepoznata greška vezana za mrežu + + + An unknown proxy-related error was detected + Otkrivena je nepoznata greška vezana za proxy + + + An unknown error related to the remote content was detected + Otkrivena je nepoznata greška vezana za udaljeni sadržaj + + + A breakdown in protocol was detected + Otkriven je kvar u protokolu + + + Unknown error + Nepoznata greška + + + + EventManager + + Working + Radi + + + Updating... + Ažuriranje ... + + + Not working + Ne radi + + + Not contacted yet + Nije još kontaktirano + + + this session + ova sesija + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seedano za %1 + + + %1 max + e.g. 10 max + %1 najviše + + + %1/s + e.g. 120 KiB/s + %1/s + + + + ExecutionLog + + Form + Oblik + + + General + Općenito + + + Blocked IPs + Blokirani IP-ovi + + + + FeedDownloader + + RSS Feed downloader + Preuzimatelj RSS kanala + + + RSS feed: + RSS kanal: + + + Feed name + Ime kanala + + + Automatically download torrents from this feed + Automatski preuzmi torrente s tog kanala + + + Download filters + Filteri preuzimanja + + + Filters: + Filteri: + + + Filter settings + Postavke filtera + + + Matches: + Podudarnosti: + + + Does not match: + Ne podudaraju se: + + + Destination folder: + Odredišna mapa: + + + ... + ... + + + Filter testing + Provjeravanje filtera + + + Torrent title: + Naslov torrenta: + + + Result: + Rezultat: + + + Test + Provjeri + + + Import... + Uvezi ... + + + Export... + Izvezi ... + + + Rename filter + Preimenuj filter + + + Remove filter + Ukloni filter + + + Add filter + Dodaj filter + + + + FeedDownloaderDlg + + New filter + Novi filter + + + Please choose a name for this filter + Izaberite ime za taj filter + + + Filter name: + Ime filtera: + + + Invalid filter name + Neispravno ime filtera + + + The filter name cannot be left empty. + Ime filtera mora biti zadano. + + + This filter name is already in use. + To se ime filtera već koristi. + + + Choose save path + Izaberite putanju spremanja + + + Filter testing error + Greška prilikom provjere filtera + + + Please specify a test torrent name. + Odredite ime testnog torrenta. + + + matches + podudarnosti + + + does not match + ne podudaraju se + + + Select file to import + Odaberite datoteku za uvoz + + + Filters Files + Datoteke filtera + + + Import successful + Uvoz je uspio + + + Filters import was successful. + Uvoz filtera je uspio. + + + Import failure + Uvoz nije uspio + + + Filters could not be imported due to an I/O error. + Filteri ne mogu biti uvezeni zbog I/O greške. + + + Select destination file + Odaberite odredišnu datoteku + + + Export successful + Izvoz je uspio + + + Filters export was successful. + Izvoz filtera je uspio. + + + Export failure + Izvoz nije uspio + + + Filters could not be exported due to an I/O error. + Filteri ne mogu biti izvezeni zbog I/O greške. + + + + FeedList + + Unread + Nepročitano + + + + FeedListWidget + + RSS feeds + RSS kanali + + + Unread + Nepročitano + + + + GUI + + Open Torrent Files + Otvori torrent datoteke + + + &Yes + &Da + + + &No + &Ne + + + Torrent Files + Torrent datoteke + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + qBittorrent + qBittorrent + + + qBittorrent %1 + e.g: qBittorrent vx.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Brzina preuzimanja: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Brzina slanja: %1 KiB/s + + + Are you sure you want to quit? + Jeste li sigurni da želite završiti? + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Datoteka %1 je preuzeta. + + + I/O Error + i.e: Input/Output Error + I/O greška + + + An error occured (full disk?), '%1' paused. + e.g: An error occured (full disk?), 'xxx.avi' paused. + Dogodila se greška (pun disk?), '%1' zaustavljeno. + + + Search + Traži + + + RSS + RSS + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Greška prilikom preuzimanja + + + Couldn't download file at url: %1, reason: %2. + Nije moguće preuzeti datoteku sa: %1, razlog: %2. + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Dogodila se I/O greška za torrent %1 +Razlog: %2 + + + Transfers + Transferi + + + Download completion + Preuzimanje završeno + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Globalni limit brzine slanja + + + Global Download Speed Limit + Globalni limit brzine preuzimanja + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Neke datoteke još se prenose. +Jeste li sigurni da želite zatvoriti qBittorrent? + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Preuzimanje: %2/s, Slanje: %3/s) + + + Use normal speed limits + Koristi uobičajene limite brzine + + + Use alternative speed limits + Koristi alternativnen limite brzine + + + Options were saved successfully. + Opcije su uspješno spremljene. + + + Recursive download confirmation + Potvrda rekurzivnog preuzimanja + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent %1 sadrži torrent datoteke. Želite li nastaviti s preuzimanjem? + + + Torrent file association + Pridruživanje torrent datoteka + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent nije zadana aplikacija za otvaranje torrent datoteka ili Magnet linkova. +Želite li pridružiti qBittorrent torrent datotekama i Magnet linkovima? + + + Transfers (%1) + Transferi (%1) + + + Yes + Da + + + No + Ne + + + Never + Nikad + + + Always + Uvijek + + + Exiting qBittorrent + Izlaz iz qBittorrenta + + + Set the password... + Postavi lozinku ... + + + Password update + Ažuriranje lozinke + + + The UI lock password has been successfully updated + Lozinka zaključavanja sučelja je uspješno ažurirana + + + UI lock password + Lozinka zaključavanja sučelja + + + Please type the UI lock password: + Upišite lozinku zaključavanja sučelja: + + + Invalid password + Neispravna lozinka + + + The password is invalid + Lozinka nije ispravna + + + A newer version is available + Dostupna je novija verzija + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Na Sourceforge dostupna je novija verzija qBittorrenta. +Želite li ažurirati qBittorrent na verziju %1? + + + Impossible to update qBittorrent + Nije moguće ažurirati qBittorrent + + + qBittorrent failed to update, reason: %1 + Ažuriranje qBittorrenta nije uspjelo. Razlog: %1 + + + + GeoIP + + Australia + Australija + + + Argentina + Argentina + + + Austria + Austrija + + + United Arab Emirates + Ujedinjeni Arapski Emirati + + + Brazil + Brazil + + + Bulgaria + Bugarska + + + Belarus + Bjelorusija + + + Belgium + Belgija + + + Bosnia + Bosna i Hercegovina + + + Canada + Kanada + + + Czech Republic + Češka + + + China + Kina + + + Costa Rica + Kostarika + + + Switzerland + Švicarska + + + Germany + Njemačka + + + Denmark + Danska + + + + Algeria + Alžir + + + Spain + Španjolska + + + Egypt + Egipat + + + Finland + Finska + + + France + Francuska + + + United Kingdom + Ujedinjeno Kraljevstvo + + + Greece + Grčka + + + Georgia + Gruzija + + + Hungary + Mađarska + + + Croatia + Hrvatska + + + Italy + Italija + + + India + Indija + + + Israel + Izrael + + + Ireland + Irska + + + Iceland + Island + + + Indonesia + Indonezija + + + Japan + Japan + + + South Korea + Južna Koreja + + + Luxembourg + Luksemburg + + + Malaysia + Malezija + + + Mexico + Meksiko + + + Serbia + Srbija + + + Morocco + Maroko + + + Netherlands + Nizozemska + + + Norway + Norveška + + + New Zealand + Novi Zeland + + + Portugal + Portugal + + + Poland + Poljska + + + Pakistan + Pakistan + + + Philippines + Filipini + + + Russia + Rusija + + + Romania + Rumunjska + + + France (Reunion Island) + Francuska (otok Reunion) + + + Sweden + Švedska + + + Slovakia + Slovačka + + + Singapore + Singapur + + + Slovenia + Slovenija + + + Taiwan + Tajvan + + + Turkey + Turska + + + Thailand + Tajland + + + USA + SAD + + + Ukraine + Ukrajina + + + South Africa + Južna Afrika + + + Saudi Arabia + Saudijska Arabija + + + + HeadlessLoader + + Information + Informacija + + + To control qBittorrent, access the Web UI at http://localhost:%1 + kako bi kontrolirali qBittorrent, pristupite web sučelju na http://localhost:%1 + + + The Web UI administrator user name is: %1 + Administratorsko korisničko ime na web sučelju je: %1 + + + The Web UI administrator password is still the default one: %1 + Adminstratorska lozinka web sučelja ostaje zadana: %1 + + + This is a security risk, please consider changing your password from program preferences. + To je sigurnosni rizik. Uzmite u obzir promjenu lozinke u postavkama programa. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + Vaša IP adresa je zabranjena nakon previše neuspjelih pokušaja ovjere. + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Preuzimanje: %1/s - Preuzeto: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Slanje: %1/s - Poslano: %2 + + + + HttpServer + + File + Datoteka + + + Edit + Uredi + + + Help + Pomoć + + + Delete from HD + Izbriši sa čvrstog diska + + + Download Torrents from their URL or Magnet link + Preuzmi torrente s njihovih URL-ova ili Magnet linka + + + Only one link per line + Samo jedan link po liniji + + + Download local torrent + Preuzmi lokalni torent + + + Torrent files were correctly added to download list. + Torrent datoteke su ispravno dodane popisu preuzimanja. + + + Point to torrent file + Istakni torrent datoteku + + + Download + Preuzmi + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Jeste li sigurni da želite izbrisati odabrane torrente s popisa transfera i čvrstog diska? + + + Download rate limit must be greater than 0 or disabled. + Limit brzine preuzimanja mora biti veći od 0 ili onemogućen. + + + Upload rate limit must be greater than 0 or disabled. + Limit brzine slanja mora biti veći od 0 ili onemogućen. + + + Maximum number of connections limit must be greater than 0 or disabled. + Limit najvećeg broja spajanja mora biti veći od 0 ili onemogućen. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Limit najvećeg broja spajanja po torrentu mora biti veći od 0 ili onemogućen. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Limit najvećeg broja priključnica po torrentu mora biti veći od 0 ili onemogućen. + + + Unable to save program preferences, qBittorrent is probably unreachable. + Nije moguće spremiti postavke programa. qBittorrent je vjerojatno nedostupan. + + + Language + Jezik + + + Downloaded + Is the file downloaded or not? + Preuzeto + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Port korišten za dolazne veze mora biti veći od 1024 i manji od 65535. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Port korišten za web sučelje mora biti veći od 1024 i manji od 65535. + + + The Web UI username must be at least 3 characters long. + Korisničko ime web sučelja mora imati najmanje 3 znaka. + + + The Web UI password must be at least 3 characters long. + Lozinka web sučelja mora imati najmanje 3 znaka. + + + Save + Spremi + + + qBittorrent client is not reachable + qBittorrent klijent nije dostupan + + + HTTP Server + HTTP poslužitelj + + + Torrent path + Putanja torrenta + + + Torrent name + Ime torrenta + + + The following parameters are supported: + Podržani su sljedeći parametri: + + + + LegalNotice + + Legal Notice + Pravna napomena + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent je program za dijeljenje datoteka. Kada pokrenete torrent, njegovi podaci bit će rapoloživi drugima. To znači da će drugi moći preuzimati datoteke i s vašeg računala. Za bilo koji sadržaj koji dijelite isključivo ste vi odgovorni. + +Neće biti daljnjih napomena. + + + Press %1 key to accept and continue... + Pritisnite %1 tipku za prihvaćanje i nastavak ... + + + Legal notice + Napomena + + + Cancel + Odustani + + + I Agree + Slažem se + + + + LineEdit + + Clear the text + Izbriši tekst + + + + MainWindow + + &Edit + Ur&edi + + + &File + &Datoteka + + + &Help + &Pomoć + + + Exit + Izlaz + + + Preferences + Postavke + + + About + O + + + Start + Kreni + + + Pause + Stani + + + Delete + Izbriši + + + Pause All + Zaustavi sve + + + Start All + Počni sve + + + Visit Website + Posjeti web mjesto + + + Download from URL + Preuzmi s URL-a + + + Create torrent + Kreiraj torrent + + + Preview file + Pregledaj datoteku + + + Clear log + Izbriši zapis + + + Log Window + Prozor zapisa + + + Use alternative speed limits + Koristi alternativne limite brzine + + + Report a bug + Prijavi grešku + + + Set upload limit + Podesi limit slanja + + + Set download limit + Podesi limit preuzimanja + + + Documentation + Dokumentacija + + + Set global download limit + Podesi globalni limit preuzimanja + + + Set global upload limit + Podesi globalni limit slanja + + + Options + Mogućnosti + + + Open torrent + Otvori torrent + + + Decrease priority + Smanji prioritet + + + Increase priority + Povećaj prioritet + + + Console + Konzola + + + &Tools + Ala&ti + + + &View + Po&gled + + + &Add File... + Dod&aj datoteku ... + + + E&xit + I&zlaz + + + &Options... + &Opcije ... + + + Add &URL... + Dodaj &URL ... + + + Torrent &creator + &Kreator torrenta + + + Set upload limit... + Podesi limit slanja ... + + + Set download limit... + Podesi limit preuzimanja ... + + + Set global download limit... + Podesi globalni limit preuzimanja ... + + + Set global upload limit... + Podesi globalni limit slanja ... + + + &Log viewer... + Preg&lednik zapisa + + + Top &tool bar + Gornja ala&tna traka + + + Display top tool bar + Prikaži gornju alatnu traku + + + &Speed in title bar + Brzina u na&slovnoj traci + + + Show transfer speed in title bar + Pokaži brzinu transfera u naslovnoj traci + + + Alternative speed limits + Alternativni limiti brzine + + + Search engine + Tražilica + + + &About + &O + + + &Start + Za&počni + + + &Pause + &Pauziraj + + + &Delete + Iz&briši + + + P&ause All + P&auziraj sve + + + S&tart All + Započni &sve + + + Visit &Website + Posjeti &web stranicu + + + Report a &bug + Prijavi g&rešku + + + &Documentation + &Dokumentacija + + + &RSS reader + &RSS čitač + + + Search &engine + &Tražilica + + + Log viewer + Preglednik zapisa + + + Lock qBittorrent + Zaključaj qBittorrent + + + Ctrl+L + Ctrl+L + + + Shutdown computer when downloads complete + Isključi računalo kada preuzimanja završe + + + &Resume + Nastavi + + + R&esume All + Nastavi sve + + + Shutdown qBittorrent when downloads complete + Ugasi qBittorrent kada je preuzimanje gotovo + + + Import torrent... + Uvezi torrent + + + Donate money + Donirajte novac + + + If you like qBittorrent, please donate! + Ako vam se sviđa qBittorrent donirajte! + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + Postavi lozinku ... + + + Transfers + Transferi + + + Torrent file association + Pridruživanje torrent datoteka + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent nije zadana aplikacija za otvaranje torrent datoteka ili Magnet linkova. +Želite li pridružiti qBittorrent torrent datotekama i Magnet linkovima? + + + UI lock password + Lozinka zaključavanja sučelja + + + Please type the UI lock password: + Upišite lozinku zaključavanja sučelja: + + + Password update + Ažuriranje lozinke + + + The UI lock password has been successfully updated + Lozinka zaključavanja sučelja je uspješno ažurirana + + + RSS + RSS + + + Search + Traži + + + Transfers (%1) + Transferi (%1) + + + Download completion + Preuzimanje završeno + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Datoteka %1 je preuzeta. + + + I/O Error + i.e: Input/Output Error + I/O greška + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Dogodila se I/O greška za torrent %1 +Razlog: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Potvrda rekurzivnog preuzimanja + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent %1 sadrži torrent datoteke. Želite li nastaviti s preuzimanjem? + + + Yes + Da + + + No + Ne + + + Never + Nikad + + + Url download error + Greška prilikom preuzimanja + + + Couldn't download file at url: %1, reason: %2. + Nije moguće preuzeti datoteku sa: %1, razlog: %2. + + + Global Upload Speed Limit + Globalni limit brzine slanja + + + Global Download Speed Limit + Globalni limit brzine preuzimanja + + + Invalid password + Neispravna lozinka + + + The password is invalid + Lozinka nije ispravna + + + Exiting qBittorrent + Izlaz iz qBittorrenta + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Neke datoteke još se prenose. +Jeste li sigurni da želite zatvoriti qBittorrent? + + + Always + Uvijek + + + Open Torrent Files + Otvori torrent datoteke + + + Torrent Files + Torrent datoteke + + + Options were saved successfully. + Opcije su uspješno spremljene. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Brzina preuzimanja: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Brzina slanja: %1 KiB/s + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Preuzimanje: %2/s, Slanje: %3/s) + + + A newer version is available + Dostupna je novija verzija + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Na Sourceforge-u dostupna je novija verzija qBittorrenta. +Želite li ažurirati qBittorrent na verziju %1? + + + Impossible to update qBittorrent + Nije moguće ažurirati qBittorrent + + + qBittorrent failed to update, reason: %1 + Ažuriranje qBittorrenta nije uspjelo. Razlog: %1 + + + &Add torrent file... + Dod&aj torrent datoteku ... + + + Add &link to torrent... + Dodaj &link torrentu ... + + + Import existing torrent... + Uvezi postojeći torrent ... + + + Execution &Log + Dnevnik izvršavanja + + + Execution Log + Dnevnik izvršavanja + + + Auto-Shutdown on downloads completion + Akcije nakon što preuzimanja završe + + + Exit qBittorrent + Izlaz iz qBittorrenta + + + Suspend system + Suspendiranje računala + + + Shutdown system + Isključivanje računala + + + Disabled + Onemogućeno + + + The password should contain at least 3 characters + Lozinka mora imati najmanje 3 znaka + + + + PeerAdditionDlg + + Invalid IP + Neispravan IP + + + The IP you provided is invalid. + IP koji ste pribavili nije ispravan. + + + + PeerListDelegate + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + Klijent + + + Progress + i.e: % downloaded + Napredak + + + Down Speed + i.e: Download speed + Brzina preuzimanja + + + Up Speed + i.e: Upload speed + Brzina slanja + + + Downloaded + i.e: total data downloaded + Preuzeto + + + Uploaded + i.e: total data uploaded + Poslano + + + Add a new peer + Dodaj novi peer + + + Limit upload rate + Limitiraj brzinu slanja + + + Limit download rate + Limitiraj brzinu slanja + + + Ban peer permanently + Trajno isključi peer + + + Peer addition + Dodavanje peerova + + + The peer was added to this torrent. + Peer je dodan ovom torrentu. + + + The peer could not be added to this torrent. + Peer ne može biti dodan ovom torrentu. + + + Are you sure? -- qBittorrent + Jeste li sigurni? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + Jeste li sigurni da želite trajno isključiti odabrane peerove? + + + &Yes + &Da + + + &No + &Ne + + + Manually banning peer %1... + Ručno isključivanje peera %1 ... + + + Upload rate limiting + Limitiranje brzine slanja + + + Download rate limiting + Limitiranje brzine preuzimanja + + + Add a new peer... + Dodaj novi peer ... + + + Limit download rate... + Limitiraj brzinu preuzimanja ... + + + Limit upload rate... + Limitiraj brzinu slanja ... + + + Copy IP + Kopiraj IP + + + Connection + Spajanje + + + + Preferences + + Preferences + Postavke + + + UI + User Interface + Korisničko sučelje + + + Downloads + Preuzimanja + + + Connection + Spajanja + + + Speed + Brzina + + + Bittorrent + Bittorrent + + + Proxy + Proxy + + + IP Filter + IP Filter + + + Web UI + Web sučelje + + + RSS + RSS + + + Advanced + Napredno + + + User interface + Korisničko sučelje + + + Language: + Jezik: + + + (Requires restart) + (Zahtjeva ponovno pokretanje) + + + Visual style: + Stil: + + + Ask for confirmation on exit when download list is not empty + Traži potvrdu na izlasku kada popis preuzimanja nije prazan + + + Display top toolbar + Prikaži alatnu traku na vrhu + + + Disable splash screen + Onemogući najavni prozor + + + Display current speed in title bar + Prikaži trenutnu brzinu u naslovnoj traci + + + Transfer list + Popis transfera + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Koristi obojene naizmjenične redove + + + Action on double click: + Action executed when doucle-clicking on an item in transfer (download/upload) list + Radnja na dvostruki klik: + + + Downloading: + Preuzimanje: + + + Start/Stop + Kreni/Stani + + + Open folder + Otvori mapu + + + Completed: + Završeno: + + + System tray icon + Ikona na sistemskoj traci + + + Disable system tray icon + Onemogući ikonu na sistemskoj traci + + + Close to tray + i.e: The systray tray icon will still be visible when closing the main window. + Ikona će biti vidljiva na sistemskoj traci kada se zatvori glavni prozor + + + Minimize to tray + Ikona će biti vidljiva na sistemskoj traci kada se spusti glavni prozor + + + Start minimized + Počni spušteno + + + Show notification balloons in tray + Pokazuj obavijestne balončiće na sistemskoj traci + + + File system + Datotečni sustav + + + QGroupBox::title { +font-weight: normal; +margin-left: -3px; +} +QGroupBox { + border-width: 0; +} + QGroupBox::title { +font-weight: normal; +margin-left: -3px; +} +QGroupBox { +(sp)(sp)border-width: 0; +} + + + Destination Folder: + Odredišna mapa: + + + Append the torrent's label + Pridodaj torrentovu oznaku + + + Use a different folder for incomplete downloads: + Koristi drugu mapu za nezavršena preuzimanja: + + + QLineEdit { + margin-left: 23px; +} + QLineEdit { + margin-left: 23px; +} + + + Automatically load .torrent files from: + Automatski učitaj .torrent datoteke iz: + + + Copy .torrent files to: + Kopiraj .torrent datoteke u: + + + Append .!qB extension to incomplete files + Pridodaj .!qB proširenje nedovršenim datotekama + + + Pre-allocate all files + Pre-dodijeli svim datotekama + + + Torrent queueing + Red čekanja torrenta + + + Enable queueing system + Omogući sustav reda čekanja + + + Maximum active downloads: + Najviše aktivnih preuzimanja: + + + Maximum active uploads: + Najviše aktivnih slanja: + + + Maximum active torrents: + Najviše aktivnih torrenta: + + + When adding a torrent + Kada dodajete torrent + + + Display torrent content and some options + Prikaži sadržaj torrenta i neke opcije + + + Do not start download automatically + The torrent will be added to download list in pause state + Ne počinji preuzimanje automatski + + + Listening port + Osluškivanje porta + + + Port used for incoming connections: + Port korišten za dolazna spajanja: + + + Random + Nasumično + + + Enable UPnP port mapping + Omogući UPnP mapiranje porta + + + Enable NAT-PMP port mapping + Omogući NAT-PMP mapiranje porta + + + Connections limit + Limit spajanja + + + Global maximum number of connections: + Globalni najveći broj spajanja: + + + Maximum number of connections per torrent: + Najveći broj spajanja po torrentu: + + + Maximum number of upload slots per torrent: + Najveći broj priključnica slanja po torrentu: + + + Upload: + Slanje: + + + Download: + Preuzimanje: + + + KiB/s + KiB/s + + + Global speed limits + Globalni limiti brzine + + + Alternative global speed limits + Alternativni globalni limiti brzine + + + Scheduled times: + Planirano razdoblje: + + + to + time1 to time2 + do + + + On days: + Koje dane: + + + Every day + Svaki dan + + + Week days + Radni dani + + + Week ends + Dani vikenda + + + Bittorrent features + Bittorrent značajke + + + Enable DHT network (decentralized) + Omogući DHT mrežu (decentralizirano) + + + Use a different port for DHT and Bittorrent + Koristi drugi port za DHT i Bittorrent + + + DHT port: + DHT port: + + + Enable Peer Exchange / PeX (requires restart) + Omogući razmjenu peerova/PeX (zahtjeva ponovno pokretanje) + + + Enable Local Peer Discovery + Omogući lokalno otkrivanje peerova + + + Encryption: + Šifriranje: + + + Enabled + Omogućeno + + + Forced + Prisilno + + + Disabled + Onemogućeno + + + KTorrent + KTorrent + + + Reset to latest software version + Vrati na posljednju verziju softvera + + + Share ratio settings + Postavke omjera djeljenja + + + Desired ratio: + Željeni omjer: + + + Remove finished torrents when their ratio reaches: + Ukloni završene torrente kada njihov omjer dosegne: + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP komunikacije (trackeri, web seedovi, tražilice) + + + Host: + Host: + + + Peer Communications + Peer komunikacije + + + SOCKS4 + SOCKS4 + + + Type: + Vrsta: + + + Client whitelisting workaround + Klijent dopušta zaobilaženje + + + Identify as: + Identificiraj kao: + + + qBittorrent + qBittorrent + + + Vuze + Vuze + + + µTorrent + µTorrent + + + Version: + Verzija: + + + Build: + Software Build nulmber: + Izgrađena: + + + (None) + (Nijedno) + + + HTTP + HTTP + + + Port: + Port: + + + Authentication + Ovjera + + + Username: + Korisničko ime: + + + Password: + Lozinka: + + + SOCKS5 + SOCKS5 + + + Filter Settings + Postavke filtera + + + Activate IP Filtering + Aktiviraj IP filtriranje + + + Filter path (.dat, .p2p, .p2b): + Putanja filtera (.dat, .p2p, .p2b): + + + Enable Web User Interface + Omogući web sučelje + + + HTTP Server + HTTP poslužitelj + + + Enable RSS support + Omogući podršku za RSS + + + RSS settings + RSS postavke + + + RSS feeds refresh interval: + Interval osvježavanja RSS kanala: + + + minutes + minute + + + Maximum number of articles per feed: + Najveći broj članaka po kanalu: + + + Check Folders for .torrent Files: + Provjeri mape za .torrent datoteke: + + + Add folder ... + Dodaj mapu ... + + + Remove folder + Ukloni mapu + + + No action + Nema radnji + + + Options + Opcije + + + Visual Appearance + Izgled + + + Action on double-click + Radnja na dvostruki klik + + + Downloading torrents: + Preuzimanje torrenta: + + + Start / Stop + Započni/Zaustavi + + + Open destination folder + Otvori odredišnu mapu + + + Completed torrents: + Završeni torrenti: + + + Desktop + Radna površina + + + Show splash screen on start up + Prikaži najavni ekran kod pokretanja + + + Start qBittorrent minimized + Pokreni qBittorrent minimiziranog + + + Show qBittorrent icon in notification area + Prikaži ikonu qBittorrenta u prostoru obavijesti + + + Minimize qBittorrent to notification area + Minimiziraj qBittorrent u prostor obavijesti + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Zatvori qBittorrent u prostor obavijesti + + + Do not start the download automatically + The torrent will be added to download list in pause state + Ne započinji preuzimanje automatski + + + Save files to location: + Spremi datoteke ovdje: + + + Append the label of the torrent to the save path + Pridodaj oznaku torrenta u putanju spremanja + + + Pre-allocate disk space for all files + Pridodijeli prostor na disku svim datotekama + + + Keep incomplete torrents in: + Drži nedovršene torrente u: + + + Append .!qB extension to incomplete files' names + Pridodaj .!qB proširenje imenima nedovršenih datoteka + + + Automatically add torrents from: + Automatski dodaj torrente iz: + + + Add folder... + Dodaj mapu ... + + + IP Filtering + IP filtriranje + + + Schedule the use of alternative speed limits + Planiraj korištenje alternativnih limita brzine + + + from + from (time1 to time2) + iz + + + When: + Kada: + + + Look for peers on your local network + Potraži peerove u vašoj lokalnoj mreži + + + Protocol encryption: + Protokol kriptiranja: + + + Enable Web User Interface (Remote control) + Omogući web korisničko sučelje (Udaljeno upravljanje) + + + Share ratio limiting + Limitiranje omjera djeljenja + + + Seed torrents until their ratio reaches + Seedaj torrente dok njihov omjer ne dosegne + + + then + tada + + + Pause them + Pauziraji ih + + + Remove them + Ukloni ih + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Razmjeni peerove s kompatibilnim Bittorrent klijentima (µTorrent, Vuze, ...) + + + Email notification upon download completion + Obavijesti e-poštom prilikom završetka preuzimanja + + + Destination email: + Odredišna adresa e-pošte: + + + SMTP server: + SMPT poslužitelj: + + + Run an external program on torrent completion + Pokreni eksterni program kod završavanja torrenta + + + Use %f to pass the torrent path in parameters + Koristi %f kako bi se prošlo putanjom torrenta u parametrima + + + Proxy server + Proxy poslužitelj + + + BitTorrent + Bittorrent + + + Start / Stop Torrent + Započni / Zaustavi torrent + + + Use UPnP / NAT-PMP port forwarding from my router + Koristi UPnP / NAT-PMP port prosljeđivanje s mojeg routera + + + Privacy + Privatnost + + + Enable DHT (decentralized network) to find more peers + Omogući DHT (decentralizirana mreža) kako bi se našlo još peerova + + + Use a different port for DHT and BitTorrent + Koristi drugi port za DHT i Bittorrent + + + Enable Peer Exchange (PeX) to find more peers + Omogući razmjenu peerova (PeX) kako bi se našlo još peerova + + + Enable Local Peer Discovery to find more peers + Omogući lokalno otkrivanje peerova + + + Encryption mode: + Način kriptiranja: + + + Prefer encryption + Preferiraj kriptiranje + + + Require encryption + Zahtjevaj kriptiranje + + + Disable encryption + Onemogući kriptiranje + + + User Interface + Korisničko sučelje + + + Reload the filter + Ponovno učitaj filter + + + Behavior + Ponašanje + + + Language + Jezik + + + Power Management + Upravljanje energijom + + + Inhibit system sleep when torrents are active + Spriječi stanje mirovanja kada su torrenti aktivni + + + Bypass authentication for localhost + Zaobiđi autentifikaciju za localhosta + + + Ask for program exit confirmation + Traži potvrdu za zatvaranje programa + + + Use monochrome system tray icon (requires restart) + Koristi jednobojnu ikonu u prostor obavijesti (potrebno ponovno pokretanje) + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Podržani su sljedeći parametri: +<ul> +<li>%f: Putanja torrenta</li> +<li>%n: Ime torrenta</li> +</ul> + + + Tray icon style: + Stil ikone na sistemskoj traci: + + + Normal + Uobičajeno + + + Monochrome (Dark theme) + Monochrome (Tamna tema) + + + Monochrome (Light theme) + Monochrome (Svijetla tema) + + + This server requires a secure connection (SSL) + Ovaj poslužitelj zahtijeva sigurnu vezu (SSL) + + + User Interface Language: + Jezik korisničkog sučelja: + + + Transfer List + Popis transfera + + + Show qBittorrent in notification area + Prikaži ikonu qBittorrenta u prostoru obavijesti + + + Hard Disk + Tvrdi disk + + + Listening Port + Osluškivanje porta + + + Connections Limits + Limiti spajanja + + + Proxy Server + Proxy poslužitelj + + + Torrent Queueing + Red čekanja torrenta + + + Share Ratio Limiting + Limitiranje omjera djeljenja + + + Use UPnP / NAT-PMP to forward the port from my router + Koristi UPnP / NAT-PMP za prosljeđivanje porta s mojeg routera + + + Update my dynamic domain name + Ažuriraj moje dinamičko ime domene + + + Service: + Servis: + + + Register + Registar + + + Domain name: + Ime domene: + + + Global Rate Limits + Globalni limiti brzine + + + Apply rate limit to uTP connections + Primijeni limit brzine za uTP spajanja + + + Apply rate limit to transport overhead + Primijeni limit brzine za dodatni promet + + + Alternative Global Rate Limits + Alternativni globalni limiti brzine + + + Schedule the use of alternative rate limits + Planiraj korištenje alternativnih limita brzine + + + Enable bandwidth management (uTP) + Omogući upravljanje propusnošću (uTP) + + + Otherwise, the proxy server is only used for tracker connections + U drugom slučaju, proxy poslužitelj bit će korišten za spajanja trackera + + + Use proxy for peer connections + Koristi proxy za spajanja peerova + + + Use HTTPS instead of HTTP + Koristi HTTPS umjesto HTTP-a + + + Import SSL Certificate + Uvezi SSL certifikat + + + Import SSL Key + Uvezi SSl ključ + + + Certificate: + Certifikat: + + + Key: + Ključ: + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + PreviewSelect + + Name + Ime + + + Size + Veličina + + + Progress + Napredak + + + Preview impossible + Pregled nije moguć + + + Sorry, we can't preview this file + Oprostite, nije moguće pregledati datoteku + + + + ProgramUpdater + + Could not create the file %1 + Nije moguće kreiratidatoteku %1 + + + Failed to download the update at %1 + %1 is an URL + Neuspješno preuzimanje ažuriranja s %1 + + + + PropListDelegate + + Not downloaded + Nije preuzeto + + + Normal + Normal (priority) + Uobičajen + + + High + High (priority) + Visok + + + Maximum + Maximum (priority) + Najviši + + + Mixed + Mixed (priorities + Miješani + + + + PropTabBar + + General + Općenito + + + Trackers + Trackeri + + + Peers + Peerovi + + + URL Seeds + URL seedovi + + + Files + Datoteke + + + HTTP Sources + HTTP izvori + + + Content + Sadržaj + + + + PropertiesWidget + + Save path: + Putanja za spremanje: + + + Torrent hash: + Torrent smjesa: + + + Share ratio: + Omjer dijeljenja: + + + Downloaded: + Preuzeto: + + + Availability: + Dostupnost: + + + Transfer + Transfer + + + Uploaded: + Poslano: + + + Wasted: + Izgubljeno: + + + UP limit: + Limit slanja: + + + DL limit: + Limit preuzimanja: + + + Time elapsed: + Isteklo vremena: + + + Connections: + Spajanja: + + + Information + Informacija + + + Created on: + Kreirano: + + + Comment: + Komentar: + + + Collapse all + Sklopi sve + + + Expand all + Proširi sve + + + General + Općenito + + + Trackers + Trackeri + + + Peers + Peerovi + + + URL seeds + URL seedovi + + + Files + Datoteke + + + Normal + Uobičajen + + + High + Visok + + + Maximum + Najviši + + + this session + ova sesija + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seedano za %1 + + + %1 max + e.g. 10 max + %1 najviše + + + I/O Error + I/O greška + + + This file does not exist yet. + Ta datoteka još ne postoji. + + + This folder does not exist yet. + Ta mapa još ne postoji. + + + Rename... + Preimenuj ... + + + Priority + Prioritet + + + Rename the file + Preimenuj ovu datoteku + + + New name: + Novo ime: + + + The file could not be renamed + Datoteka se ne može preimenovati + + + This file name contains forbidden characters, please choose a different one. + Ovo ime datoteke sadrži zabranjene znakove. Izaberite druge. + + + This name is already in use in this folder. Please use a different name. + Ovo ime već se koristi u toj mapi. Koristite drugo. + + + The folder could not be renamed + Mapa se ne može preimenovati + + + New url seed + New HTTP source + Novi URL seed + + + New url seed: + Novi URL seed: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + Taj URL seed je već na listi. + + + Choose save path + Izaberite putanju za spremanje + + + Save path creation error + Greška prilikom kreiranja putanje za spremanje + + + Could not create the save path + Nije moguće kreirati putanju za spremanje + + + Reannounce in: + Ponovno objavi u: + + + Force reannounce + Prisili ponovno objavljivanje + + + Not downloaded + Nije preuzeto + + + Select All + Odaberi sve + + + Select None + Ne odaberi ništa + + + Do not download + Ne preuzimaj + + + Pieces size: + Veličina djelića: + + + Time active: + Time (duration) the torrent is active (not paused) + Aktivno: + + + Torrent content: + Sadržaj torrenta: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1 dostigao je najveći zadani omjer. + + + Removing torrent %1... + Uklanjanje torrenta %1 ... + + + Pausing torrent %1... + Pauziranje torrenta %1 ... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent je povezan s portom: TCP/%1 + + + UPnP support [ON] + Podrška za UPnP [UKLJUČENO] + + + UPnP support [OFF] + Podrška za UPnP [ISKLJUČENO] + + + NAT-PMP support [ON] + Podrška za NAT-PMP [UKLJUČENO] + + + NAT-PMP support [OFF] + Podrška za NAT-PMP [ISKLJUČENO] + + + HTTP user agent is %1 + Agent HTTP korisnika je %1 + + + Using a disk cache size of %1 MiB + Korištenje privremene memorije diska od %1 MiB + + + DHT support [ON], port: UDP/%1 + Podrška za DHT [UKLJUČENO], port: UDP/%1 + + + DHT support [OFF] + Podrška za DHT [ISKLJUČENO] + + + PeX support [ON] + Podrška za PeX [UKLJUČENO] + + + PeX support [OFF] + Podrška za PeX [ISKLJUČENO] + + + Restart is required to toggle PeX support + Potrebno je ponovno pokretanje za uključivanje/isključivanje podrške za PeX + + + Local Peer Discovery [ON] + Otkrivanje lokalnih peerova [UKLJUČENO] + + + Local Peer Discovery support [OFF] + Podrška za otkrivanje lokalnih peerova [ISKLJUČENO] + + + Encryption support [ON] + Podrška za kriptiranje [UKLJUČENO] + + + Encryption support [FORCED] + Podrška za kriptiranje [PRISILNO] + + + Encryption support [OFF] + Podrška za kriptiranje [ISKLJUČENO] + + + Embedded Tracker [ON] + Ugrađeni tracker [UKLJUČENO] + + + Failed to start the embedded tracker! + Nije moguće pokrenuti ugrađeni tracker! + + + Embedded Tracker [OFF] + Ugrađeni tracker [ISKLJUČENO] + + + The Web UI is listening on port %1 + Web sučelje osluškuje na portu %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Greška web korisničkog sučelja - Nije moguće povezati web korisničko sučelje s portom %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' je uklonjena s popisa transfera i čvrstog diska. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' je uklonjena s popisa transfera. + + + '%1' is not a valid magnet URI. + '%1' nije valjani magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' je već na popisu preuzimanja. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' počinje iznova. (brzo) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' je dodan popisu preuzimanja. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Nije moguće dekodirati torrent datoteku: '%1' + + + This file is either corrupted or this isn't a torrent. + Ta datoteka je i dalje neispravna ili nije torrent. + + + Error: The torrent %1 does not contain any file. + Greška: Torrent %1 ne sadrži nikakve datoteke. + + + Note: new trackers were added to the existing torrent. + Opaska: novi trackeri su dodani postojećem torrentu. + + + Note: new URL seeds were added to the existing torrent. + Opaska: novi URL seedovi dodani su postojećem torrentu. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>blokirano s obzirom na IP filter</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>zabranjeno zbog neispravnih dijelova</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekurzivno preuzimanje datoteke %1 ugrađeno u torrent %2 + + + Unable to decode %1 torrent file. + Nije moguće dekodirati %1 torrent datoteku. + + + Torrent name: %1 + Ime torrenta: %1 + + + Torrent size: %1 + Veličina torrenta: %1 + + + Save path: %1 + Putanja spremanja: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent je preuzet u %1. + + + Thank you for using qBittorrent. + Hvala vam što ste koristili qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 je preuzet + + + An I/O error occured, '%1' paused. + Dogodila se I/O greška. '%1' pauziran. + + + Reason: %1 + Razlog: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Mapiranje porta nije uspjelo, poruka: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Mapiranje porta je uspjelo, poruka: %1 + + + File sizes mismatch for torrent %1, pausing it. + Veličine datoteka se ne slažu za torrent %1, tako da će biti pauziran. + + + Fast resume data was rejected for torrent %1, checking again... + Brzi ponovni početak je odbijen za torrent %1, ponovna provjera ... + + + Url seed lookup failed for url: %1, message: %2 + Traženje URL seeda nije uspjelo za URL: %1, poruka: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Preuzimanje '%1', pričekajte ... + + + The network interface defined is invalid: %1 + Definirano mrežno sučelje nije ispravno: %1 + + + Trying any other network interface available instead. + Isprobavanje bilo kojeg drugog mrežnog sučelje umjesto raspoloživog. + + + Listening on IP address %1 on network interface %2... + Osluškivanje na IP adresi %1 na mrežnom sučelju %2 ... + + + Failed to listen on network interface %1 + Nije uspjelo osluškivanje na mrežnom sučelju %1 + + + UPnP / NAT-PMP support [ON] + Podrška za UPnP / NAT-PMP [UKLJUČENA] + + + UPnP / NAT-PMP support [OFF] + Podrška za UPnP / NAT-PMP [ISKLJUČENA] + + + Local Peer Discovery support [ON] + Podrška za lokalno otkrivanje peerova [UKLJUČENA] + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Uspješno razrješen dani IP filter: Primjenjena su %1 pravila. + + + Error: Failed to parse the provided IP filter. + Greška: Razrješavanje danog IP filtera nije uspjelo. + + + Reporting IP address %1 to trackers... + Prijavljivanje IP adrese trackerima... + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Računalo će sada prijeći u stanje mirovanja osim ako ne otkažete unutar sljedećih 15 sekundi ... + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Računalo će sada biti isključeno osim ako ne otkažete unutar sljedećih 15 sekundi ... + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent će se sada zatvoriti osim ako ne otkažete unutar sljedećih 15 sekundi ... + + + + RSS + + Search + Traži + + + New subscription + Nova predbilježba + + + Mark items read + Označi stavke kao pročitane + + + Update all + Ažuriraj sve + + + RSS feeds + RSS kanali + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrenti:</span> <span style=" font-style:italic;">(dvostruki klik za preuzimanje )</span></p></body></html> + + + Article title + Naslov članka + + + Feed URL + URL kanala + + + Delete + Izbriši + + + Rename + Preimenuj + + + Update + Ažuriraj + + + Update all feeds + Ažuriraj sve kanale + + + Download torrent + Preuzmi torrent + + + Open news URL + Otvori news URL + + + Copy feed URL + Kopiraj URL kanala + + + RSS feed downloader + Preuzimač RSS kanala + + + New folder + Nova mapa + + + Refresh RSS streams + Osvježi RSS strujanja + + + Rename... + Preimenuj ... + + + New subscription... + Nova predbilježba ... + + + RSS feed downloader... + Preuzimatelj RSS kanala ... + + + New folder... + Nova mapa ... + + + Manage cookies... + Upravljaj kolačićima ... + + + Settings... + Postavke ... + + + RSS Downloader... + RSS preuzimatelj + + + + RSSImp + + Please type a rss stream url + Utipkajte URL RSS strujanja + + + Stream URL: + URL strujanja: + + + Are you sure? -- qBittorrent + Jeste li sigurni? -- qBittorrent + + + &Yes + &Da + + + &No + &Ne + + + Please choose a folder name + Izaberite ime mape + + + Folder name: + Ime mape: + + + New folder + Nova mapa + + + Overwrite attempt + Pokušaj pisanja preko + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Ne možete pisti preko %1 stavke. + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + Taj RSS kanal je već na popisu. + + + Are you sure you want to delete these elements from the list? + Jeste li sigurni da želite izbrisati te elemente s popisa? + + + Are you sure you want to delete this element from the list? + Jeste li sigurni da želite izbrisati taj element s popisa? + + + Please choose a new name for this RSS feed + Izaberite novo ime za taj RSS kanal + + + New feed name: + Novo ime kanala: + + + Name already in use + Ime se već koristi + + + This name is already used by another item, please choose another one. + To ime već koristi neka druga stavka. Izaberite drugo. + + + Date: + Datum: + + + Author: + Autor: + + + Unread + Nepročitano + + + + RssArticle + + No description available + Opis nije dostupan + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + Automatsko preuzimanje %1 torrenta sa %2 RSS kanala ... + + + + RssItem + + No description available + Opis nije dostupan + + + + RssSettings + + RSS Reader Settings + Postavke RSS čitača + + + RSS feeds refresh interval: + Interval osvježavanja RSS kanala: + + + minutes + minute + + + Maximum number of articles per feed: + Najveći broj članaka po kanalu: + + + + RssSettingsDlg + + RSS Reader Settings + Postavke RSS čitača + + + RSS feeds refresh interval: + Interval osvježavanja RSS kanala: + + + minutes + minute + + + Maximum number of articles per feed: + Najveći broj članaka po kanalu: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Automatsko preuzimanje %1 torrenta sa %2 RSS kanala ... + + + + ScanFoldersModel + + Watched Folder + Pregledana mapa + + + Download here + Preuzmi ovdje + + + + SearchCategories + + All categories + Kategorije + + + Movies + Filmovi + + + TV shows + TV emisije + + + Music + Glazba + + + Games + Igre + + + Anime + Animirani + + + Software + Softver + + + Pictures + Slike + + + Books + Knjige + + + + SearchEngine + + Cut + Izreži + + + Copy + Kopiraj + + + Paste + Zalijepi + + + Clear field + Očisti polje + + + Clear completion history + Izbriši povijest upotpunjavanja + + + Search + Traži + + + Empty search pattern + Prazan predložak potrage + + + Please type a search pattern first + Prvo utipkajte predložak potrage + + + Results + Rezultati + + + Searching... + Potraga ... + + + Search Engine + Tražilica + + + Search has finished + Potraga je gotova + + + An error occured during search... + Dogodila se greška za vrijeme potrage ... + + + Search aborted + Potraga je otkazana + + + Search returned no results + Potraga vraćena bez rezultata + + + Results + i.e: Search results + Rezultati + + + Unknown + Nije poznato + + + Download error + Greška prilikom preuzimanja + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Python setup nije moguće preuzeti. Razlog: %1. +Instalirajte ručno. + + + Missing Python Interpreter + Nedostaje Python Interpreter + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x je nužan kako biste mogli koristiti tražilicu i čini se da nije instaliran. +Želite li ga sada instalirati? + + + Confirmation + Potvrda + + + Are you sure you want to clear the history? + Jeste li sigurni da želite izbrisati povijest? + + + + SearchTab + + Name + i.e: file name + Ime + + + Size + i.e: file size + Veličina + + + Seeders + i.e: Number of full sources + Seederi + + + Leechers + i.e: Number of partial sources + Leecheri + + + Search engine + Tražilica + + + + ShutdownConfirmDlg + + Shutdown confirmation + Potvrda isključivanja + + + + SpeedLimitDialog + + KiB/s + KiB/s + + + + StatusBar + + Connection status: + Status spajanja: + + + No direct connections. This may indicate network configuration problems. + Nema izravnih spajanja. Ovo može značiti probleme u postavkama mreže. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + Preuzimanje: %1 B/s - Preuzeto: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + Slanje: %1 B/s - Poslano: %2 + + + DHT: %1 nodes + DHT: %1 čvorova + + + Connection Status: + Status spajanja: + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Odspojeno. Ovo najčešće znači da qBittorrent nije uspio u očekivanju veze na odabranom portu za dolazna spajanja. + + + Online + Spojeno + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Preuzimanje: %1/s - Preuzeto: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Slanje: %1/s - Poslano: %2 + + + Click to disable alternative speed limits + Kliknite kako biste onemogućili alternativne limite brzine + + + Click to enable alternative speed limits + Kliknite kako biste omogućili alternativne limite brzine + + + Global Download Speed Limit + Globalni limit brzine preuzimanja + + + Global Upload Speed Limit + Globalni limit brzine slanja + + + qBittorrent needs to be restarted + qBittorrent treba ponovno pokrenuti + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent je upravo ažuriran i treba ga ponovno pokrenuti kako bi promjene postale učinkovite. + + + Click to switch to alternative speed limits + Kliknite za prelazak na alternativne limite brzine + + + Click to switch to regular speed limits + Kliknite za prelazak na uobičajene limite brzine + + + %1/s + Per second + %1/s + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + Izaberite mapu koja će biti dodana torrentu + + + Select a file to add to the torrent + Izaberite datoteku koja će biti dodana torrentu + + + No input path set + Nije zadana ulazna putanja + + + Please type an input path first + Upišite prvo ulaznu putanju + + + Select destination torrent file + Izabrite odredišnu torrent datoteku + + + Torrent Files + Torrent datoteke + + + Torrent creation + Kreiranje torrenta + + + Torrent creation was unsuccessful, reason: %1 + Kreiranje torrenta nije uspjelo. Razlog: %1 + + + Created torrent file is invalid. It won't be added to download list. + Kreirana torrent datoteka nije ispravna. Neće biti dodana na popis preuzimanja. + + + Torrent was created successfully: + Torrent je uspješno kreiran: + + + + TorrentFilesModel + + Name + Ime + + + Size + Veličina + + + Progress + Napredak + + + Priority + Prioritet + + + + TorrentImportDlg + + Torrent Import + Uvoz torrenta + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Ovaj pomoćnik će vam olakšati dijeliti pomoću qBittorrenta torrent koji ste već preuzeli. + + + Torrent file to import: + Torrent datoteka za uvoz: + + + ... + ... + + + Content location: + Lokacija sadržaja: + + + Skip the data checking stage and start seeding immediately + Preskoči korak provjere podataka i trenutno započni seedanje + + + Import + Uvezi + + + Torrent file to import + Torrent datoteka za uvoz + + + Torrent files (*.torrent) + Torrent datoteke (*.torrent) + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 datoteke + + + Please provide the location of %1 + %1 is a file name + Navedite lokaciju %1 + + + Please point to the location of the torrent: %1 + Istaknite lokaciju torrenta: %1 + + + Invalid torrent file + Neispravna torrent datoteka + + + This is not a valid torrent file. + Ovo nije ispravna torrent datoteka. + + + + TorrentModel + + Name + i.e: torrent name + Ime + + + Size + i.e: torrent size + Veličina + + + Done + % Done + Napredak + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + Seeds + i.e. full sources (often untranslated) + Seedovi + + + Peers + i.e. partial sources (often untranslated) + Peerovi + + + Down Speed + i.e: Download speed + Brzina preuzimanja + + + Up Speed + i.e: Upload speed + Brzina slanja + + + Ratio + Share ratio + Omjer + + + ETA + i.e: Estimated Time of Arrival / Time left + Preostalo vrijeme + + + Label + Oznaka + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Dodano + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Dovršeno + + + Tracker + Tracker + + + Down Limit + i.e: Download limit + Limit preuzimanja + + + Up Limit + i.e: Upload limit + Limit slanja + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Preuzeta količina + + + Amount left + Amount of data left to download (e.g. in MB) + Preostala količina + + + Time Active + Time (duration) the torrent is active (not paused) + Vrijeme aktivnosti + + + + TrackerList + + URL + URL + + + Status + Status + + + Peers + Peerovi + + + Message + Poruka + + + [DHT] + [DHT] + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Working + Radi + + + Disabled + Onemogućeno + + + This torrent is private + Ovaj torrent je privatan + + + Updating... + Ažuriranje ... + + + Not working + Ne radi + + + Not contacted yet + Još nije kontaktirano + + + Add a new tracker + Dodaj novi tracker + + + Add a new tracker... + Dodaj novi tracker ... + + + Remove tracker + Ukloni tracker + + + Force reannounce + Prisili ponovno objavljivanje + + + + TrackersAdditionDlg + + Trackers addition dialog + Dijalog dodavanja trackera + + + List of trackers to add (one per line): + Popis trackera za dodati (jedan po liniji): + + + µTorrent compatible list URL: + Popis URL-ova kompatibilan s µTorrentom: + + + I/O Error + I/O greška + + + Error while trying to open the downloaded file. + Greška prilikom pokušaja otvaranja preuzete datoteke. + + + No change + Bez promjene + + + No additional trackers were found. + Nisu pronađeni dodatni trackeri. + + + Download error + Greška prilikom preuzimanja + + + The trackers list could not be downloaded, reason: %1 + Popis trackera nije moguće preuzeti. Razlog: %1 + + + + TransferListDelegate + + Downloading + Preuzimanje + + + Paused + Pauzirano + + + Queued + i.e. torrent is queued + Na čekanju + + + Seeding + Torrent is complete and in upload-only mode + Seedanje + + + Stalled + Torrent is waiting for download to begin + Zastoj + + + Checking + Torrent local data is being checked + Provjeravanje + + + /s + /second (.i.e per second) + /s + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seedano za %1 + + + + TransferListFiltersWidget + + All + Sve + + + Downloading + Preuzimanja + + + Completed + Završeno + + + Active + Aktivno + + + Inactive + Neaktivno + + + All labels + Sve označeno + + + Unlabeled + Neoznačeno + + + Remove label + Ukloni oznaku + + + Add label + Dodaj oznaku + + + New Label + Nova oznaka + + + Label: + Oznaka: + + + Invalid label name + Neispravno ime oznake + + + Please don't use any special characters in the label name. + Nemojte koristiti niti jedan poseban znak u imenu oznake. + + + Paused + Pauzirano + + + Add label... + Dodaj oznaku ... + + + Resume torrents + Nastavi s torrentima + + + Pause torrents + Pauziraj torrente + + + Delete torrents + Izbriši torrente + + + + TransferListWidget + + Down Speed + i.e: Download speed + Brzina preuzimanja + + + Up Speed + i.e: Upload speed + Brzina slanja + + + ETA + i.e: Estimated Time of Arrival / Time left + Preostalo vrijeme + + + Column visibility + Vidljivost stupca + + + Start + Započni + + + Pause + Pauziraj + + + Delete + Izbriši + + + Preview file + Pregledaj datoteku + + + Name + i.e: torrent name + Ime + + + Size + i.e: torrent size + Veličina + + + Done + % Done + Gotovo + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + Seeds + i.e. full sources (often untranslated) + Seedovi + + + Peers + i.e. partial sources (often untranslated) + Peerovi + + + Ratio + Share ratio + Omjer + + + Label + Oznaka + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Dodano + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Dovršeno + + + Down Limit + i.e: Download limit + Limit preuzimanja + + + Up Limit + i.e: Upload limit + Limit slanja + + + Torrent Download Speed Limiting + Limitiranje brzine preuzimanja torrenta + + + Torrent Upload Speed Limiting + Limitiranje brzine slanja torrenta + + + New Label + Nova oznaka + + + Label: + Oznaka: + + + Invalid label name + Neispravno ime oznake + + + Please don't use any special characters in the label name. + Nemojte koristiti niti jedan poseban znak u imenu oznake. + + + Rename + Preimenovanje + + + New name: + Novo ime: + + + Limit upload rate + Limitiraj brzinu slanja + + + Limit download rate + Limitiraj brzinu preuzimanja + + + Open destination folder + Otvori odredišnu mapu + + + Buy it + Kupi + + + Increase priority + Povećaj prioritet + + + Decrease priority + Smanji prioritet + + + Force recheck + Prisili ponovnu provjeru + + + Copy magnet link + Kopiraj magnet link + + + Super seeding mode + Način superseedanja + + + Rename... + Preimenuj ... + + + Download in sequential order + Preuzmi u sekvencijskom poretku + + + Download first and last piece first + Preuzmi prvi i zadnji djelić + + + New... + New label... + Nova ... + + + Reset + Reset label + Poništi + + + Choose save path + Izaberi putanju spremanja + + + Save path creation error + Greška prilikom kreiranja putanje spremanja + + + Could not create the save path + Nije moguće kreirati putanju spremanja + + + Set location... + Postavi mjesto ... + + + Preview file... + Pregledaj datoteke + + + Limit upload rate... + Limitiraj brzinu slanja ... + + + Limit download rate... + Limitiraj brzinu preuzimanja ... + + + Move up + i.e. move up in the queue + Pomakni gore + + + Move down + i.e. Move down in the queue + Pomakni dolje + + + Move to top + i.e. Move to top of the queue + Na vrh + + + Move to bottom + i.e. Move to bottom of the queue + Na dno + + + Priority + Prioritet + + + Resume + Resume/start the torrent + Nastavi + + + Pause + Pause the torrent + Pauziraj + + + Delete + Delete the torrent + Izbriši + + + Limit share ratio... + Limit omjera djeljenja + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + Limitiranje omjera slanja/preuzimanja torrenta + + + Use global ratio limit + Koristi globalni limit omjera + + + buttonGroup + buttonGroup + + + Set no ratio limit + Ne podešavaj limit omjera + + + Set ratio limit to + Podesi limit omjera na + + + + UsageDisplay + + Usage: + Upotreba: + + + displays program version + prikazuje verziju programa + + + disable splash screen + onemogućava najavni zaslon + + + displays this help message + prikazuje ovu poruku pomoći + + + changes the webui port (current: %1) + mijenja port web sučelja(trenutni: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [datoteke ili URL-ovi]: preuzima torrente koje je korisnik dopustio (neobavezno) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + Zahvaljujem sljedećim ljudima koji su dobrovoljno preveli qBittorrent: + + + Please contact me if you would like to translate qBittorrent into your own language. + Molim vas da me obavijestite ako želite prevesti qBittorrent na svoj jezik. + + + + addPeerDialog + + Peer addition + Dodavanje peerova + + + IP + IP + + + Port + Port + + + + addTorrentDialog + + Torrent addition dialog + Dijalog dodavanja torrenta + + + Save path: + Putanja za spremanje: + + + ... + ... + + + Torrent size: + Veličina torrenta: + + + Unknown + Nije poznato + + + Free disk space: + Slobodan prostor na disku: + + + Label: + Oznaka: + + + Torrent content: + Sadržaj torrenta: + + + Download in sequential order (slower but good for previewing) + Preuzmi u sekvencijskom poretku (sporije, ali dobro za pregledavanje) + + + Skip file checking and start seeding immediately + Preskoči provjeru datoteke i trenutno započni seedanje + + + Add to download list in paused state + Dodaj popisu preuzimanja u zaustavljenom stanju + + + Add + Dodaj + + + Cancel + Odustani + + + Normal + Uobičajen + + + High + Visok + + + Maximum + Najviši + + + Collapse all + Sklopi sve + + + Expand all + Proširi sve + + + Not downloaded + Nije preuzeto + + + Select All + Odaberi sve + + + Select None + Ne odaberi ništa + + + Do not download + Ne preuzimaj + + + + authentication + + Tracker authentication + Ovjera trackera + + + Tracker: + Tracker: + + + Login + Prijava + + + Username: + Korisničko ime: + + + Password: + Lozinka: + + + Log in + Prijavi se + + + Cancel + Odustani + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + Potvrda brisanja - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + Jeste li sigurni da želite izbrisati odabrane torrente s popisa transfera? + + + Delete the files on the hard disk as well + Brisati datoteke i na tvrdom disku + + + Remember choice + Zapamti izbor + + + Also delete the files on the hard disk + Također izbriši datoteke i na čvrstom disku + + + + createTorrentDialog + + Cancel + Odustani + + + Torrent Creation Tool + Alat za kreiranje torrenta + + + Torrent file creation + Kreiranje torrent datoteke + + + Add file + Dodaj datoteku + + + Add folder + Dodaj mapu + + + Announce urls (trackers): + Objavi URL-ove (trackeri): + + + Comment (optional): + Komentar (neobavezno): + + + Web seeds urls (optional): + URL-ovi web seedova (neobavezno): + + + File or folder to add to the torrent: + Datoteka ili mapa za dodati u torrent: + + + Piece size: + Veličina djelića: + + + 32 KiB + 32 KiB + + + 64 KiB + 64 KiB + + + 128 KiB + 128 KiB + + + 256 KiB + 256 KiB + + + 512 KiB + 512 KiB + + + 1 MiB + 1 MiB + + + 2 MiB + 2 MiB + + + 4 MiB + 4 MiB + + + Private (won't be distributed on DHT network if enabled) + Privatno (neće biti distribuirano na DHT mreži ako je omogućeno) + + + Start seeding after creation + Započni seedanje nakon kreiranja + + + Create and save... + Kreiraj i spremi ... + + + Progress: + Napredak: + + + Tracker URLs: + URL-ovi trackera: + + + Web seeds urls: + URL-ovi web seedova: + + + Comment: + Komentar: + + + Auto + Auto + + + + createtorrent + + Select destination torrent file + Izabrite odredišnu torrent datoteku + + + Torrent Files + Torrent datoteke + + + No input path set + Nije zadana ulazna putanja + + + Please type an input path first + Upišite prvo ulaznu putanju + + + Torrent creation + Kreiranje torrenta + + + Torrent was created successfully: + Torrent je uspješno kreiran: + + + Select a folder to add to the torrent + Izaberite mapu koja će biti dodana torrentu + + + Please type an announce URL + Upišite objavljeni URL + + + Torrent creation was unsuccessful, reason: %1 + Kreiranje torrenta nije uspjelo. Razlog: %1 + + + Announce URL: + Tracker URL + Objavljeni URL: + + + Please type a web seed url + Upišite URL web seeda + + + Web seed URL: + URL web seeda: + + + Select a file to add to the torrent + Izaberite datoteku koja će biti dodana torrentu + + + Created torrent file is invalid. It won't be added to download list. + Kreirana torrent datoteka nije ispravna. Neće biti dodana na popis preuzimanja. + + + + downloadFromURL + + Download Torrents from URLs + Preuzmi torrente s URL-ova + + + Only one URL per line + Samo jedan URL po liniji + + + Download + Preuzmi + + + Cancel + Odustani + + + Download from urls + Preuzmi s URL-ova + + + No URL entered + Nije unesen URL + + + Please type at least one URL. + Upišite bar jedan URL. + + + Add torrent links + Dodaj linkove torrenta + + + Both HTTP and Magnet links are supported + Podržani su HTTP i Magnet linkovi + + + + downloadThread + + I/O Error + I/O greška + + + The remote host name was not found (invalid hostname) + Ime udaljenog računala nije nađeno (neispravno ime računala) + + + The operation was canceled + Operacija je otkazana + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Udaljeni poslužitelj je prerano prekinuo spajanje, prije nego je primljen i obrađen cijeli odgovor + + + The connection to the remote server timed out + Spajanje s udaljenim poslužiteljem je isteklo + + + SSL/TLS handshake failed + SSL/TLS usklađivanje nije uspjelo + + + The remote server refused the connection + Udaljeni poslužitelj odbija spajanje + + + The connection to the proxy server was refused + Spajanje s proxy poslužiteljem je odbijeno + + + The proxy server closed the connection prematurely + Proxy server je prerano prekinuo spajanje + + + The proxy host name was not found + Ime proxy računala nije nađeno + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Spajanje prema proxyju je isteklo ili proxy nije na vrijeme odgovorio na poslani zahtjev + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Proxy zahtjeva ovjeru kako bi prihvatio zahtjev, ali nije prihvatio ponuđene vjerodajnice + + + The access to the remote content was denied (401) + Pristup udaljenom sadržaju je odbijen (401) + + + The operation requested on the remote content is not permitted + Tražena operacija nad udaljenim sadržajem nije dopuštena + + + The remote content was not found at the server (404) + Udaljeni sadržaj nije nađen na poslužitelju (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Udaljeni poslužitelj zahtjeva ovjeru kako bi dostavio sadržaj, ali pružene vjerodajnice nisu prihvaćene + + + The Network Access API cannot honor the request because the protocol is not known + Network Access API ne može prihvatiti zahtjev jer protokol nije poznat + + + The requested operation is invalid for this protocol + Tražena operacija je neispravna za ovaj protokol + + + An unknown network-related error was detected + Otkrivena je nepoznata greška vezana za mrežu + + + An unknown proxy-related error was detected + Otkrivena je nepoznata greška vezana za proxy + + + An unknown error related to the remote content was detected + Otkrivena je nepoznata greška vezana za udaljeni sadržaj + + + A breakdown in protocol was detected + Otkriven je kvar u protokolu + + + Unknown error + Nepoznata greška + + + + engineSelect + + Search plugins + Tražilice + + + Installed search engines: + Instalirane tražilice: + + + Name + Ime + + + Url + Url + + + Enabled + Omogućeno + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Nove tražilice možete naći ovdje: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + Install a new one + Instaliraj novu + + + Check for updates + Provjeri ažuriranja + + + Close + Zatvori + + + Enable + Omogući + + + Disable + Onemogući + + + Uninstall + Deinstaliraj + + + + engineSelectDlg + + Uninstall warning + Upozorenje deinstalacije + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Neke tražilice ne mogu biti instalirane jer su već uključene u QBittorrent. +Samo one koje ste sami dodali mogu biti deinstalirane. +Međutim, te tražilice su bile onemogućene. + + + Uninstall success + Deinstalacija je uspjela + + + Select search plugins + Izaberite tražilice + + + qBittorrent search plugins + qBittorrentove tražilice + + + Search plugin install + Instalacija tražilice + + + Yes + Da + + + No + Ne + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Novija verzija %1 tražilice je već instalirana. + + + Search plugin update + Ažuriranje tražilice + + + Sorry, update server is temporarily unavailable. + Oprostite, ali poslužitelj za ažuriranje trenutno nije raspoloživ. + + + All your plugins are already up to date. + Sve vaše tražilice su ažurirane. + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 tražilica ne može biti ažurirana tako da ostaje stara verzija. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 tražilicu nije moguće instalirati. + + + All selected plugins were uninstalled successfully + Sve izabrane tražilice su uspješno deinstalirane + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 tražilica je uspješno ažurirana. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1 tražilica je uspješno instalirana. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Oprostite, ali instalacija %1 tražilice nije uspjela. + + + New search engine plugin URL + Novi URL tražilice + + + URL: + URL: + + + + misc + + B + bytes + B + + + KiB + kibibytes (1024 bytes) + KiB + + + MiB + mebibytes (1024 kibibytes) + MiB + + + GiB + gibibytes (1024 mibibytes) + GiB + + + TiB + tebibytes (1024 gibibytes) + TiB + + + Unknown + Unknown (size) + Nije poznato + + + Unknown + Nije poznato + + + < 1m + < 1 minute + < 1m + + + %1m + e.g: 10minutes + %1m + + + %1h%2m + e.g: 3hours 5minutes + %1s%2m + + + %1d%2h%3m + e.g: 2days 10hours 2minutes + %1d%2s%3m + + + %1h %2m + e.g: 3hours 5minutes + %1s %2m + + + %1d %2h + e.g: 2days 10hours + %1d %2s + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent će sada isključiti računalo jer su sva preuzimanja završila. + + + + options_imp + + Choose scan directory + Izaberite direktorij za skeniranje + + + Choose export directory + Izaberite direktorij za izvoz + + + Choose a save directory + Izaberite direktorij za spremanje + + + Choose an ip filter file + Izaberite datoteku za ip filtriranje + + + Filters + Filteri + + + Add directory to scan + Dodaj direktorij za skeniranje + + + Folder is already being watched. + Mapa je već pregledana. + + + Folder does not exist. + Mapa ne postoji. + + + Folder is not readable. + Mapa nije čitljiva. + + + Failure + Neuspjeh + + + Failed to add Scan Folder '%1': %2 + Nije uspjelo dodavanje mape za skeniranje '%1': %2 + + + Parsing error + Greška razrješavanja + + + Failed to parse the provided IP filter + Razrješavanje danog IP filtera nije uspjelo + + + Succesfully refreshed + Uspješno obnovljeno + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Uspješno razrješen dani IP filter: Primjenjena su %1 pravila. + + + Successfully refreshed + Uspješno obnovljeno + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + Invalid key + + + + This is not a valid SSL key. + + + + Invalid certificate + + + + This is not a valid SSL certificate. + + + + + pluginSourceDlg + + Plugin source + Izvor priključka + + + Search plugin source: + Potraži izvor priključka: + + + Local file + Lokalna datoteka + + + Web link + Web link + + + + preview + + Preview selection + Pregledaj odabir + + + File preview + Pregled datoteke + + + The following files support previewing, <br>please select one of them: + Sljedeće datoteke podržavaju pregledavanje, <br>izaberite jednu od njih: + + + Preview + Pregledaj + + + Cancel + Odustani + + + + previewSelect + + Preview impossible + Pregled nije moguć + + + Sorry, we can't preview this file + Oprostite, nije moguće pregledati datoteku + + + Name + Ime + + + Size + Veličina + + + Progress + Napredak + + + + search_engine + + Search + Traži + + + Status: + Status: + + + Stopped + Zaustavljeno + + + Download + Preuzmi + + + Search engines... + Tražilice ... + + + Go to description page + Idi na stranicu opisa + + + + torrentAdditionDialog + + Unable to decode magnet link: + Nije moguće dekodirati magnet link: + + + Magnet Link + Magnet link + + + Unable to decode torrent file: + Nije moguće dekodirati torrent datoteku: + + + Rename... + Preimenuj ... + + + Priority + Prioritet + + + Rename the file + Preimenuj datoteku + + + New name: + Novo ime: + + + The file could not be renamed + Datoteku nije moguće preimenovati + + + This file name contains forbidden characters, please choose a different one. + Datoteka sadrži nedopuštene znakove. Izaberite drukčije znakove. + + + This name is already in use in this folder. Please use a different name. + Ime se već koristi u toj mapi. Koristite drugo ime. + + + The folder could not be renamed + Mapu nije moguće preimenovati + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 ostalo nakon preuzimanja torrenta) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 više je potrebno za preuzimanje) + + + Choose save path + Izaberite putanju za spremanje + + + Empty save path + Ispraznite putanju za spremanje + + + Please enter a save path + Upišite putanju za spremanje + + + Save path creation error + Greška prilikom kreiranja putanje za spremanje + + + Could not create the save path + Nije moguće kreirati putanju za spremanje + + + Invalid label name + Neispravano ime oznake + + + Please don't use any special characters in the label name. + Nemojte koristiti nijedan poseban znak u imenu oznake. + + + Seeding mode error + Greška seeding moda + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Izabrali ste preskočiti provjeru datoteke. Ipak, čini se da lokalne datoteke ne postoje u trenutnoj odredišnoj mapi. Onemogućite ovu značajku ili ažurirajte putanju za spremanje. + + + Invalid file selection + Neispravan odabir datoteke + + + You must select at least one file in the torrent + Morate izabrati najmanje jednu datoteku u torrentu + + + diff --git a/src/lang/qbittorrent_hu.qm b/src/lang/qbittorrent_hu.qm new file mode 100644 index 0000000000000000000000000000000000000000..086bf852ff8c7432696e1a9b3d519943f7f81998 GIT binary patch literal 100480 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 qiCwz1b6AD7w3L? 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 + + + + AboutDlg + + + About qBittorrent + A qBittorrent névjegye + + + + About + Névjegy + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Bittorrent kliens Qt4-re C++ nyelven fejlesztve </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">libtorrent-rasterbar alapú. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Honlap:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Fórum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + Author + Szerző + + + + Name: + Név: + + + + Country: + Szülőföld: + + + + E-mail: + E-mail: + + + + Christophe Dumez + Christophe Dumez + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + + France + Franciaország + + + + Translation + Fordítás + + + + License + Licenc + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + + chris@qbittorrent.org + chris@qbittorrent.org + + + + Thanks to + Külön köszönet + + + + AdvancedSettings + + Property + Tulajdonság + + + Value + Érték + + + + Disk write cache size + Lemez írási gyorsítótár mérete + + + + MiB + MiB + + + + Outgoing ports (Min) [0: Disabled] + Outgoing port (Min) [0: Letiltva] + + + + Outgoing ports (Max) [0: Disabled] + Outgoing ports (Max) [0: Letiltva] + + + + Recheck torrents on completion + Torrent újra ellenőrzése a letöltés végén + + + + Transfer list refresh interval + Átviteli lista frissítése + + + + ms + milliseconds + ms + + + + Setting + + + + + Value + Value set for this setting + Érték + + + + Resolve peer countries (GeoIP) + Ügyfelek országának megjelenítése + + + + Resolve peer host names + Host név megjelenítése + + + + Maximum number of half-open connections [0: Disabled] + A félig nyitott kapcsolatok maximális száma [0: Kikapcsolva] + + + + Strict super seeding + Szigorúan szuper seed + + + + Network Interface (requires restart) + Háltózati csatoló (újraindítást igényel) + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + Bármely csatoló + + + + IP Address to report to trackers (requires restart) + IP cím jelentése a trackernek (újraindítást igényel) + + + + Display program on-screen notifications + Értesítési ablakok megjelenítése + + + Display program notification balloons + Értesítési üzenetek megjelenítése + + + + Enable embedded tracker + Beágyazott tracker + + + + Embedded tracker port + Beágyazott tracker port + + + + Check for software updates + Frissítések keresése + + + + Use system icon theme + Renszer ikon téma használata + + + + Confirm torrent deletion + Torrent törlés megerősítése + + + + Ignore transfer limits on local network + Az átviteli limit letiltása helyi hálózaton + + + Include TCP/IP overhead in transfer limits + Include TCP/IP overhead in transfer limits + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Automata RSS letöltő + + + + Enable the automated RSS downloader + Automatikus RSS letöltő engedélyezése + + + + Download rules + Letöltési szabályok + + + + Rule definition + Szabályok + + + + Must contain: + Tartalmaznia kell: + + + + Must not contain: + Nem lehet benne: + + + + Use regular expressions + + + + + Import... + Import... + + + + Export... + Export... + + + + ... + ... + + + + Assign label: + Kijelelölt címke: + + + + Save to a different directory + Külön könyvtárba mentés + + + + Save to: + Mentés helye: + + + + Apply rule to feeds: + Szabály a csatornákhoz: + + + + Matching RSS articles + Megfelelő cikkek + + + + New rule name + Új szabály neve + + + + Please type the name of the new download rule. + Kérlek add meg az új letöltési szabály nevét. + + + + + Rule name conflict + Szabály név ütközés + + + + + A rule with this name already exists, please choose another name. + Már van ilyen szabály név. Kérlek válassz másikat. + + + + Are you sure you want to remove the download rule named %1? + Biztosan el akarod távolítani ezt a szabályt %1? + + + + Are you sure you want to remove the selected download rules? + Biztosan eltávolítod a kiválasztott szabályokat? + + + + Rule deletion confirmation + Szabály törlés megerősítése + + + + Destination directory + Célmappa + + + + Invalid action + Érvénytelen esemény + + + + The list is empty, there is nothing to export. + A lista üres. Nincs mit exportálni. + + + + Where would you like to save the list? + Hová szeretnéd menteni a listát? + + + + Rules list (*.rssrules) + Szabály lista (*.rssrules) + + + + I/O Error + I/O Hiba + + + + Failed to create the destination file + Fájl létrehozása sikertelen + + + + Please point to the RSS download rules file + Kérlek nyisd meg az RSS szabályt + + + + Rules list (*.rssrules *.filters) + Szabály lista (*.rssrules *.filters) + + + + Import Error + Import hiba + + + + Failed to import the selected rules file + A kiválasztott szábályok importálása sikertelen + + + + Add new rule... + Új szabály hozzáadása... + + + + Delete rule + Szabály törlése + + + + Rename rule... + Szabály átnevezése... + + + + Delete selected rules + Kiválasztott szabályok törlése + + + + Rule renaming + Szabály átnevezése + + + + Please type the new rule name + Kérlek add meg a szabály új nevét + + + + Regex mode: use Perl-like regular expressions + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 elérte a megengedett arányt. + + + Removing torrent %1... + Torrent eltávolítása %1... + + + Pausing torrent %1... + Torrent leállítása %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent ezen a porton figyel: TCP/%1 + + + UPnP support [ON] + UPnP támogatás [ON] + + + UPnP support [OFF] + UPnP támogatás [OFF] + + + NAT-PMP support [ON] + NAT-PMP támogatás [ON] + + + NAT-PMP support [OFF] + NAT-PMP támogatás [OFF] + + + HTTP user agent is %1 + HTTP user agent %1 + + + Using a disk cache size of %1 MiB + Lemez gyorsítótár: %1 MiB + + + DHT support [ON], port: UDP/%1 + DHT támogatás [ON], port: UDP/%1 + + + DHT support [OFF] + DHT funkció [OFF] + + + PeX support [ON] + PeX [ON] + + + PeX support [OFF] + PeX támogatás [OFF] + + + Restart is required to toggle PeX support + A PeX támogatás bekapcsolása újraindítást igényel + + + Local Peer Discovery [ON] + Local Peer Discovery [ON] + + + Local Peer Discovery support [OFF] + Local Peer Discovery támogatás [OFF] + + + Encryption support [ON] + Titkosítás [ON] + + + Encryption support [FORCED] + Titkosítás [KÉNYSZERÍTVE] + + + Encryption support [OFF] + Titkosítás [OFF] + + + The Web UI is listening on port %1 + A Web UI ezen a porton figyel: %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Webes felület hiba - port használata sikertelen: %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' eltávolítva az átviteli listáról és a merevlemezről. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' eltávolítva az átviteli listáról. + + + '%1' is not a valid magnet URI. + '%1' nem hiteles magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' már letöltés alatt. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' visszaállítva. (folytatás) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' felvéve a letöltési listára. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Megfejthetetlen torrent: '%1' + + + This file is either corrupted or this isn't a torrent. + Ez a fájl sérült, vagy nem is torrent. + + + Note: new trackers were added to the existing torrent. + Megjegyzés: új tracker hozzáadva a torrenthez. + + + Note: new URL seeds were added to the existing torrent. + Megjegyzés: új URL seed hozzáadva a torrenthez. + + + Error: The torrent %1 does not contain any file. + Hiba: A %1 torrent nem tartalmaz fájlokat. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>letiltva IP szűrés miatt</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>kitiltva hibás adatküldés miatt</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Fájl ismételt letöltése %1 beágyazva a torrentbe %2 + + + Unable to decode %1 torrent file. + Megfejthetetlen torrent: %1. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port felderítése sikertelen, hibaüzenet: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port felderítése sikeres, hibaüzenet: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Hibás ellenőrző adat ennél a torrentnél: %1, újraellenőrzés... + + + Reason: %1 + Mivel: %1 + + + An I/O error occured, '%1' paused. + I/O hiba történt, '%1' megállítva. + + + File sizes mismatch for torrent %1, pausing it. + A fájl mérete nem megfelelő ennél a torrentnél: %1, leállítva. + + + Url seed lookup failed for url: %1, message: %2 + Url forrás meghatározása sikertelen: %1, hibaüzenet: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Letöltés alatt: '%1', kis türelmet... + + + + ConsoleDlg + + qBittorrent log viewer + qBittorent eseménynapló + + + General + Általános + + + Blocked IPs + Blokkolt IP címek + + + + CookiesDlg + + + Cookies management + Süti kezelés + + + + Key + As in Key/Value pair + Kulcs + + + + Value + As in Key/Value pair + Érték + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Gyakori süti kulcsok: '%1', '%2'. +Ez megtudható a böngésző beállításaiból. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + + + + + Dynamic DNS error: Invalid username/password. + + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: Your username was blocked due to abuse. + + + + + Dynamic DNS error: supplied domain name is invalid. + + + + + Dynamic DNS error: supplied username is too short. + + + + + Dynamic DNS error: supplied password is too short. + + + + + DownloadThread + + + + I/O Error + I/O Hiba + + + + The remote host name was not found (invalid hostname) + A távoli kiszolgálónév nem található (érvénytelen hosztnév) + + + + The operation was canceled + A művelet megszakítva + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + A távoli szerver lezárta a kapcsolatot a teljes válasz elküldése és feldolgozása előtt + + + + The connection to the remote server timed out + Időtúllépés a szervehez való kapcsolódás közben + + + + SSL/TLS handshake failed + SSL/TLS kapcsolódás sikertelen + + + + The remote server refused the connection + A szerver visszautasította a kapcsolódást + + + + The connection to the proxy server was refused + Kapcsolódás a proxy szerverhez sikertelen + + + + The proxy server closed the connection prematurely + A proxy szerver idő előtt bontotta a kapcsolatot + + + + The proxy host name was not found + Proxy szerver név ismeretlen + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Időtúllépés a proxy szerverhez való kapcsolódáskor, vagy a szerver nem továbbította a kérést időben + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + A proxy szerver hitelesítést kíván, de nem fogadja el a megadott igazolást + + + + The access to the remote content was denied (401) + Csatlakozás a távoli tartalomhoz megtagadva (401) + + + + The operation requested on the remote content is not permitted + A kért művelet nem engedélyezett a távoli eszközön + + + + The remote content was not found at the server (404) + A távoli tartalom nem található a szeveren (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + A szerver hitelesítést kíván, de nem fogadja el a megadott igazolást + + + + The Network Access API cannot honor the request because the protocol is not known + A Network Access API nem teljesíti a kérést, mivel a protokoll ismeretlen + + + + The requested operation is invalid for this protocol + A kért művelet ismeretlen ebben a protokollban + + + + An unknown network-related error was detected + Ismeretlen hálózati hiba történt + + + + An unknown proxy-related error was detected + Ismeretlen proxy hiba történt + + + + An unknown error related to the remote content was detected + Ismeretlen hiba a távoli tartalomban + + + + A breakdown in protocol was detected + Hiba a protokollban + + + + Unknown error + Ismeretlen hiba + + + + EventManager + + + + Working + Folyamatban + + + + Updating... + Frissítés... + + + + + Not working + Nincs folyamatban + + + + + Not contacted yet + Még nem kapcsolódott + + + + + this session + ezen folyamat + + + + + /s + /second (i.e. per second) + /mp + + + + Seeded for %1 + e.g. Seeded for 3m10s + Feltöltési idő: %1 + + + + %1 max + e.g. 10 max + %1 max + + + + + %1/s + e.g. 120 KiB/s + %1/mp + + + + ExecutionLog + + Form + Űrlap + + + + General + Általános + + + + Blocked IPs + Blokkolt IP címek + + + + FeedDownloader + + RSS Feed downloader + Letöltés RSS forrásból + + + RSS feed: + RSS forrás: + + + Feed name + Forrás neve + + + Automatically download torrents from this feed + Torrent automatikus letöltése ebből a forrásból + + + Download filters + Letöltési szűrő + + + Filters: + Szűrő: + + + Filter settings + Szűrő beállításai + + + Matches: + Egyezések: + + + Does not match: + Kivételek: + + + Destination folder: + Célmappa: + + + ... + ... + + + Filter testing + Szűrő próbája + + + Torrent title: + Torrent címe: + + + Result: + Eredmény: + + + Test + Teszt + + + Import... + Import... + + + Export... + Export... + + + Rename filter + Szűrő átnevezése + + + Remove filter + Szűrő eltávolítása + + + Add filter + Szűrő hozzáadása + + + + FeedDownloaderDlg + + New filter + Új szűrő + + + Please choose a name for this filter + Kérlek válassz nevet a szűrőnek + + + Filter name: + Szűrő név: + + + Invalid filter name + Érvénytelen szűrő név + + + The filter name cannot be left empty. + A szűrő név mindenképpen szükséges. + + + This filter name is already in use. + A szűrő név már használatban. + + + Choose save path + Mentés helye + + + Filter testing error + Szűrő teszt hiba + + + Please specify a test torrent name. + Kérlek válassz teszt torrentet. + + + matches + egyezés + + + does not match + nincs egyezés + + + Select file to import + Fájl kiválasztása + + + Filters Files + Szűrő fájlok + + + Import successful + Importálás sikeres + + + Filters import was successful. + Szűrő importálás sikeres. + + + Import failure + Importálás sikertelen + + + Filters could not be imported due to an I/O error. + A szűrőt nem sikerült importálni I/O hiba miatt. + + + Select destination file + Szűrő fájl kiválasztása + + + Export successful + Exportálás sikeres + + + Filters export was successful. + Szűrő exportálás sikeres. + + + Export failure + Exportálás sikertelen + + + Filters could not be exported due to an I/O error. + A szűrőt nem sikerült exportálni I/O hiba miatt. + + + + FeedList + + Unread + Olvasatlan + + + + FeedListWidget + + + RSS feeds + RSS források + + + + Unread + Olvasatlan + + + + GUI + + Open Torrent Files + Megnyitás + + + Torrent Files + Torrentek + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Letöltés: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Feltöltés: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 letöltve. + + + I/O Error + i.e: Input/Output Error + I/O Hiba + + + Search + Keresés + + + Transfers + Átvitelek + + + Torrent file association + Torrent fájl társítás + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + A qBittorrent nem az alapértelmezett .torrent vagy Magnet link kezelő alkalmazás. +Szeretnéd alapértelmezetté tenni? + + + RSS + RSS + + + Transfers (%1) + Átvitelek (%1) + + + Download completion + Elkészült letöltés + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + I/O hiba történt ennél a torrentnél %1. +Oka: %2 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Recursive download confirmation + Letöltés ismételt megerősítése + + + The torrent %1 contains torrent files, do you want to proceed with their download? + A %1 torrent .torrent fájlokat is tartalmaz. Szeretnéd folytatni a letöltést? + + + Yes + Igen + + + No + Nem + + + Never + Soha + + + A newer version is available + Elérhető új verzió + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + A qBittorrent egy újabb verziója érhető el a Soruceforge oldalon. +Szeretnéd most frissíteni a %1 verzióra? + + + Impossible to update qBittorrent + Frissítés sikertelen + + + qBittorrent failed to update, reason: %1 + A qBittorrent frissítése meghiúsult, mert: %1 + + + Exiting qBittorrent + qBittorrent bezárása + + + Always + Mindig + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Letöltés: %2/s, Feltöltés: %3/s) + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Url letöltés hiba + + + Couldn't download file at url: %1, reason: %2. + Nem sikerült letölteni url címről: %1, mert: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Teljes feltöltési sebesség korlát + + + Global Download Speed Limit + Teljes letöltési sebesség korlát + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Néhány átvitel még folyamatban van. +Bizotos, hogy bezárod a qBittorrentet? + + + Options were saved successfully. + Beállítások sikeresen elmentve. + + + + GeoIP + + Australia + Ausztrália + + + Argentina + Argentína + + + Austria + Ausztria + + + United Arab Emirates + Egyesült Arab Emírségek + + + Brazil + Brazília + + + Bulgaria + Bulgária + + + Belarus + Fehéroroszország + + + Belgium + Belgium + + + Bosnia + Bosznia + + + Canada + Kanada + + + Czech Republic + Csehország + + + China + Kína + + + Costa Rica + Costa Rica + + + Switzerland + Svájc + + + Germany + Németország + + + Denmark + Dánia + + + Algeria + Algéria + + + Spain + Spanyolország + + + Egypt + Egyiptom + + + Finland + Finnország + + + France + Franciaország + + + United Kingdom + Egyesült Királyság + + + Greece + Görögország + + + Georgia + Georgia + + + Hungary + Magyarország + + + Croatia + Horvátország + + + Italy + Olaszország + + + India + India + + + Israel + Izrael + + + Ireland + Írország + + + Iceland + Izland + + + Indonesia + Indonézia + + + Japan + Japán + + + South Korea + Dél Korea + + + Luxembourg + Luxemburg + + + Malaysia + Majalzia + + + Mexico + Mexikó + + + Serbia + Szerbia + + + Morocco + Marokkó + + + Netherlands + Hollandia + + + Norway + Norvégia + + + New Zealand + Új-Zéland + + + Portugal + Portugália + + + Poland + Lengyelország + + + Pakistan + Pakisztán + + + Philippines + Fülöp-szigetek + + + Russia + Oroszország + + + Romania + Románia + + + France (Reunion Island) + Franciaország (Reunion Island) + + + Saudi Arabia + Szaúd-Arábia + + + Sweden + Svédország + + + Slovakia + Szlovákia + + + Singapore + Szingapúr + + + Slovenia + Szlovénia + + + Taiwan + Tajvan + + + Turkey + Törökország + + + Thailand + Tájföld + + + USA + USA + + + Ukraine + Ukrajna + + + South Africa + Dél Afrika + + + + HeadlessLoader + + + Information + Információ + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + A qBittorrent irányításához webes felületen nyisd meg ezt a címet: http://localhost:%1 + + + + The Web UI administrator user name is: %1 + Web UI adminisztrátor felhasználó neve: %1 + + + + The Web UI administrator password is still the default one: %1 + Web UI adminisztrátor jelszó még az alapértelmezett: %1 + + + + This is a security risk, please consider changing your password from program preferences. + Ez biztonsági kockázatot jelent. Kérlek változtass jelszót a program beállításinál. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + Az IP címed bannolva lett túl sok hibás azonosítási kísárlet miatt. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - T: %2 + + + + HttpServer + + + File + Fájl + + + + Edit + Szerkesztés + + + + Help + Súgó + + + Delete from HD + Törlés a merevlemezről + + + + Download Torrents from their URL or Magnet link + Torrent letöltése URL vagy Magnet linkről + + + + Only one link per line + Soronként csak egy linket + + + + Download local torrent + Helyi torrent letöltése + + + + Torrent files were correctly added to download list. + Torrent sikeresen hozzáadva a letöltési listához. + + + + Point to torrent file + Torrent lekérdezése + + + + Download + Letöltés + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Egészen biztos, hogy törlöd az átviteli listáról ÉS a merevlemezről is? + + + + Download rate limit must be greater than 0 or disabled. + Letöltési korlátnak 0-nál nagyobbnak kell lennie, vagy kikapcsolva. + + + + Upload rate limit must be greater than 0 or disabled. + Feltöltési korlátnak 0-nál nagyobbnak kell lennie, vagy kikapcsolva. + + + + Maximum number of connections limit must be greater than 0 or disabled. + A maximális kapcsolatok számának 0-nál nagyobbnak kell lennei, vagy kikapcsolva. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + A maximális kapcsolatok számának torrentenként 0-nál nagyobbnak kell lennei, vagy kikapcsolva. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + A maximális feltöltési szálaknak torrentenként 0-nál nagyobbnak kell lennei, vagy kikapcsolva. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Nem sikerült menteni a beállításokat. A qBittorrent valószínüleg nem elérhető. + + + + Language + Nyelv + + + + Downloaded + Is the file downloaded or not? + Letöltve + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + A bejövő kapcsolatokhoz használt portnak 1024 és 65535 közé kell esnie. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + A Web UI-hoz használt portnak 1024 és 65535 közé kell esnie. + + + + The Web UI username must be at least 3 characters long. + A Web UI felhasználói névnek legalább 3 karakter hosszúnak kell lennie. + + + + The Web UI password must be at least 3 characters long. + A Web UI felhasználói jelszónak legalább 3 karakter hosszúnak kell lennie. + + + + Save + Mentés + + + + qBittorrent client is not reachable + A qBittorent kliens nem elérhető + + + + HTTP Server + HTTP Szerver + + + + The following parameters are supported: + + + + + Torrent path + + + + + Torrent name + + + + + LegalNotice + + + Legal Notice + Jogi figyelmeztetés + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + A qBittorrent egy fájl megosztó program. Amikor futtatod, elérhetővé teszel tartalmakat mások számára a feltöltés révén. Kizárólag saját felelősségre ossz meg bármilyen tartalmat. + +Vélhetően tisztában vagy ezzel, így többé nem kapsz figyelmeztetést. + + + + Press %1 key to accept and continue... + Nyomd meg a %1 billentyűt az elfogadás és folytatáshoz... + + + + Legal notice + Jogi figyelmeztetés + + + + Cancel + Mégsem + + + + I Agree + Elfogadom + + + + LineEdit + + + Clear the text + Szöveg törlése + + + + MainWindow + + + &Edit + Sze&rkesztés + + + + &Tools + &Eszközök + + + + &File + &Fájl + + + + &Help + &Súgó + + + + &View + &Nézet + + + &Add File... + &Fájl Hozzáadása... + + + E&xit + &Kilépés + + + + &Options... + Beállítás&ok... + + + + &About + &Névjegy + + + + &Pause + &Szünet + + + + &Delete + &Törlés + + + + P&ause All + Összes le&állítása + + + + &Resume + &Folytatás + + + + &Add torrent file... + Torrent hozzá&adása... + + + + + Exit + Kilépés + + + + R&esume All + Összes &folytatása + + + + Visit &Website + Irány a &weboldal + + + Add &URL... + &URL hozzáadása... + + + + Torrent &creator + Torrent &készítő + + + + Report a &bug + &Hibajelentés + + + + Set upload limit... + Feltöltési korlát megadása... + + + + Set download limit... + Letöltési korlát megadása... + + + + &Documentation + &Dokumentáció + + + + Set global download limit... + Letöltési sebességkorlát... + + + + Set global upload limit... + Feltöltési sebességkorlát... + + + + Exit qBittorrent + qBittorrent bezárása + + + + Suspend system + Számítógép felfüggesztése + + + + Shutdown system + Számítógép leállítása + + + + Disabled + Kikapcsolva + + + &Log viewer... + &Eseménynapló... + + + Log viewer + Eseménynapló + + + Shutdown computer when downloads complete + Számbítógép leállítása a letöltések végén + + + + + Lock qBittorrent + qBittorrent zárolása + + + + Ctrl+L + Ctrl+L + + + Shutdown qBittorrent when downloads complete + qBittorrent leállítása a letöltések végén + + + + Import existing torrent... + Létező torrent importálása... + + + + Import torrent... + Torrent importálása... + + + + Donate money + Adomány + + + + If you like qBittorrent, please donate! + Ha kedveled a qBittorrentet, kélek támogasd! + + + + Execution &Log + Folyamat nap&ló + + + + + Execution Log + Napló + + + + + Alternative speed limits + Alternatív sebességkorlát + + + + &RSS reader + &RSS olvasó + + + + Search &engine + &Keresőmotor + + + + Top &tool bar + Felső &eszköz panel + + + + Auto-Shutdown on downloads completion + Automatikus leállítás a letöltés végén + + + + Add &link to torrent... + &Link hozzáadása torrenthez... + + + + Display top tool bar + Eszközsor megjelenítése + + + + &Speed in title bar + &Sebesség a címsoron + + + + Show transfer speed in title bar + Sebesség megjelenítése a címsoron + + + Preview file + Minta fájl + + + Clear log + Napló kiürítése + + + + Decrease priority + Elsőbbség csökkentése + + + + Increase priority + Elsőbbség fokozása + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + Jelszó beállítása... + + + + Transfers + Átvitelek + + + + Torrent file association + Torrent fájl társítás + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + A qBittorrent nem az alapértelmezett .torrent vagy Magnet link kezelő alkalmazás. +Szeretnéd alapértelmezetté tenni? + + + + + + UI lock password + UI jelszó + + + + + + Please type the UI lock password: + Kérlek add meg az UI jelszavát: + + + + The password should contain at least 3 characters + A jelszó legalább három karaktert tartalmazzon + + + + Password update + Jelszó frissítés + + + + The UI lock password has been successfully updated + Az UI jelszó sikeresen frissítve + + + + RSS + RSS + + + + Search + Keresés + + + + Transfers (%1) + Átvitelek (%1) + + + + Download completion + Elkészült letöltés + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 letöltve. + + + + I/O Error + i.e: Input/Output Error + I/O Hiba + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + I/O hiba történt ennél a torrentnél %1. +Oka: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Letöltés ismételt megerősítése + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + A %1 torrent .torrent fájlokat is tartalmaz. Szeretnéd folytatni a letöltést? + + + + + Yes + Igen + + + + + No + Nem + + + + Never + Soha + + + + Url download error + Url letöltés hiba + + + + Couldn't download file at url: %1, reason: %2. + Nem sikerült letölteni url címről: %1, mert: %2. + + + + Global Upload Speed Limit + Teljes feltöltési sebesség korlát + + + + Global Download Speed Limit + Teljes letöltési sebesség korlát + + + + + Invalid password + Érvénytelen jelszó + + + + The password is invalid + A jelszó érvénytelen + + + + Exiting qBittorrent + qBittorrent bezárása + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Néhány átvitel még folyamatban van. +Bizotos, hogy bezárod a qBittorrentet? + + + + Always + Mindig + + + + Open Torrent Files + Megnyitás + + + + Torrent Files + Torrentek + + + + Options were saved successfully. + Beállítások sikeresen elmentve. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Letöltés: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Feltöltés: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Letöltés: %2/s, Feltöltés: %3/s) + + + + A newer version is available + Elérhető új verzió + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + A qBittorrent egy újabb verziója érhető el a Soruceforge oldalon. +Szeretnéd most frissíteni a %1 verzióra? + + + + Impossible to update qBittorrent + Frissítés sikertelen + + + + qBittorrent failed to update, reason: %1 + A qBittorrent frissítése meghiúsult, mert: %1 + + + + PeerAdditionDlg + + + Invalid IP + Érvénytelen IP + + + + The IP you provided is invalid. + A megadott IP cím nem hiteles. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + IP + + + + Connection + Kapcsolatok + + + + Client + i.e.: Client application + Kliens + + + + Progress + i.e: % downloaded + Folyamat + + + + Down Speed + i.e: Download speed + Letöltési sebesség + + + + Up Speed + i.e: Upload speed + Feltöltési sebesség + + + + Downloaded + i.e: total data downloaded + Letöltve + + + + Uploaded + i.e: total data uploaded + Feltöltve + + + + Add a new peer... + Új ügyfél hozzáadása... + + + + Copy IP + IP másolása + + + + Limit download rate... + Letöltési arány korlát... + + + + Limit upload rate... + Feltöltési arány korlát... + + + + Ban peer permanently + Ügyfél kitiltása végleg + + + + + Peer addition + Ügyfél hozzáadása + + + + The peer was added to this torrent. + Ügyfél hozzáadva ehhez a torrenthez. + + + + The peer could not be added to this torrent. + Az ügyfélt nem lehet hozzáadni ehhez a torenthez. + + + + Are you sure? -- qBittorrent + Egészen biztos? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Biztos vagy benne, hogy végleg kitiltod a kiválaszott ügyfelet? + + + + &Yes + &Igen + + + + &No + &Nem + + + + Manually banning peer %1... + Ügyfél kitiltva %1... + + + + Upload rate limiting + Feltöltési arány korlátozása + + + + Download rate limiting + Letöltési arány korlátozása + + + + Preferences + + UI + User Interface + Felület + + + + Downloads + Letöltések + + + + Connection + Kapcsolatok + + + + Speed + Sebesség + + + Bittorrent + Bittorrent + + + Proxy + Proxy + + + + Web UI + Webes felület + + + + Advanced + Speciális + + + Language: + Nyelv: + + + + (Requires restart) + (Újraindítást igényel) + + + Visual style: + Kinézet: + + + Transfer list + Átviteli lista + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Alternatív sorkiemelés használata + + + + + Start / Stop Torrent + Torrent elindítása / megállítása + + + + + No action + Semmitse + + + File system + Fájlrendszer + + + + Copy .torrent files to: + .torrent fájlok másolása ide: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + + + + Torrent queueing + Torrent korlátozások + + + + Maximum active downloads: + Aktív letöltések maximási száma: + + + + Maximum active uploads: + Maximális aktív feltöltés: + + + + Maximum active torrents: + Torrentek maximális száma: + + + + When adding a torrent + Torrent hozzáadása + + + + + Options + Tulajdonságok + + + Visual Appearance + Megjelenés + + + + Action on double-click + Dupla katt esetén + + + + Downloading torrents: + Letöltések: + + + Start / Stop + Indítás/Megállítás + + + + + Open destination folder + Letöltési könyvtár megnyitása + + + + Completed torrents: + Letöltött torrenteknél: + + + + Desktop + Asztal + + + + Show splash screen on start up + Indítókép megjelenítése + + + + Start qBittorrent minimized + qBittorrent indításai háttérben + + + Show qBittorrent icon in notification area + qBittorent ikon megjelenítése a panelen + + + Use monochrome system tray icon (requires restart) + Egyszínű panel ikon használata (újraindítást igényel) + + + + Minimize qBittorrent to notification area + qBittorrent panelre helyezése minimalizálásnál + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Panelre helyezés bezárásnál + + + + Tray icon style: + + + + + Normal + Átlagos + + + + Monochrome (Dark theme) + + + + + Monochrome (Light theme) + + + + + Ask for program exit confirmation + Megerősítés kérése kilépéskor + + + + User Interface Language: + + + + + Transfer List + + + + + Show qBittorrent in notification area + + + + + Power Management + Energia gazdálkodás + + + + Inhibit system sleep when torrents are active + Alvó üzemmód tiltása aktív torrenteknél + + + + Display torrent content and some options + Torrent részleteinek és az opciók megjelenítése + + + + Do not start the download automatically + The torrent will be added to download list in pause state + Automatikusan letöltés nélküli hozzádás a listához + + + + Hard Disk + + + + + Save files to location: + Letöltés helye: + + + + Append the label of the torrent to the save path + A címke hozzfűzése a letöltési könyvtár nevéhez + + + + Pre-allocate disk space for all files + Fájlok helyének lefoglalása előre + + + + Keep incomplete torrents in: + Átmeneti fájlok helye: + + + Append .!qB extension to incomplete files' names + .!qB kiterjesztés használata az átmeneti fájloknál + + + + Automatically add torrents from: + Torrentek hozzáadása a letöltésekhez innen: + + + + Add folder... + Könyvtár hozzáadása... + + + + Email notification upon download completion + E-mail értesítés a letöltés végén + + + + Destination email: + E-mail cím: + + + + SMTP server: + SMTP szerver: + + + + This server requires a secure connection (SSL) + + + + + Run an external program on torrent completion + Külső program indítása a letöltés végén + + + + Otherwise, the proxy server is only used for tracker connections + + + + + Use proxy for peer connections + + + + + Global Rate Limits + + + + + Apply rate limit to uTP connections + + + + + Apply rate limit to transport overhead + + + + + Alternative Global Rate Limits + + + + + Schedule the use of alternative rate limits + + + + + Use HTTPS instead of HTTP + + + + + Import SSL Certificate + + + + + Import SSL Key + + + + + Certificate: + + + + + Key: + + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + Update my dynamic domain name + + + + + Service: + + + + + Register + + + + + Domain name: + + + + Use %f to pass the torrent path in parameters + Use %f to pass the torrent path in parameters + + + + Use UPnP / NAT-PMP port forwarding from my router + UPnP / NAT-PMP port átirányítás használata a routeremről + + + Proxy server + Proxy szerver + + + + Reload the filter + Szűrő újratöltése + + + + Enable bandwidth management (uTP) + + + + + Privacy + Titkosítás + + + + Enable DHT (decentralized network) to find more peers + DHT engedélyezése, hogy több ügyfélt találjon + + + + Use a different port for DHT and BitTorrent + DHT és bittorrent eltérő port használ + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Ügyfélcsere használata a kompatibilis kliensekkel (µTorrent, Vuze, ...) + + + + Enable Peer Exchange (PeX) to find more peers + PeX (ügyfélcsere) engedélyezése, hogy többet találjon + + + + Enable Local Peer Discovery to find more peers + Local Peer Discovery engedélyezése, több ügyfél + + + + Encryption mode: + Titkosítás: + + + + Prefer encryption + Előnyben + + + + Require encryption + Megkövetel + + + + Disable encryption + Kikapcsolva + + + Share ratio limiting + Megosztási arány korlátok + + + + Seed torrents until their ratio reaches + Torrent megosztása eddig az arányig + + + + then + aztán + + + + Pause them + Leállítás + + + + Remove them + Eltávolítás + + + + Enable Web User Interface (Remote control) + Webes felület engedélyezése (Távoli elérés) + + + + Use UPnP / NAT-PMP to forward the port from my router + + + + + Bypass authentication for localhost + Hitelesítés mellőzése helyi gépen + + + Listening port + Port beállítása + + + + Port used for incoming connections: + Port a bejövő kapcsoaltokhoz: + + + + Random + Random + + + Enable UPnP port mapping + UPnP port átirányítás engedélyezése + + + Enable NAT-PMP port mapping + NAT-PMP port átirányítás engedélyezése + + + Connections limit + Kapcsolatok korlátozása + + + + Global maximum number of connections: + Kapcsolatok maximális száma: + + + + Maximum number of connections per torrent: + Kapcsolatok maximális száma torrentenként: + + + + Maximum number of upload slots per torrent: + Feltöltési szálak száma torrentenként: + + + + + Upload: + Feltöltés: + + + + + Download: + Letöltések: + + + + + + + KiB/s + KiB/s + + + User Interface + Felhasználói felület + + + + BitTorrent + BitTorrent + + + Global speed limits + Teljes sebesség korlát + + + Alternative global speed limits + Alternatív teljees sebesség korlát + + + + to + time1 to time2 + eddig + + + + Every day + Minden nap + + + + Week days + Minden hét + + + + Week ends + Hétvékének + + + Bittorrent features + Bittorrent funkciók + + + Enable DHT network (decentralized) + DHT hálózati működés engedélyezése + + + Use a different port for DHT and Bittorrent + Használj külön porot DHT-hoz és torrenthez + + + + DHT port: + DHT port: + + + Enable Peer Exchange / PeX (requires restart) + Ügyfél csere (PeX) engedélyezése (újraindítást igényel) + + + Enable Local Peer Discovery + Local Peer Discovery engedélyezése + + + Enabled + Enged + + + Forced + Kényszerít + + + Disabled + Tilt + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP Kapcsolatok (trackerek, web seed, kereső motor) + + + + Host: + Host: + + + Peer Communications + Ügyfél kapcsolatok + + + + SOCKS4 + SOCKS4 + + + + Type: + Típus: + + + + + Behavior + Viselkedés + + + + Language + Nyelv + + + + Append .!qB extension to incomplete files + + + + + Remove folder + Könvtár eltávolítása + + + + Listening Port + + + + + Connections Limits + + + + + Proxy Server + + + + + IP Filtering + IP szűrés + + + Schedule the use of alternative speed limits + Alternatív sebesség korlát ütemezése + + + + from + from (time1 to time2) + Ettől + + + + When: + Ekkor: + + + + Look for peers on your local network + Ügyfél keresése a helyi hálózaton + + + Protocol encryption: + Titkosítási protokoll: + + + + (None) + (Nincs) + + + + HTTP + HTTP + + + + + Port: + Port: + + + + + + Authentication + Hitelesítés + + + + + + + Username: + Felhasználónév: + + + + + + + Password: + Jelszó: + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + Ip szűrő fájl helye (.dat, .p2p, .p2b): + + + + Torrent Queueing + + + + + Share Ratio Limiting + + + + HTTP Server + HTTP Szerver + + + + PreviewSelect + + + Name + Név + + + + Size + Méret + + + + Progress + Állapot + + + + + + Preview impossible + Bemutató hiba + + + + + + Sorry, we can't preview this file + Nincs előzetes az ilyen fájlhoz. Bocs + + + + ProgramUpdater + + Could not create the file %1 + A %1 fájl létrehozása sikertelen + + + Failed to download the update at %1 + %1 is an URL + Frissítés letöltése sikertelen a %1 címről + + + + PropListDelegate + + + Not downloaded + Mellőzve + + + + + Normal + Normal (priority) + Átlagos + + + + + High + High (priority) + Magas + + + + Mixed + Mixed (priorities + Kevert + + + + + Maximum + Maximum (priority) + Maximális + + + + PropTabBar + + + General + Általános + + + + Trackers + Trackerek + + + + Peers + Ügyfelek + + + + HTTP Sources + HTTP források + + + + Content + Tartalom + + + URL Seeds + URL Seed + + + Files + Fájlok + + + + PropertiesWidget + + + Save path: + Mentés helye: + + + + Torrent hash: + Torrent hash: + + + + Comment: + Megjegyzés: + + + + Share ratio: + Megosztási arány: + + + + + Downloaded: + Letöltve: + + + + Availability: + Elérhető: + + + + Transfer + Átvitel + + + + Uploaded: + Feltöltve: + + + + Wasted: + Elvetve: + + + + Time active: + Time (duration) the torrent is active (not paused) + Akív idő: + + + + Pieces size: + Szelet mérete: + + + + Torrent content: + Torrent tartalma: + + + + Select All + Összes kiválasztása + + + + Select None + Egyiket sem + + + + + Do not download + Mellőzés + + + + UP limit: + Feltöltési korlát: + + + + DL limit: + Letöltési korlát: + + + Time elapsed: + Eltelt idő: + + + + Connections: + Kapcsolatok: + + + + Reannounce in: + Újra kapcsolódás: + + + + Information + Információ + + + + Created on: + Készítés ideje: + + + General + Általános + + + Trackers + Trackerek + + + Peers + Ügyfelek + + + URL seeds + URL seed + + + Files + Fájlok + + + + Priority + Elsőbbség + + + + Normal + Átlagos + + + + Maximum + Maximális + + + + High + Magas + + + + + this session + ezen folyamat + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Feltöltési idő: %1 + + + + %1 max + e.g. 10 max + %1 max + + + + + I/O Error + I/O Hiba + + + + This file does not exist yet. + A fájl még nem létezik. + + + + This folder does not exist yet. + A könyvtár még nem létezik. + + + + Rename... + Átnevezés... + + + + Rename the file + Fájl átnevezése + + + + New name: + Új név: + + + + + The file could not be renamed + A fájlt nem lehet átnevezni + + + + This file name contains forbidden characters, please choose a different one. + Ez a név tiltott karaktereket tartalmaz, kérlek válassz másik nevet. + + + + + This name is already in use in this folder. Please use a different name. + Ilyen fájl már van a könyvtárban. Kérlek válassz másik nevet. + + + + The folder could not be renamed + A könyvtárat nem lehet átnevezni + + + + New url seed + New HTTP source + Új url forrás + + + + New url seed: + Új url seed: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Már letöltés alatt ez az url forrás. + + + + + Choose save path + Mentés helye + + + Save path creation error + Járhatatlan ösvény + + + Could not create the save path + Nem sikerült létrehozni a letöltési könyvtárat. (Írásvédett?) + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 elérte a megengedett arányt. + + + + Removing torrent %1... + Torrent eltávolítása %1... + + + + Pausing torrent %1... + Torrent leállítása %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent ezen a porton figyel: TCP/%1 + + + UPnP support [ON] + UPnP támogatás [ON] + + + UPnP support [OFF] + UPnP támogatás [OFF] + + + NAT-PMP support [ON] + NAT-PMP támogatás [ON] + + + NAT-PMP support [OFF] + NAT-PMP támogatás [OFF] + + + + HTTP user agent is %1 + HTTP user agent %1 + + + Using a disk cache size of %1 MiB + Lemez gyorsítótár: %1 MiB + + + + DHT support [ON], port: UDP/%1 + DHT támogatás [ON], port: UDP/%1 + + + + + DHT support [OFF] + DHT funkció [OFF] + + + + PeX support [ON] + PeX [ON] + + + + PeX support [OFF] + PeX támogatás [OFF] + + + + Restart is required to toggle PeX support + A PeX támogatás bekapcsolása újraindítást igényel + + + Local Peer Discovery [ON] + Local Peer Discovery [ON] + + + + Local Peer Discovery support [OFF] + Local Peer Discovery támogatás [OFF] + + + + Encryption support [ON] + Titkosítás [ON] + + + + Encryption support [FORCED] + Titkosítás [KÉNYSZERÍTVE] + + + + Encryption support [OFF] + Titkosítás [OFF] + + + + Embedded Tracker [ON] + Beágyazott tracker [ON] + + + + Failed to start the embedded tracker! + Beágyazott tracker indítása sikertelen! + + + + Embedded Tracker [OFF] + Beágyazott tracker [OFF] + + + + The Web UI is listening on port %1 + A Web UI ezen a porton figyel: %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Webes felület hiba - port használata sikertelen: %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' eltávolítva az átviteli listáról és a merevlemezről. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' eltávolítva az átviteli listáról. + + + + '%1' is not a valid magnet URI. + '%1' nem hiteles magnet URI. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' már letöltés alatt. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' visszaállítva. (folytatás) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' felvéve a letöltési listára. + + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP támogatás [ON] + + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP támogatás [OFF] + + + + Reporting IP address %1 to trackers... + %1 IP cím jelentése a trackernek... + + + + Local Peer Discovery support [ON] + Local Peer Discovery [ON] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Megfejthetetlen torrent: '%1' + + + + This file is either corrupted or this isn't a torrent. + Ez a fájl sérült, vagy nem is torrent. + + + + Error: The torrent %1 does not contain any file. + Hiba: A %1 torrent nem tartalmaz fájlokat. + + + + Note: new trackers were added to the existing torrent. + Megjegyzés: új tracker hozzáadva a torrenthez. + + + + Note: new URL seeds were added to the existing torrent. + Megjegyzés: új URL seed hozzáadva a torrenthez. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>letiltva IP szűrés miatt</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>kitiltva hibás adatküldés miatt</i> + + + + The network interface defined is invalid: %1 + A megadott hálózati csatoló hasznavehetetlen: %1 + + + + Trying any other network interface available instead. + Másik elérhető hálózati csatoló használata. + + + + Listening on IP address %1 on network interface %2... + IP cím: %1 hálózati csatoló: %2... + + + + Failed to listen on network interface %1 + A hálózati csatoló használata sikertelen: %1 + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Fájl ismételt letöltése %1 beágyazva a torrentbe %2 + + + + + Unable to decode %1 torrent file. + Megfejthetetlen torrent: %1. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + A számítógép alvó állapotba kerül, hacsak nem állítod le 15 másodpercen belül... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + A számítógép kikapcsol, hacsak nem állítod le 15 másodpercen belül... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + A qBittorent kilép, hacsak nem vonod vissza 15 másodpercen belül... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + IP szűrő sikeresen megnyitva: %1 elfogadva. + + + + Error: Failed to parse the provided IP filter. + Hiba: az IP szűrő megnyitása sikertelen. + + + + Torrent name: %1 + Torrent neve: %1 + + + + Torrent size: %1 + Torrent mérete: %1 + + + + Save path: %1 + Mentés helye: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + A torrent letöltve %1 alatt. + + + + Thank you for using qBittorrent. + Köszönjük, hogy a qBittorentet használod. + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 letöltése befejeződött + + + + An I/O error occured, '%1' paused. + I/O hiba történt, '%1' megállítva. + + + + + Reason: %1 + Mivel: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port felderítése sikertelen, hibaüzenet: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port felderítése sikeres, hibaüzenet: %1 + + + + File sizes mismatch for torrent %1, pausing it. + A fájl mérete nem megfelelő ennél a torrentnél: %1, leállítva. + + + + Fast resume data was rejected for torrent %1, checking again... + Hibás ellenőrző adat ennél a torrentnél: %1, újraellenőrzés... + + + + Url seed lookup failed for url: %1, message: %2 + Url forrás meghatározása sikertelen: %1, hibaüzenet: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Letöltés alatt: '%1', kis türelmet... + + + + RSS + + + Search + Keresés + + + + New subscription + Új feliratkozás + + + + + + Mark items read + Olvasottnak jelölés + + + + Update all + Összes frissítése + + + + RSS Downloader... + RSS letöltő... + + + + Settings... + Beállítások... + + + RSS feed downloader... + Letöltés RSS forrásból... + + + + New folder... + Új könyvtár... + + + + Manage cookies... + Süti kezelés... + + + Feed URL + URL forrás + + + + Rename... + Átnevezés... + + + + + Update + Frissítés + + + RSS feeds + RSS források + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(dupla katt a letöltéshez)</span></p></body></html> + + + Article title + Cikk címe + + + + New subscription... + Új feliratkozás... + + + + + Update all feeds + Összes forrás frissítése + + + + + Delete + Törlés + + + + Rename + Átnevezés + + + + Download torrent + Torrent letöltése + + + + Open news URL + Új URL megnyitása + + + + Copy feed URL + URL forrás másolása + + + + Refresh RSS streams + RSS csatornák ellenőrzése + + + + RSSImp + + + Please type a rss stream url + Kérlek add meg a csatorna url címét + + + + Stream URL: + Csatorna címe: + + + + + Are you sure? -- qBittorrent + Egészen biztos? -- qBittorrent + + + + + &Yes + &Igen + + + + + &No + &Nem + + + + Please choose a folder name + Válassz könyvtár nevet + + + + Folder name: + Könyvtár név: + + + + New folder + Új könyvtár + + + + Overwrite attempt + Felülírási kísérlet + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Nem lehet felülírni: %1. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Ez a hírcsatorna már felvéve. + + + + Are you sure you want to delete these elements from the list? + Egészen biztos, hogy törlöd ezeket az elemet a listáról? + + + + Are you sure you want to delete this element from the list? + Egészen biztos, hogy törlöd ezt az elemet a listáról? + + + + Please choose a new name for this RSS feed + Válassz új nevet az RSS csatornának + + + + New feed name: + Új forrás neve: + + + + Name already in use + A név már foglalt + + + + This name is already used by another item, please choose another one. + Ez a név már foglalt, kérlek válassz másikat. + + + + Date: + Dátum: + + + + Author: + Szerző: + + + + Unread + Olvasatlan + + + + RssArticle + + No description available + Nem található leírás + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Automatikus letöltése %1 torrentnek a %2 RSS forrásból... + + + + RssItem + + No description available + Nem található leírás + + + + RssSettings + + RSS Reader Settings + RSS olvasó beállításai + + + RSS feeds refresh interval: + RSS csatornák firssítésének időköze: + + + minutes + perc + + + Maximum number of articles per feed: + Hírek maximális száma csatornánként: + + + + RssSettingsDlg + + + RSS Reader Settings + RSS olvasó beállításai + + + + RSS feeds refresh interval: + RSS csatornák firssítésének időköze: + + + + minutes + perc + + + + Maximum number of articles per feed: + Hírek maximális száma csatornánként: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Automatikus letöltése %1 torrentnek a %2 RSS forrásból... + + + + ScanFoldersModel + + + Watched Folder + Megfigyelt könyvtár + + + + Download here + Letöltés ide + + + + SearchCategories + + + All categories + Összes kategória + + + + Movies + Filmek + + + + TV shows + TV műsorok + + + + Music + Zene + + + + Games + Játék + + + + Anime + Anime + + + + Software + Szoftver + + + + Pictures + Képek + + + + Books + Könyvek + + + + SearchEngine + + + Empty search pattern + Hiányzó kulcsszó + + + + Please type a search pattern first + Kérlek adj meg kulcsszót a kereséshez + + + + + Results + Eredmény + + + + Searching... + Keresés... + + + + Cut + Kivágás + + + + Copy + Másolás + + + + Paste + Beillesztés + + + + Clear field + Mező törlése + + + + Clear completion history + Előzmények törlése + + + + Confirmation + Megerősítés + + + + Are you sure you want to clear the history? + Bizotosan törlöd az előzményeket? + + + + + + Search + Keresés + + + + Missing Python Interpreter + Hiányzó Python bővítmény + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + A kereső használatához Python 2.x szükséges, de úgy tűnik nincs telepítve. +Szeretnéd most telepíteni? + + + + Search Engine + Keresőmotor + + + + + Search has finished + A keresés befejeződött + + + + An error occured during search... + Hiba a keresés közben... + + + + + Search aborted + Keresés félbeszakítva + + + + Download error + Letöltési hiba + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + A Python telepítőt nem sikerült letölteni, mivel: %1. +Kérlek telepítsd manuálisan. + + + + Search returned no results + Eredménytelen keresés + + + + Results + i.e: Search results + Találat + + + + + Unknown + Ismeretlen + + + + SearchTab + + + Name + i.e: file name + Név + + + + Size + i.e: file size + Méret + + + + Seeders + i.e: Number of full sources + Feltöltők + + + + Leechers + i.e: Number of partial sources + Letöltők + + + + Search engine + Kereső oldal + + + + ShutdownConfirmDlg + + + Shutdown confirmation + Leállítás megerősítése + + + + SpeedLimitDialog + + + KiB/s + KiB/s + + + + StatusBar + + + + Connection status: + Kapcsolat állapota: + + + + + No direct connections. This may indicate network configuration problems. + Nincsenek kapcsolatok. Ez lehet hálózat beállítási hiba miatt is. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + D: %1 B/s - T: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + U: %1 B/s - T: %2 + + + + + DHT: %1 nodes + DHT: %1 csomó + + + + qBittorrent needs to be restarted + qBittorrent újraindítást igényel + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + A qBittorrent frissült új verzióra. Most újraindítást igényel a változások életbe lépéséhez. + + + + + Connection Status: + A kapcsolat állapota: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Offline: ezt leggyakrabban az okozza, hogy a qBittorrent nem tudja használni a bejövő kapcsolatokhoz megadott portot. + + + + Online + Online + + + + + %1/s + Per second + %1/mp + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - T: %2 + + + + Click to switch to alternative speed limits + Alternatív sebesség korlát bekapcsolásához kattints ide + + + + Click to switch to regular speed limits + Általános sebesség korlát bekapcsolásához kattints ide + + + Click to disable alternative speed limits + Alternatív sebesség korlátok kikapcsolásához kattints ide + + + Click to enable alternative speed limits + Alternatív sebesség korlátok engedélyezéséhez kattints ide + + + + Global Download Speed Limit + Teljes letöltési sebesség korlát + + + + Global Upload Speed Limit + Teljes feltöltési sebesség korlát + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Válassz egy könyvtárat a torrenthez + + + + Select a file to add to the torrent + Válassz fájlt(okat) a torrenthez + + + Please type an announce URL + Kérlek add meg a gazda címét (URL) + + + Announce URL: + Tracker URL + Gazda tracker (URL): + + + Please type a web seed url + Kérlek adj meg címet a web seedhez (url) + + + Web seed URL: + Web seed URL: + + + + No input path set + Nincs forrásmappa + + + + Please type an input path first + Kérlek adj meg forrásmappát + + + + Select destination torrent file + Torrent helye + + + + Torrent Files + Torrentek + + + + + + Torrent creation + Torrent létrehozása + + + + Torrent creation was unsuccessful, reason: %1 + Torrent készítése sikertelen:(, oka: %1 + + + + Created torrent file is invalid. It won't be added to download list. + Az elkészült torrent fájl hibás. Nem lesz felvéve a listára. + + + + Torrent was created successfully: + Torrent sikeresen elkészült:): + + + + TorrentFilesModel + + + Name + Név + + + + Size + Méret + + + + Progress + Állapot + + + + Priority + Elsőbbség + + + + TorrentImportDlg + + + Torrent Import + Torrent Import + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Ez a program segítségedre lesz a már letöltött torrentek importálásában a qBittorrentbe. + + + + Torrent file to import: + Importálandó torrent fájl: + + + + + ... + ... + + + + Content location: + Letöltés helye: + + + + Skip the data checking stage and start seeding immediately + Adatok ellenőrzésének kihagyása. Seed kezdése azonnal + + + + Import + Import + + + + Torrent file to import + Torrent fájl importálása + + + + Torrent files (*.torrent) + Torrent fájlok (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 fájlok + + + + Please provide the location of %1 + %1 is a file name + Kérlek add meg a %1 helyét + + + + Please point to the location of the torrent: %1 + Kérlek add meg a %1 helyét + + + + Invalid torrent file + Érvénytelen torrent fájl + + + + This is not a valid torrent file. + Ez nem egy használható torrent fáj. + + + + TorrentModel + + + Name + i.e: torrent name + Név + + + + Size + i.e: torrent size + Méret + + + + Done + % Done + Elkészült + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Állapot + + + + Seeds + i.e. full sources (often untranslated) + Feltöltő + + + + Peers + i.e. partial sources (often untranslated) + letöltő + + + + Down Speed + i.e: Download speed + Letöltési sebesség + + + + Up Speed + i.e: Upload speed + Feltöltési sebesség + + + + Ratio + Share ratio + Arány + + + + ETA + i.e: Estimated Time of Arrival / Time left + Idő + + + + Label + Címke + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Hozáadva + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Elkészült + + + + Tracker + Tracker + + + + Down Limit + i.e: Download limit + Letöltés limit + + + + Up Limit + i.e: Upload limit + Feltöltés limit + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Letöltött mennyiség + + + + Amount left + Amount of data left to download (e.g. in MB) + Hátrelévő mennyiség + + + + Time Active + Time (duration) the torrent is active (not paused) + Aktív idő + + + + TrackerList + + + URL + URL + + + + Status + Állapot + + + + Peers + Ügyfelek + + + + Message + Üzenet + + + + [DHT] + [DHT] + + + + [PeX] + [PeX] + + + + [LSD] + [LSD] + + + + + + + + Working + Kapcsolódva + + + + + + Disabled + Tilt + + + + This torrent is private + Ez egy privát torrent + + + + Updating... + Frissítés... + + + + + Not working + Nincs kapcsolódva + + + + + Not contacted yet + Még nem kapcsolódott + + + + Add a new tracker... + Új tracker hozzáadása... + + + + Remove tracker + Tracker eltávolítása + + + + Force reannounce + Kényszerített újraközlés + + + + TrackersAdditionDlg + + + Trackers addition dialog + Tracker hozzáadása + + + + List of trackers to add (one per line): + Trackerek listája (soronként egyet): + + + + µTorrent compatible list URL: + µTorrent kompatiblis URL lista: + + + + I/O Error + I/O Hiba + + + + Error while trying to open the downloaded file. + Hiba történt a letöltött fájl megnyitásakor. + + + + No change + Nincs változás + + + + No additional trackers were found. + További tracker nem található. + + + + Download error + Letöltési hiba + + + + The trackers list could not be downloaded, reason: %1 + A tracker listát nem sikerült letölteni, mivel: %1 + + + + TransferListDelegate + + + Downloading + Letöltés + + + + Paused + Leállítva + + + + Queued + i.e. torrent is queued + Sorban áll + + + + Seeding + Torrent is complete and in upload-only mode + Seed + + + + Stalled + Torrent is waiting for download to begin + Elakadt + + + + Checking + Torrent local data is being checked + Ellenőrzés + + + + /s + /second (.i.e per second) + /s + + + + KiB/s + KiB/second (.i.e per second) + KiB/mp + + + + Seeded for %1 + e.g. Seeded for 3m10s + Feltöltési idő: %1 + + + + TransferListFiltersWidget + + + + All + Összes + + + + + Downloading + Letöltés + + + + + Completed + Feltöltés + + + + + Paused + Leállítva + + + + + Active + Aktív + + + + + Inactive + Inaktív + + + + + All labels + Összes címke + + + + + Unlabeled + Jelöletlen + + + + Remove label + Címke eltávolítása + + + + Add label... + Címke hozzáadasa... + + + + Resume torrents + Torrentek folytatása + + + + Pause torrents + Torrentek megállítása + + + + Delete torrents + Torrentek törlése + + + + New Label + Új címke + + + + Label: + Címke: + + + + Invalid label name + Érvénytelen címke név + + + + Please don't use any special characters in the label name. + Kérlek ne használj speciális karaktereket a címke nevében. + + + + TransferListWidget + + Down Speed + i.e: Download speed + Letöltési sebesség + + + Up Speed + i.e: Upload speed + Feltöltési sebesség + + + ETA + i.e: Estimated Time of Arrival / Time left + Idő + + + + Column visibility + Oszlop megjelenítése + + + Name + i.e: torrent name + Név + + + Size + i.e: torrent size + Méret + + + Done + % Done + Elkészült + + + Status + Torrent status (e.g. downloading, seeding, paused) + Állapot + + + Seeds + i.e. full sources (often untranslated) + Seed + + + Peers + i.e. partial sources (often untranslated) + Ügyfelek + + + Ratio + Share ratio + Arány + + + + Label + Címke + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Hozáadva + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Elkészült + + + Down Limit + i.e: Download limit + Letöltés limit + + + Up Limit + i.e: Upload limit + Feltöltés limit + + + + Choose save path + Mentés helye + + + Save path creation error + Járhatatlan ösvény + + + Could not create the save path + Nem sikerült létrehozni a letöltési könyvtárat. (Írásvédett?) + + + + Torrent Download Speed Limiting + Torrent letöltési sebesség limit + + + + Torrent Upload Speed Limiting + Torrent feltöltési sebesség limit + + + + New Label + Új címke + + + + Label: + Címke: + + + + Invalid label name + Érvénytelen címke név + + + + Please don't use any special characters in the label name. + Kérlek ne használj speciális karaktereket a címke nevében. + + + + Rename + Átnevezés + + + + New name: + Új név: + + + + Resume + Resume/start the torrent + Folytatás + + + + Pause + Pause the torrent + Szünet + + + + Delete + Delete the torrent + Törlés + + + + Preview file... + Minta fájl... + + + + Limit share ratio... + Megosztási arány korlát... + + + + Limit upload rate... + Feltöltési arány limit... + + + + Limit download rate... + Letöltési arány limit... + + + + Priority + Elsőbbség + + + + Open destination folder + Célkönyvtár megnyitása + + + + Move up + i.e. move up in the queue + Feljebb + + + + Move down + i.e. Move down in the queue + Lejjebb + + + + Move to top + i.e. Move to top of the queue + Legfelülre + + + + Move to bottom + i.e. Move to bottom of the queue + Legalúlra + + + + Set location... + Hely megadása... + + + + Force recheck + Kényszerített ellenőrzés + + + + Copy magnet link + Magnet link másolása + + + + Super seeding mode + Szuper seed üzemmód + + + + Rename... + Átnevezés... + + + + Download in sequential order + Letöltés sorrendben + + + + Download first and last piece first + Első és utolsó szelet letöltése először + + + + New... + New label... + Új... + + + + Reset + Reset label + Visszaállítás + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Torrent fel/letöltés arány korlátozás + + + + Use global ratio limit + Teljes arány limit használata + + + + + + buttonGroup + buttonGroup + + + + Set no ratio limit + Nincs arány limit + + + + Set ratio limit to + Arány korlát beállítása + + + + UsageDisplay + + + Usage: + Használat: + + + + displays program version + program verzió megjelenítése + + + + disable splash screen + induló képernyő letiltása + + + + displays this help message + ezen súgó oldal megjelenítése + + + + changes the webui port (current: %1) + webui port megváltozatása (aktuális: %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [fájl vagy url]: torrent letöltése felhasználói engedély esetén (opcionális) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Külön köszönet illeti a fordítókat, önkéntes munkájukért: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Amennyiben szeretnéd lefordítani (mondjuk már le van) a qBittorrentet, kérlek értesíts. + + + + addPeerDialog + + + Peer addition + Ügyfél hozzáadása + + + + IP + IP + + + + Port + Port + + + + addTorrentDialog + + + Torrent addition dialog + Torrent hozzáadása + + + + Save path: + Mentés helye: + + + + ... + ... + + + + Torrent size: + Torrent mérete: + + + + + Unknown + Ismeretlen + + + + Free disk space: + Szabad hely: + + + + Label: + Címke: + + + + Torrent content: + Torrent tartalma: + + + + Select All + Összes kiválasztása + + + + Select None + Egyiket sem + + + + Download in sequential order (slower but good for previewing) + Letöltés sorrendben (lassabb, de előnézethez ideális) + + + + Skip file checking and start seeding immediately + Fájl ellenőrzés kihagyása, és letöltés indítása tüstént + + + + + Do not download + Mellőzés + + + + Add to download list in paused state + Letöltés nélkül add a listához + + + + Add + Mehet + + + + Cancel + Mégse + + + + Normal + Átlagos + + + + High + Magas + + + + Maximum + Maximális + + + + authentication + + + + Tracker authentication + Tracker hitelesítés + + + + Tracker: + Tracker: + + + + Login + Belépés + + + + Username: + Felhasználónév: + + + + Password: + Jelszó: + + + + Log in + Bejelentkezés + + + + Cancel + Mégse + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Törlés megerősítése - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Egészen biztos, hogy törlöd az átviteli listáról? + + + + Remember choice + Emlékeztető + + + + Also delete the files on the hard disk + Fájlok törlése a merevlemezről is + + + + createTorrentDialog + + + Cancel + Mégsem + + + + Torrent Creation Tool + Torrent készítő + + + + Torrent file creation + Torrent létrehozása + + + Announce urls (trackers): + Gazda tracker (url): + + + Comment (optional): + Megjegyzés (esetleges): + + + Web seeds urls (optional): + Web seeds címek (esetleges): + + + + File or folder to add to the torrent: + Fájl vagy könyvtár. A torrent tartalma: + + + + Add file + Fájl hozzáadása + + + + Add folder + Könyvtár hozzáadása + + + + Tracker URLs: + Tracker URL: + + + + Web seeds urls: + Web seed url: + + + + Comment: + Megjegyzés: + + + + Piece size: + Szelet mérete: + + + + 32 KiB + 32 KiB + + + + 64 KiB + 64 KiB + + + + 128 KiB + 128 KiB + + + + 256 KiB + 256 KiB + + + + 512 KiB + 512 KiB + + + + 1 MiB + 1 MiB + + + + 2 MiB + 2 MiB + + + + 4 MiB + 4 MiB + + + + Auto + Auto + + + + Private (won't be distributed on DHT network if enabled) + Zárt (nem jelenik meg a DHT hálózaton) + + + + Start seeding after creation + Megosztás létrehozás után + + + + Create and save... + Létrehozás és mentés... + + + + Progress: + Folyamat: + + + + createtorrent + + Select destination torrent file + Torrent helye + + + Torrent Files + Torrentek + + + No input path set + Nincs forrásmappa + + + Please type an input path first + Kérlek adj meg forrásmappát + + + Torrent creation + Torrent létrehozása + + + Torrent was created successfully: + Torrent sikeresen elkészült:): + + + Select a folder to add to the torrent + Válassz egy könyvtárat a torrenthez + + + Please type an announce URL + Kérlek add meg a gazda címét (URL) + + + Torrent creation was unsuccessful, reason: %1 + Torrent készítése sikertelen:(, oka: %1 + + + Announce URL: + Tracker URL + Gazda tracker (URL): + + + Please type a web seed url + Kérlek adj meg címet a web seedhez (url) + + + Web seed URL: + Web seed URL: + + + Select a file to add to the torrent + Válassz fájlt(okat) a torrenthez + + + Created torrent file is invalid. It won't be added to download list. + Az elkészült torrent fájl hibás. Nem lesz felvéve a listára. + + + + downloadFromURL + + Download Torrents from URLs + Letöltés url címről + + + Only one URL per line + Soronként csak egy címet + + + + Add torrent links + Torrent link hozzáadása + + + + Both HTTP and Magnet links are supported + HTTP és Magnet link is támogatott + + + + Download + Letöltés + + + + Cancel + Mégsem + + + + Download from urls + Letöltés url címről + + + + No URL entered + Nem lett cím megadva + + + + Please type at least one URL. + Kérlek adj meg legalább egy url címet. + + + + downloadThread + + I/O Error + I/O Hiba + + + The remote host name was not found (invalid hostname) + A távoli hosztnév nem található (érvénytelen hosztnév) + + + The operation was canceled + A művelet megszakítva + + + The remote server closed the connection prematurely, before the entire reply was received and processed + A távoli szerver lezárta a kapcsolatot, a teljes válasz elküldése és feldolgozása előtt + + + The connection to the remote server timed out + Időtúllépés a szervehez való kapcsolódás közben + + + SSL/TLS handshake failed + SSL/TLS kapcsolódás sikertelen + + + The remote server refused the connection + A szerver visszautasította a kapcsolódást + + + The connection to the proxy server was refused + Kapcsolódás a proxy szerverhez sikertelen + + + The proxy server closed the connection prematurely + A proxy szerver idő előtt bontotta a kapcsolatot + + + The proxy host name was not found + Proxy szerver név ismeretlen + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Időtúllépés a proxy szerverhez való kapcsolódáskor, vagy a szerver nem továbbította a kérést időben + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + A proxy szerver hitelesítést kíván, de nem fogadja el a megadott igazolást + + + The access to the remote content was denied (401) + Csatlakozás a távoli tartalomhoz megtagadva (401) + + + The operation requested on the remote content is not permitted + A kért művelet nem engedélyezett a távoli eszközön + + + The remote content was not found at the server (404) + A távoli tartalom nem található a szeveren (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + A szerver hitelesítést kíván, de nem fogadja el a megadott igazolást + + + The Network Access API cannot honor the request because the protocol is not known + A Network Access API nem teljesíti a kérést, mivel a protokol ismeretlen + + + The requested operation is invalid for this protocol + A kért művelet ismeretlen ebben a protokollban + + + An unknown network-related error was detected + Ismeretlen hálózati hiba történt + + + An unknown proxy-related error was detected + Ismeretlen proxy hiba történt + + + An unknown error related to the remote content was detected + Ismeretlen hiba a távoli tartalomban + + + A breakdown in protocol was detected + Hiba a protokollban + + + Unknown error + Ismeretlen hiba + + + + engineSelect + + + Search plugins + Kereső modulok + + + + Installed search engines: + Telepített keresők: + + + + Name + Név + + + + Url + Url + + + + + Enabled + Státusz + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + További kereső modulok letölthetőek innen: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Új telepítése + + + + Check for updates + Frissítések ellenőrzése + + + + Close + Bezárás + + + Enable + Enged + + + Disable + Tilt + + + + Uninstall + Eltávolít + + + + engineSelectDlg + + + Uninstall warning + Figyelemeztetés + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Ezt a modult nem lehet eltávolítani, mivel a program része. + Csak azokat lehet, amiket saját kezüleg telepítettél. +Viszont kikapcsoltam a modult. + + + + Uninstall success + Sikeresen eltávolítva + + + + Select search plugins + Modul kiválasztása + + + + qBittorrent search plugins + qBittorrent kereső modulok + + + + + + + + Search plugin install + Kerső telepítése + + + + + + Yes + Bekapcsolva + + + + + + + No + Kikapcsolva + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + A %1 kereső modul egy újabb verziója már telepítve van. + + + + + + + Search plugin update + Kereső modul frissítése + + + + + Sorry, update server is temporarily unavailable. + A kiszolgálő jelenleg nem elérhető. Bocs. + + + + All your plugins are already up to date. + A legújabb kereső modulokat használod. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 keresőt nem lehet frissíteni, előző verzió megtartva. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 kereső modul telepítése sikertelen. + + + + All selected plugins were uninstalled successfully + Kereső modul(ok) sikeresen eltávolítva + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 kereső modul sikeresen frissítve. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1 kereső modul sikeresen telepítve. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Bocs, %1 kereső modul telepítése sikertelen. + + + + New search engine plugin URL + Új kereső modul címe + + + + URL: + URL: + + + + misc + + + B + bytes + B + + + + KiB + kibibytes (1024 bytes) + KiB + + + + MiB + mebibytes (1024 kibibytes) + MiB + + + + GiB + gibibytes (1024 mibibytes) + GiB + + + + TiB + tebibytes (1024 gibibytes) + TiB + + + + + + + + + Unknown + Ismeretlen + + + + %1h %2m + e.g: 3hours 5minutes + %1ó %2p + + + + %1d %2h + e.g: 2days 10hours + %1nap %2ó + + + + Unknown + Unknown (size) + Ismeretlen + + + + qBittorrent will shutdown the computer now because all downloads are complete. + A qBittorrent most leállítja a számítógépet, mert az összes letöltés elkészült. + + + + < 1m + < 1 minute + < 1perc + + + + %1m + e.g: 10minutes + %1perc + + + + options_imp + + + + + + Choose a save directory + Letöltési könyvtár megadása + + + + Add directory to scan + Könyvtár hozzáadása megfigyelésre + + + + Folder is already being watched. + A könyvtár már megfigyelés alatt. + + + + Folder does not exist. + A könyvtár nem létezik. + + + + Folder is not readable. + A könyvtár nem olvasható. + + + + Failure + Hiba + + + + Failed to add Scan Folder '%1': %2 + Hiba a könyvtár vizsgálata közben '%1': %2 + + + + + Choose export directory + Export könyvtár kiválasztása + + + + + Choose an ip filter file + Válassz egy ip szűrő fájlt + + + + + Filters + Szűrők + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + Megnyitási hiba + + + + Failed to parse the provided IP filter + A megadott IP szűrő megnyitása sikertelen + + + + Successfully refreshed + Sikeresen frissítve + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + Succesfully refreshed + Sikeresen frissítve + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + IP szűrő sikeresen megnyitva: %1 elfogadva. + + + + pluginSourceDlg + + + Plugin source + Modul telepítés + + + + Search plugin source: + Kereső modul helye: + + + + Local file + Helyi fájl + + + + Web link + Webcím + + + + preview + + + Preview selection + Minta + + + + File preview + Előzetes + + + + The following files support previewing, <br>please select one of them: + Minta megtekinthető az alábbi fájloknál, <br>válassz egyet: + + + + Preview + Előzetes + + + + Cancel + Mégsem + + + + previewSelect + + Preview impossible + Bemutató hiba + + + Sorry, we can't preview this file + Nincs előzetes az ilyen fájlhoz. Bocs + + + Name + Név + + + Size + Méret + + + Progress + Folyamat + + + + search_engine + + + + Search + Keresés + + + + Status: + Állapot: + + + + Stopped + Megállítva + + + + Download + Letöltés + + + + Go to description page + Adatlap megnyitása + + + + Search engines... + Keresők... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + Hasznavehetetlen torrent fájl: + + + + Unable to decode magnet link: + Magnet link dekódolása sikertelen: + + + + Magnet Link + Magnet Link + + + + Rename... + Átnevezés... + + + + Rename the file + Fájl átnevezése + + + + New name: + Új név: + + + + + The file could not be renamed + A fájlt nem lehet átnevezni + + + + This file name contains forbidden characters, please choose a different one. + Ez a név tiltott karaktereket tartalmaz, kérlek válassz másik nevet. + + + + + This name is already in use in this folder. Please use a different name. + Ilyen fájl már van a könyvtárban. Kérlek válassz másik nevet. + + + + The folder could not be renamed + A könyvtárat nem lehet átnevezni + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 hely marad letöltés után) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 hely hiányzik a letöltéshez) + + + + + + Choose save path + Mentés helye + + + + Empty save path + Mentés helye hiányos + + + + Please enter a save path + Kérlek add meg a mentés helyét + + + + Save path creation error + Járhatatlan ösvény + + + + Could not create the save path + Nem sikerült létrehozni a letöltési könyvtárat. (Írásvédett?) + + + + Invalid label name + Érvénytelen címke név + + + + Please don't use any special characters in the label name. + Kérlek ne használj speciális karaktereket a címke nevében. + + + + Seeding mode error + Seed mód hiba + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Ellenőrzés kihagyását kérted. Viszont a megadott helyen nincsenek a megadott fájlok. Kapcsold ki ezt a funkciót, vagy adj meg másik letöltési helyet. + + + + Invalid file selection + Választás hiánya + + + + You must select at least one file in the torrent + Legalább egy fájlt ki kell választanod + + + + Priority + Elsőbbség + + + diff --git a/src/lang/qbittorrent_hy.qm b/src/lang/qbittorrent_hy.qm new file mode 100644 index 0000000000000000000000000000000000000000..e34328f03a661f10c7acc8c52a24828c1be09d1c GIT binary patch literal 114609 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 literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_hy.ts b/src/lang/qbittorrent_hy.ts new file mode 100644 index 000000000..9c4f7e64a --- /dev/null +++ b/src/lang/qbittorrent_hy.ts @@ -0,0 +1,5658 @@ + + + + + AboutDlg + + + About qBittorrent + qBittorrent-ի մասին + + + + About + Ծրագրի մասին + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Bittorrent ծրագիրը գրվել է C++-ով՝ հիմնված Qt4 toolkit-ի </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">և libtorrent-rasterbarվրա <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Վեբ կայքը.</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Սխալների կայքը.</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Ֆորումը.</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + Author + Հեղինակը + + + + Name: + Անունը. + + + + Country: + Երկիրը. + + + + E-mail: + էլ. հասցե. + + + + Christophe Dumez + Christophe Dumez + + + + France + Ֆրանսիա + + + + Translation + Թարգմանիչներ + + + + License + Լիցենզիան + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Bittorrent ծրագիրը գրվել է C++-ով՝ հիմնված Qt4 toolkit-ի </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">և libtorrent-rasterbarվրա <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Վեբ կայքը.</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Ֆորումը.</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC-ն.</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + chris@qbittorrent.org + chris@qbittorrent.org + + + + Thanks to + Շնորհակալ ենք + + + + AdvancedSettings + + Property + Առաջ-ը + + + Value + Նիշը + + + + Disk write cache size + Պնակը գրելու պահեստի չափը + + + + MiB + ՄԲ + + + + Outgoing ports (Min) [0: Disabled] + Ելքի դարպասներ (Նվազ) [0. Անջատված] + + + + Outgoing ports (Max) [0: Disabled] + Ելքի դարպասներ (Առավ) [0. Անջատված] + + + + Recheck torrents on completion + Ավարտելուց հետո ստուգել torrent-ները + + + + Transfer list refresh interval + Փոխանցումների ցանկի թարմացման դադարը + + + + ms + milliseconds + մվ + + + + Setting + Կարգավորում + + + + Value + Value set for this setting + Կարգավորման նշանակ-ը + + + + Resolve peer countries (GeoIP) + Որոշել peer-երի երկրները (GeoIP) + + + + Resolve peer host names + Որոշել peer-երի հոսթերի անունները + + + + Maximum number of half-open connections [0: Disabled] + Կիսաբաց միացումների առավ. քանակը [0. Անջատված] + + + + Strict super seeding + Որոշված գերփոխանցումը + + + + Network Interface (requires restart) + Ցանցի միջներեսը (պահանջում է վերագործարկում) + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + Ցանկացած միջներես + + + + IP Address to report to trackers (requires restart) + Ուղորդիչների հաշվետվության IP-ն (պահ. է վերագործարկում) + + + + Display program on-screen notifications + Ցուցադրել ծրագիրը էկրանի տեղեկացումներում + + + Display program notification balloons + Ցուցադրել ծրագրի տեղեկացումների պատուհանները + + + + Enable embedded tracker + Միացնել ուղղորդիչի արգելումը + + + + Embedded tracker port + Արգելված ուղղորդիչի դարպասը + + + + Check for software updates + Ստուգել ծրագրի թարմացումները + + + + Use system icon theme + Օգտ. համակարգային պատկերով թեման + + + + Confirm torrent deletion + Հաստատեք torrent-ի ջնջումը + + + + Ignore transfer limits on local network + Անտեսել փոխանցումների սահ-ները լոկալ ցանցի համար + + + Include TCP/IP overhead in transfer limits + Ներառել TCP/IP վերադիր՝ փոխանցումների սահ-երում + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Ինքնագործարկվող RSS բեռնում + + + + Enable the automated RSS downloader + Միացնել ինքնագործարկվող RSS բեռնումը + + + + Download rules + Բեռնման կանոնները + + + + Rule definition + Որոշել կանոնը + + + + Must contain: + Պետք է պարունակի. + + + + Must not contain: + Չպետք է պարունակի. + + + + Use regular expressions + Օգտ. կանոնավոր սահ-ներ + + + + Import... + Ներմուծել... + + + + Export... + Արտածել... + + + + ... + + + + + Assign label: + Ընտրեք նիշը. + + + + Save to a different directory + Պահպանել այլ տեղում + + + + Save to: + Պահպանել՝ + + + + Apply rule to feeds: + Կիրառել կանոնները ալիքներին. + + + + Matching RSS articles + Համապատասխան RSS-ի + + + + New rule name + Նոր կանոնի անունը + + + + Please type the name of the new download rule. + Նշեք կանոնի անունը։ + + + + + Rule name conflict + Այս անունը արդեն առկա է։ + + + + + A rule with this name already exists, please choose another name. + Այս անունով կանոն արդեն առկա է, ընտրեք այլ անուն։ + + + + Are you sure you want to remove the download rule named %1? + Ջնջե՞լ %1 անունով կանոնը։ + + + + Are you sure you want to remove the selected download rules? + Ջնջե՞լ ընտրված կանոնները։ + + + + Rule deletion confirmation + Հաստատեք ջնջումը + + + + Destination directory + Նշանակման թղթապանակը + + + + Invalid action + Սխալ գործողություն + + + + The list is empty, there is nothing to export. + Ցանկը դատարկ է, ոչինչ չկա արտածելու համար։ + + + + Where would you like to save the list? + Որտե՞ղ պահպանել ցանկը։ + + + + Rules list (*.rssrules) + Կանոնների ցանկը (*.rssrules) + + + + I/O Error + Ն/Ա սխալ + + + + Failed to create the destination file + Հնարավոր չէ ստեղծել նշանակման ֆայլը + + + + Please point to the RSS download rules file + Նշեք RSS բեռնման կանոնների ֆայլը + + + + Rules list (*.rssrules *.filters) + Կանոնների ցանկը (*.rssrules *.filters) + + + + Import Error + Ներմուծման սխալ + + + + Failed to import the selected rules file + Հնարավոր չէ ներմուծել ընտրված ֆայլը + + + + Add new rule... + Ավելացնել նոր կանոն... + + + + Delete rule + Ջնջել կանոնը + + + + Rename rule... + Անվանափոխել կանոնը... + + + + Delete selected rules + Ջնջել ընտրված կանոնները + + + + Rule renaming + Կանոնի անվանափոխում + + + + Please type the new rule name + Նշեք կանոնի անունը + + + + Regex mode: use Perl-like regular expressions + Regex եղանակ. օգտ. Perl՝ կանոնավոր սահ-ը + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Wildcard եղանակ. կարող եք օգտագործել <ul><li>? պարզ նշանների համար</li><li>* զրո և զրոյից բարձր</li><li>Բացատներ ԵՎ օպերատորը </li></ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Wildcard եղանակ. կարող եք օգտագործել <ul><li>? պարզ նշանների համար</li><li>* զրո և զրոյից բարձր</li><li>| Բացատներ ԿԱՄ օպերատորը </li></ul> + + + + ConsoleDlg + + qBittorrent log viewer + qBittorrent-ի մատյանի դիտում + + + General + Գլխավորը + + + Blocked IPs + Կողփված IP-ներ + + + + CookiesDlg + + + Cookies management + Cookie-ների կառավարում + + + + Key + As in Key/Value pair + Բանալին + + + + Value + As in Key/Value pair + Նշանակությունը + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Cookie-երի ընդհանուր բանալիներն են . '%1', '%2'։ +Մանրամասները վեբ դիտարկիչի կարգավորումներում։ + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + Ակտիվ DNS հաջողությամբ է թարմացվել։ + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Ակտիվ DNS-ի սխալ. Սպասարկիչը հասանելի չէ։ Կրկին կփորձի 30 րոպեից։ + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Ակտիվ DNS-ի սխալ. հոսթի անունը սխալ է։ + + + + Dynamic DNS error: Invalid username/password. + Ակտիվ DNS-ի սխալ. Ծածկանունը/ծածկագիրը սխալ են։ + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Ակտիվ DNS-ի սխալ. qBittorrent-ը արգելվել է սպասարկիչի կողմից, խնդրում ենք այս մասին հաղորդեք մեզ http://bugs.qbittorrent.org կայքում։ + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Ակտիվ DNS-ի սխալ. %1-ը վերադարձվել է սպասարկիչի կողմից, խնդրում ենք հաղորդել այսմասին http://bugs.qbittorrent.org կայքում։ + + + + Dynamic DNS error: Your username was blocked due to abuse. + Ակտիվ DNS-ի սխալ. Ձեր ծածկանունը արգելված է։ + + + + Dynamic DNS error: supplied domain name is invalid. + Ակտիվ DNS-ի սխալ. տիրույթի անունը սխալ է։ + + + + Dynamic DNS error: supplied username is too short. + Ակտիվ DNS-ի սխալ. ծածկանունը կար- է։ + + + + Dynamic DNS error: supplied password is too short. + Ակտիվ DNS-ի սխալ. ծածկագիրը կարճ է։ + + + + DownloadThread + + + + I/O Error + Սխալ + + + + The remote host name was not found (invalid hostname) + Հեռադիր հոսթի անունը չի գտնվել (հոսթի անունը սխալ է) + + + + The operation was canceled + Գործողությունը ընդհատվել է + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Հեռադիր սպասարկիչը փակել է միացումը՝ մինչ կստացվեր պատասխանը + + + + The connection to the remote server timed out + Հեռադիր սպասարկիչին միանալու ժ-ը լրացել է + + + + SSL/TLS handshake failed + SSL/TLS փոխլրացումը ձախողվեց + + + + The remote server refused the connection + Հեռադիր սպասարկիչը մերժել է միացումը + + + + The connection to the proxy server was refused + Միացումը միջնորդ սպասարկիչին մերժվել է + + + + The proxy server closed the connection prematurely + Միջնորդ սպասարկիչը փակել է միացումը + + + + The proxy host name was not found + Չի գտնվել միջնորդի հոսթի անունը + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Միջնորդին միանալու ժ-ը լրացել է, միջնորդը հարցմանը ժամանակին չի պատասխանել + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Միջնորդը պահանջում է ներկայացում + + + + The access to the remote content was denied (401) + +Մուտքը հեռադիր կառավարմանը փակ է (401) + + + + The operation requested on the remote content is not permitted + Գործողությունը, որը պահանջում է հեռադիր պարունակությունը, չի թույլատրվել + + + + The remote content was not found at the server (404) + Հեռադիր պարունակությունը չի գտնվել սպասարկիչում (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Հեռադիր սպասարկիչը պահանջում է ներկայացում + + + + The Network Access API cannot honor the request because the protocol is not known + Network Access API-ին չի կարողանում ստանալ հարցում, որովհետեև արձանագր. հայտնի չէ + + + + The requested operation is invalid for this protocol + Պահանջվող գործողությունը սխալ է այս արձանագր. համար + + + + An unknown network-related error was detected + Անհայտ սխալ + + + + An unknown proxy-related error was detected + Միջնորդի անհայտ սխալ + + + + An unknown error related to the remote content was detected + Հեռադիր պարունակության անհայտ սխալ + + + + A breakdown in protocol was detected + Անհաջողություն արձանագրությունում + + + + Unknown error + Անհայտ սխալ + + + + EventManager + + + + Working + Աշխատում է + + + + Updating... + Թարմացվում է... + + + + + Not working + Չի աշխատում + + + + + Not contacted yet + Դեռ չի կապնվել + + + + + this session + այս շրջանում + + + + + /s + /second (i.e. per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + Փոխանցվել է՝ %1 + + + + %1 max + e.g. 10 max + Առավ. %1 + + + + + %1/s + e.g. 120 KiB/s + %1/վ + + + + ExecutionLog + + + General + Գլխավորը + + + + Blocked IPs + Կողփված IP-ներ + + + + FeedListWidget + + + RSS feeds + RSS ալիքներ + + + + Unread + Չկարդացած + + + + HeadlessLoader + + + Information + Տեղեկություն + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Կառավարելու համար qBittorrent-ը մուտք գործեք Web UI՝ http://localhost:%1 հասցեով + + + + The Web UI administrator user name is: %1 + Web UI-ի Ադմինի ծածկագիրն է՝ %1 + + + + The Web UI administrator password is still the default one: %1 + Web UI-ի Ադմինի ծածկագիրը դեռ ծրագրայինն է՝ %1 + + + + This is a security risk, please consider changing your password from program preferences. + Սա անվտանգության խախտում է, դիտարկեք ծածկագրի փոփոխությունը ծրագրի կարգավորումներում։ + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + Ձեր IP հասցեն արգելվել է՝ մի շարք անհաջող ներկայացումներից հետո։ + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Բ. %1/վ - Ը. %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Փ. %1/վ - Ը. %2 + + + + HttpServer + + + File + Ֆայլ + + + + Edit + Խմբագրել + + + + Help + Օգնություն + + + Delete from HD + Ջնջել HD-ից + + + + Download Torrents from their URL or Magnet link + Բեռնել Torrent-ները իրենց հղումներից կամ Magnet հղումից + + + + Only one link per line + Մեկ հղում տողի համար + + + + Download local torrent + Բեռնել լոկալ torrent + + + + Torrent files were correctly added to download list. + Torrent ֆայլերը հաջողությամբ ավելացվել են բեռնումների ցանկին։ + + + + Point to torrent file + Ավելացնել torrent ֆայլին + + + + Download + Բեռնել + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Ջնջե՞լ ընտրված torrent-ները ցանկից և պնակից։ + + + + Download rate limit must be greater than 0 or disabled. + Բեռնման սահմանափակումը պետք է լինի կամ բարձր 0-ից կամ անջատված։ + + + + Upload rate limit must be greater than 0 or disabled. + Փոխանցման սահմանափակումը պետք է լինի կամ բարձր 0-ից կամ անջատված։ + + + + Maximum number of connections limit must be greater than 0 or disabled. + Միացումների առավ. քանակը պետք է լինի կամ բարձր 0-ից կամ անջատված։ + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Միացումների առավ. քանակը torrent-ի համար պետք է լինի կամ բարձր 0-ից կամ անջատված։ + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Փոխանցման սլոթների առավ. քանակը torrent-ի համար պետք է լինի կամ բարձր 0-ից կամ անջատված։ + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Հնարավոր չէ պահպանել ծրագրի կարգավորումները, qBittorrent-ը հնարավոր է անհասանելի է։ + + + + Language + Լեզուն + + + + Downloaded + Is the file downloaded or not? + Բեռնվել է + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Մտնող կապուղիների դարպասը պետք է լինի 1024-ից մինչև 65535։ + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Web UI-ի համար օգտագործվող դարպասը պետք է լինի 1024-ից մինչև 65535։ + + + + The Web UI username must be at least 3 characters long. + Web UI-ի օգտագործողի անունը պետք է պարունակի գոնե 3 նիշ։ + + + + The Web UI password must be at least 3 characters long. + Օգտագործողի ծածկագիրը պետք է պարունակի գոնե 3 նիշ։ + + + + Save + Պահպանել + + + + qBittorrent client is not reachable + qBittorrent ծրագիրը հասանելի չէ + + + + HTTP Server + HTTP սպասարկիչ + + + + The following parameters are supported: + Աջակցվում են՝ + + + + Torrent path + Torrent-ի ճ-ը + + + + Torrent name + Torrent-ի անունը + + + + LegalNotice + + + Legal Notice + Օգտագործման իրավունքը + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent-ը ֆայլերի տարածման ծրագիր է։ Երբ բացում եք torrent-ը, նրա տվյալները հասանելի կդառնան նաև մյուսների համար՝ այն փոխանցելու ճանապարհով։ Ցանկացած ֆայլ Դուք տարածում եք Ձեր պատասխանատվությամբ։ + +Հետագայում նման հարցում չի արվի։ + + + + Press %1 key to accept and continue... + Սեղմեք %1 կոճակը՝ համաձայնվելու և շարունակելու... + + + + Legal notice + Օգտագործման իրավունքը + + + + Cancel + Մերժել + + + + I Agree + Համաձայն եմ + + + + LineEdit + + + Clear the text + Մաքրել տեսքտ + + + + MainWindow + + + &Edit + &Խմբագրել + + + + &Tools + &Գործիքներ + + + + &File + &Ֆայլ + + + + &Help + &Օգնություն + + + + &View + &Դիտել + + + &Add File... + &Ավելացնել ֆայլ... + + + + &Options... + &Ընտրանքներ... + + + + &Resume + &Վերսկսել + + + + R&esume All + Վ&երսկսել բոլորը + + + Add &URL... + Ավելացնել &հղում... + + + + Torrent &creator + Ստեղծել &torrent + + + Log viewer + Դիտել մատյանը + + + + + Alternative speed limits + Արագ-ան այլընտրանքային սահ-ում + + + + Top &tool bar + Գործիքների &վահանակը վերևում + + + + Display top tool bar + Ցուցադրել գործիքների վահանակը + + + + &Speed in title bar + &Արագ-ը պատուհանի վերին մասում + + + + Show transfer speed in title bar + Ցուցադրել փոխանցումների արագ-ը անունների վահանակում + + + + &About + &Մասին + + + + Auto-Shutdown on downloads completion + Անջատել՝ բեռնումները ավարտելուց հետո + + + + &Add torrent file... + &Ավելացնել torrent ֆայլ… + + + + + Exit + Ելք + + + + &Pause + &Դադար + + + + &Delete + &Ջնջել + + + + Add &link to torrent... + Ավելացնել &torrent-ի հղումը… + + + + Import existing torrent... + Ներմուծել առկա torrent… + + + + P&ause All + Դ&ադարեցնել բոլորը + + + + Execution &Log + Բացառության &ցանկը + + + + + Execution Log + Բացառության ցանկը + + + + Exit qBittorrent + Ելք qBittorrent-ից + + + + Suspend system + Կանգնեցնել համակարգը + + + + Shutdown system + Անջատել համակարգիչը + + + + Disabled + Անջատված է + + + + Visit &Website + Ծրագրի &կայքը + + + Preview file + Նախն. դիտում + + + Clear log + Մաքրել մատյանը + + + + Report a &bug + Հաղորդել &սխալի մասին + + + + Set upload limit... + Նշել փոխանցման սահ-փակում... + + + + Set download limit... + Նշել բեռնման սահ-փակում... + + + + &Documentation + &Թղթաբանություն + + + + Set global download limit... + Նշել բեռնման գլոբալ սահ-փակում... + + + + Set global upload limit... + Նշել փոխանցման գլոբալ սահ-փակում... + + + &Log viewer... + &Դիտել մատյանը... + + + + &RSS reader + &RSS ալիքներ + + + + Search &engine + Փնտրման &տողը + + + Shutdown computer when downloads complete + Բեռնումները ավարտելուց հետո անջատել համակարգիչը + + + + + Lock qBittorrent + Փակել qBittorrent-ը + + + + Ctrl+L + Ctrl+L + + + Shutdown qBittorrent when downloads complete + Բեռնումները ավարտելուց հետո փակել qBittorrent-ը + + + + Import torrent... + Ներմուծել torrent... + + + + Donate money + Նվիրատվություն + + + + If you like qBittorrent, please donate! + Եթե qBittorrent-ը Ձեզ դուր եկավ, խնդրում ենք նվիրաբերել։ + + + + Decrease priority + Իջեցնել առաջ-ը + + + + Increase priority + Բարձրաց-ել առաջ-ը + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent + + + + Set the password... + Նշեք ծածկագիրը... + + + + Transfers + Փոխանցումներ + + + + Torrent file association + Torrent ֆայլի ասոցիացումներ + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent-ը torrent ֆայլերի կամ Magnet հղումների համար ասոցիացված ծրագիրը չէ։ +Ասոցիացնե՞լ այն տվյալ ֆայլերի համար։ + + + + + + UI lock password + Ծրագրի կողփման ծածկագիրը + + + + + + Please type the UI lock password: + Նշեք ծածկագիրը. + + + + The password should contain at least 3 characters + Ծածկագիրը պետք է պարունակի գոնե 3 նիշ + + + + Password update + Թարմացնել ծածկագիրը + + + + The UI lock password has been successfully updated + UI-ի կողփման ծածկագիրը հաջողությամբ թարմացվեց + + + + RSS + RSS + + + + Search + Փնտրել + + + + Transfers (%1) + Փոխանցումներ (%1) + + + + Download completion + Բեռնումը ավարտվում է + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1-ի բեռնումը ավարտվեց։ + + + + I/O Error + i.e: Input/Output Error + Ն/Ա սխալ + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Ն/Ա սխալ torrent-ի համար %1. + Պատճառը. %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Բեռնման հաստատում + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + %1 torrent-ը պարունակում է torrent ֆայլեր, ցանկանու՞մ եք շարունակել դրանց բեռնումը։ + + + + + Yes + Այո + + + + + No + Ոչ + + + + Never + Երբեք + + + + Url download error + Հղումից բեռնման սխալ + + + + Couldn't download file at url: %1, reason: %2. + Հնարավոր չէ բեռնել ֆայլը %1 հղումից, պատճառը՝ %2։ + + + + Global Upload Speed Limit + Փոխանցման արագ-ան գլոբալ սահ-փակումներ + + + + Global Download Speed Limit + Բեռնման արագ-ան գլոբալ սահ-փակումներ + + + + + Invalid password + Ծածկագիրը սխալ է + + + + The password is invalid + Ծածկագիրը սխալ է + + + + Exiting qBittorrent + Ելք qBittorrent-ից + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Այս պահին որոշ ֆայլեր փախանցվում են։ +Այնուհանդերձ դու՞րս գալ qBittorrent-ից։ + + + + Always + Միշտ + + + + Open Torrent Files + Բացել torrent ֆայլեր + + + + Torrent Files + Torrent ֆայլեր + + + + Options were saved successfully. + Ընտրանքները հաջողությամբ պահպանվեցին։ + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Բ-ն արագ-ը %1 Կբիթ/վ + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Փ-ն արագ-ը. %1 Կբիթ/վ + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Բ. %2/վ, Փ. %3/վ) + + + + A newer version is available + Հասանելի է նոր տարբերակը + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Sourceforge-ում հասանելի է qBittorrent-ի նոր տարբերակը։ +Թարմացնե՞լ qBittorrent-ը մինչև %1 տարբերակի։ + + + + Impossible to update qBittorrent + Հնարավոր չէ թարմացնել qBittorrent-ը + + + + qBittorrent failed to update, reason: %1 + qBittorrent-ի թարմացումը ձախողվեց, պատճառը՝ %1 + + + + PeerAdditionDlg + + + Invalid IP + Սխալ IP + + + + The IP you provided is invalid. + Ձեր նշած IP-ին սխալ է + + + + PeerListDelegate + + + /s + /second (i.e. per second) + + + + + PeerListWidget + + + IP + IP + + + + Connection + Միացումը + + + + Client + i.e.: Client application + Ծրագիրը + + + + Progress + i.e: % downloaded + Ընթացքը + + + + Down Speed + i.e: Download speed + Բեռնման արգ-ը + + + + Up Speed + i.e: Upload speed + Փոխանցման արգ-ը + + + + Downloaded + i.e: total data downloaded + Բեռնվել է + + + + Uploaded + i.e: total data uploaded + Փոխանցվել է + + + + Add a new peer... + Ավելացնել նոր peer… + + + + Copy IP + Պատճենել IP-ին + + + + Limit download rate... + Բեռնման սահ-ը… + + + + Limit upload rate... + Փոխանցման սահմանափակումը… + + + + Ban peer permanently + Արգելել peer-ը մեկընդմիշտ + + + + + Peer addition + Peer-ի լրացում + + + + The peer was added to this torrent. + Peer-ը ավելացվել է torrent-ին։ + + + + The peer could not be added to this torrent. + Peer-ը չի կարող ավելացվել այս torrent-ին։ + + + + Are you sure? -- qBittorrent + Համոզվա՞ծ եք -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Արգելե՞լ ընտրված peer-երը։ + + + + &Yes + &Այո + + + + &No + &Ոչ + + + + Manually banning peer %1... + %1 peer-երի ձեռադիր արգելում… + + + + Upload rate limiting + Փոխանցման սահ-ը + + + + Download rate limiting + Բեռնման սահ-ը + + + + Preferences + + UI + User Interface + Արտացոլումը + + + + Downloads + Բեռնումներ + + + + Connection + Միացումը + + + + Speed + Արագությունը + + + Bittorrent + Bittorrent + + + + Web UI + Web UI + + + + Advanced + Ընդլայնված + + + Language: + Լեզուն. + + + + (Requires restart) + (Պահանջվում է վերագործարկում) + + + Visual style: + Տեսքը. + + + Transfer list + Փոխանցումերի ցանկը + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Օգտ. այլ գույն + + + + + Start / Stop Torrent + Սկսել / Կանգնեցնել + + + + + No action + Չկա գործողություն + + + File system + Ֆայլային համակարգը + + + + Copy .torrent files to: + Պատճենել .torrent ֆայլերը՝ + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Աջակցվում են հետևյալ տեսակները. +<ul> +<li>%f: Torrent-ի ճ-ը</li> +<li>%n: Torrent-ի անունը</li> +</ul> + + + + Listening Port + Մտնող դարպասը + + + + Connections Limits + Միացումների սահ-ում + + + + Proxy Server + Միջնորդը + + + + Enable bandwidth management (uTP) + Միացնել սահմանափակումները (uTP) + + + + Enable Local Peer Discovery to find more peers + Միացնել Լոկալ Peer-երի բացահայտումը + + + + Encryption mode: + Կոդավորման եղանակը. + + + + Prefer encryption + Նախընտրելի կոդավորում + + + + Require encryption + Պահանջել կոդավորում + + + + Disable encryption + Անջատել կոդավորումը + + + Torrent queueing + Torrent-երի հերթը + + + + Maximum active downloads: + Առավելագ. ակտիվ բեռնումներ. + + + + Maximum active uploads: + Առավելագ. ակտիվ փոխանցումներ. + + + + Maximum active torrents: + Առավելագ. ակտիվ torrent-ներ. + + + + When adding a torrent + Երբ ավելացվում է torrent + + + + Display torrent content and some options + Ցուցադրել torrent-ի պարունակությունը և այլ ընտրանքներ + + + Listening port + Դարպասը + + + + Port used for incoming connections: + Մուտքային կապուղիների դարպասը. + + + + Random + Պատահական + + + Enable UPnP port mapping + Միացնել UPnP դարպասի պլան-ը + + + Enable NAT-PMP port mapping + Միացնել NAT-PMP դարպասի պլան-ը + + + Connections limit + Միացումների սահմանափակումներ + + + + Global maximum number of connections: + Կապուղիների առավ. քանակը + + + + Maximum number of connections per torrent: + Կապուղիների առավ. քանակը torrent-ի համար. + + + + Maximum number of upload slots per torrent: + Փոխանցումների սլոթների առավ. քանակը torrent-ի համար. + + + + + Upload: + Փոխանցում. + + + + + Download: + Բեռնում. + + + + + + + KiB/s + Կբիթ/վ + + + Global speed limits + Արագության սահմանափակումներ + + + + Remove folder + Ջնջել թղթապանակը + + + + + Behavior + Վարմունքը + + + + Language + Լեզուն + + + Alternative global speed limits + Արագության այլընտրանքային սահմանափակումներ + + + + to + time1 to time2 + մինչև + + + + Every day + Ամեն օր + + + + Week days + Շաբաթական + + + + Week ends + Հանգստյան օրեր + + + Bittorrent features + Bittorrent-ի հնարավորությունները + + + Enable DHT network (decentralized) + Միացնել DHT ցանցը + + + Use a different port for DHT and Bittorrent + Օգտագործել տարբեր դարպասներ DHT-ի և Bittorrent-ի համար + + + + DHT port: + DHT դարպասը. + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Փոխանակել peer-երը համատեղելի Bittorrent ծրագրերի միջև (µTorrent, Vuze, ...) + + + Enable Peer Exchange / PeX (requires restart) + ՄԻացնել Peer-երի փոխանակումը / PeX (պահանջվում է վերամեկնարկում) + + + Enable Local Peer Discovery + Միացնել լոկալ Peer-երի որոնումը + + + Enabled + Միացված է + + + Forced + Հարկադիր + + + Disabled + Անջատված է + + + + Host: + Հոսթը. + + + + SOCKS4 + SOCKS4 + + + + Type: + Տեսակը. + + + + + Options + Ընտրանքներ + + + Visual Appearance + Տեսողականացում + + + + Action on double-click + Գործ. կրկնակի սեղմամբ + + + + Downloading torrents: + Բեռնվում են torrent-ներ. + + + Start / Stop + Սկսել/Կանգնեցնել + + + + + Open destination folder + Բացել պարունակող թղթապանակը + + + + Completed torrents: + Ավարտված torrent-ներ. + + + + Desktop + Աշխատանքը + + + + Show splash screen on start up + Բացելիս ցուցադրել ծրագրի պատկերը + + + + Start qBittorrent minimized + Բացել qBittorrent-ը թաքնված վիճակում + + + Show qBittorrent icon in notification area + Ցուցադրել qBittorrent-ի պատկերը իրազեկման գոտում + + + Use monochrome system tray icon (requires restart) + Օգտ. անգույն պատկեր՝էկրանի ներքևում (պահ. է վերագործարկում) + + + + Minimize qBittorrent to notification area + Թաքցնել qBittorrent-ը իրազեկման գոտում + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + qBittorrent-ը փակելիս թաքցնել իրազեկման գոտում + + + + Tray icon style: + Էկրանի ներքևի պատկերի ոճը. + + + + Normal + Նորմալ + + + + Monochrome (Dark theme) + Միագույն (Մուգ շապիկ) + + + + Monochrome (Light theme) + Միագույն (Բաց շապիկ) + + + + Ask for program exit confirmation + Հարցնել ծրագիրը փակելիս + + + + User Interface Language: + Ծրագրի լեզուն. + + + + Transfer List + Ակտիվների ցանկը + + + + Show qBittorrent in notification area + Ցուցադրել qBittorrent-ը տեղեկացումների վահանակում + + + + Power Management + Սնուցման կառավարում + + + + Inhibit system sleep when torrents are active + Կանխել համակարգչի "քնեցումը", երբ կան ակտիվ torrent-ներ + + + + Do not start the download automatically + The torrent will be added to download list in pause state + Միանգամից չսկսել բեռնումները + + + + Hard Disk + Կոշտ պնակ + + + + Save files to location: + Պահպանել ֆայլերը՝ + + + + Append the label of the torrent to the save path + Torrent-ի նիշը պահպանելու ճանապարհին + + + + Pre-allocate disk space for all files + Բոլոր ֆայլերի համար առանձնացնել անհրաժեշտ չափով տեղ պնակի վրա + + + + Keep incomplete torrents in: + Պահել չբեռնված torrent-ները՝ + + + Append .!qB extension to incomplete files' names + Կցել .!qB ընդլայնումը անավարտ ֆայլերի անուններին + + + + Automatically add torrents from: + Միանգամից ավելացնել torrent-ները՝ + + + + Add folder... + Ավելացնել թղթապանակ... + + + + Email notification upon download completion + Բեռնումները ավարտելիս տեղեկացնել էլ. փոստով + + + + Destination email: + էլ. հասցեն. + + + + SMTP server: + SMTP սպասարկիչ. + + + + This server requires a secure connection (SSL) + Սպասարկիչը պահանջում է անվտանգ միացում (SSL) + + + + Run an external program on torrent completion + Torrent-ը բեռնելուց հետո բացել արտաքին ծրագրով + + + + Otherwise, the proxy server is only used for tracker connections + Այնուհանդերձ միջնորդը օգտ. է միայն ուղղորդիչներին միանալու համար + + + + Use proxy for peer connections + Օգտ. միջնորդը՝ peer միացումների համար + + + + Global Rate Limits + Սահմանափակումները + + + + Apply rate limit to uTP connections + Կիրառել սահ-փակում uTP-ի համար + + + + Apply rate limit to transport overhead + Կիրառել սահ-փակում գերազանցելու դեպքում + + + + Alternative Global Rate Limits + Այլընտրանքային սահմանափակումներ + + + + Schedule the use of alternative rate limits + Այլընտրանքային սահ-փակումների պլանավորում + + + + Use HTTPS instead of HTTP + Օգտ. HTTPS՝ HTTP-ի փոխարեն + + + + Import SSL Certificate + Ներմուծել SSL վավերագիր + + + + Import SSL Key + Ներմուծել SSL բանալի + + + + Certificate: + Վավերագիրը. + + + + Key: + Բանալին. + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Ինֆո վավերագրի մասին</a> + + + + Update my dynamic domain name + Թարմացնել ակտիվ տիրույթի անունը + + + + Service: + Սպասարկիչը. + + + + Register + Գրանցել + + + + Domain name: + Տիրույթի անունը. + + + Use %f to pass the torrent path in parameters + Օգտագործեք %f-ը՝ բաց թողնելու համար torrent-ի ճանապարհի ցուցիչը + + + + Use UPnP / NAT-PMP port forwarding from my router + Օգտագործել UPnP / NAT-PMP դարպասի փոխանցում ռոութերից + + + Proxy server + Միջնորդ սպասարկիչ + + + + IP Filtering + Ֆիլտրում IP-ով + + + + Reload the filter + Վերաբացել ֆիլտրը + + + Schedule the use of alternative speed limits + Նշեք արագության այլընտրանքային սահմանափակում + + + + from + from (time1 to time2) + Ժ. + + + + When: + Երբ. + + + + Privacy + Անվտանգություն + + + + Enable DHT (decentralized network) to find more peers + Միացնել DHT՝ լրացուցիչ peer-եր գտնելու համար + + + + Use a different port for DHT and BitTorrent + Օգտագործել այլ դարպաս՝ DHT-ի և BitTorrent-ի համար + + + + Enable Peer Exchange (PeX) to find more peers + Միացնել Peer-երի փոխանակումը (PeX)՝ լրացուցիչ peer-եր գտնելու համար + + + + Look for peers on your local network + Ձեր լոկալ ցանցի peer-երը + + + + Torrent Queueing + Torrent-ը հերթում է + + + + Share Ratio Limiting + Փոխանցման սահ-ներ + + + + Use UPnP / NAT-PMP to forward the port from my router + Օգտ. UPnP / NAT-PMP՝ ռոութերից փոխանցելու համար + + + + Bypass authentication for localhost + localhost-ի շրջանցիկ ներկայացում + + + Protocol encryption: + Արձանագրության գաղտնագրում + + + Share ratio limiting + Սահմանափակումներ + + + + Seed torrents until their ratio reaches + Փոխանցել torrent-ները մինչև սահ-ը կհասնի + + + + then + ապա + + + + Pause them + Դադարեցնել բոլորը + + + + Remove them + Ջնջել + + + + (None) + (Չկա) + + + User Interface + Տեսքը + + + + BitTorrent + BitTorrent + + + + HTTP + HTTP + + + + + Port: + Դարպասը. + + + + + + Authentication + Ներկայացում + + + + Append .!qB extension to incomplete files + Կցել .!qB ընդլայոնւմը անավարտ ֆայլերի համար + + + + + + + Username: + Օգտվողը. + + + + + + + Password: + Ծածկագիրը. + + + + Enable Web User Interface (Remote control) + Միացնել Web User Interface-ը (Հեռադիր կառավարում) + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + Ֆիլտրերի ճանապարհը (.dat, .p2p, .p2b). + + + HTTP Server + HTTP սպասարկիչ + + + + PreviewSelect + + + Name + Անունը + + + + Size + Չափը + + + + Progress + Ընթացքը + + + + + + Preview impossible + Դիտումը հնարավոր չէ + + + + + + Sorry, we can't preview this file + Հնարավոր չէ դիտել այս ֆայլը + + + + PropListDelegate + + + Not downloaded + Չի բեռնվելու + + + + + Normal + Normal (priority) + Նորմալ + + + + + High + High (priority) + Բարձր + + + + Mixed + Mixed (priorities + Խառը + + + + + Maximum + Maximum (priority) + Առավելագույն + + + + PropTabBar + + + General + Գլխավորը + + + + Trackers + Ուղղորդիչներ + + + + Peers + Peer-եր + + + + HTTP Sources + HTTP աղբյուրներ + + + + Content + Պարունակությունը + + + URL Seeds + Հղվող Seed-եր + + + Files + Ֆայլեր + + + + PropertiesWidget + + + Save path: + Պահպանելու ճանապարհը. + + + + Torrent hash: + Torrent-ի hash-ը. + + + + Share ratio: + Սահ-ը. + + + + + Downloaded: + Բեռնվել է. + + + + Availability: + Հասանելի է. + + + + Transfer + Փոխանցում + + + + Uploaded: + Փոխանցվել է. + + + + Wasted: + Վնասված. + + + + UP limit: + Փ. սահ-փակում. + + + + DL limit: + Բ. սահ-փակում. + + + Time elapsed: + Մնացել է ժ-կ. + + + + Connections: + Միացումներ. + + + + Time active: + Time (duration) the torrent is active (not paused) + Ակտիվ ժ-ը. + + + + Reannounce in: + Վերահայտարարել. + + + + Information + Տեղեկություն + + + + Created on: + Ստեղծվել է՝ + + + + Pieces size: + ՄԱսերի չափը. + + + + Comment: + Մեկնաբանություն. + + + + Torrent content: + Torrent-ի պարունակությունը. + + + + Select All + Ընտրել բոլորը + + + + Select None + Չընտրել ոչ մեկը + + + + Normal + Նորմալ + + + + High + Բարձր + + + + Maximum + Առավելագույնը + + + + + Do not download + Չբեռնել + + + + + this session + այս շրջանում + + + + + /s + /second (i.e. per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + Փոխանցվել է %1 + + + + %1 max + e.g. 10 max + Առավելագ. %1 + + + + + I/O Error + Ն/Ա սխալ + + + + This file does not exist yet. + Այս ֆայլը դեռևս գոյություն չունի։ + + + + This folder does not exist yet. + Այս թղթապանակը դեռևս գոյություն չունի։ + + + + Rename... + Անվանափոխել... + + + + Priority + Առաջնայնությունը + + + + Rename the file + Անվանափոխել + + + + New name: + Նոր անունը. + + + + + The file could not be renamed + Հնարավոր չէ անվանափոխել ֆայլը + + + + This file name contains forbidden characters, please choose a different one. + Ֆայլի անունը պարունակում է արգելված նշաններ, ընտրեք այլ անուն։ + + + + + This name is already in use in this folder. Please use a different name. + Այս անունը արդեն առկա է տվյալ թղթապանակում։ Նշեք այլ անուն։ + + + + The folder could not be renamed + Թղթապանակը հնարավոր չէ անվանափոխել + + + + New url seed + New HTTP source + Նոր հղման փոխանցում + + + + New url seed: + Նոր հղման փոխանցում. + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Այս հղումը արդեն առկա է ցանկում։ + + + + + Choose save path + Ընտրեք պահպանելու տեղը + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1-ի սահմանափակումը լրացել է։ + + + + Removing torrent %1... + Ջնջվում է %1 torrent-ը... + + + + Pausing torrent %1... + Դադարեցվում է %1 torrent-ը... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent-ը սահ. է TCP/%1 դարպասը + + + UPnP support [ON] + UPnP աջակցում [ՄԻԱՑ] + + + UPnP support [OFF] + UPnP աջակցում [ԱՆՋ] + + + NAT-PMP support [ON] + NAT-PMP աջակցում [ՄԻԱՑ] + + + NAT-PMP support [OFF] + NAT-PMP աջակցում [ԱՆՋ] + + + + HTTP user agent is %1 + HTTP օգտագործելու ծրագիրը՝ %1 + + + Using a disk cache size of %1 MiB + Օգտագործվում է պնակի պահեստի չափը՝ %1 Մբիթ + + + + DHT support [ON], port: UDP/%1 + DHT աջակցումը [ՄԻԱՑ], դարպասը. UDP/%1 + + + + + DHT support [OFF] + DHT աջակցում [ԱՆՋ] + + + + PeX support [ON] + PeX աջակցում [ՄԻԱՑ] + + + + PeX support [OFF] + PeX աջակցում [ԱՆՏ] + + + + Restart is required to toggle PeX support + Պահանջվում է վերագործարկում՝ փոխանջատելու համար PeX-ը + + + Local Peer Discovery [ON] + Լոկալ Peer-երի բացահայտում [ՄԻԱՑ] + + + + Local Peer Discovery support [OFF] + Լոկալ Peer-երի բացահայտման աջակցում [ԱՆՋ] + + + + Encryption support [ON] + Գաղտնագրման աջակցում [ՄԻԱՑ] + + + + Encryption support [FORCED] + Գաղտնագրման աջակցում [ՊԱՐՏ.] + + + + Encryption support [OFF] + Գաղտնագրման աջակցում [ԱՆՋ.] + + + + Embedded Tracker [ON] + Արգելված ուղղորդիչ [ՄԻԱՑ] + + + + Failed to start the embedded tracker! + Սխալ՝ արգելված ուղղորդիչը բացելիս։ + + + + Embedded Tracker [OFF] + Արգելված ուղղորդիչ [ԱՆՋ] + + + + The Web UI is listening on port %1 + Web UI-ին ստանում է %1 դարպասից + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Web User Interface-ի սխալ - Հնարավոր չէ պարդատրել Web UI-ին %1 դարպասը + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1'-ը ջնջվել է բեռնումների ցանկից և պնակից։ + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1'-ը ջնջվել է բեռնումների ցանկից։ + + + + '%1' is not a valid magnet URI. + '%1'-ը ճիշտ magnet հղում չէ։. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1'-ը արդեն առկա է ցանկում։ + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1'-ը վերսկսվել է։ + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1'-ը ավելացվել է բեռնումների ցանկին։ + + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP աջակցում [ՄԻԱՑ] + + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP աջակցում [ԱՆՋ] + + + + Reporting IP address %1 to trackers... + Հաղորդվում է %1 IP հասցեի մասին ուղորդիչին... + + + + Local Peer Discovery support [ON] + Լոկալ Peer-երի բացահայտման աջակցում [ՄԻԱՑ] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Հնարավոր չէ ապակոդավորել '%1' ֆայլը + + + + This file is either corrupted or this isn't a torrent. + Ֆայլը վնասված է կամ torrent չէ։ + + + + Error: The torrent %1 does not contain any file. + Սխալ. %1 torrent-ը չի պարունակում ֆայլեր։ + + + + Note: new trackers were added to the existing torrent. + Նշում. նոր ուղղորդիչները ավելացվել են ընթացիկ torrent-ում։ + + + + Note: new URL seeds were added to the existing torrent. + Նշում. նոր հղումները ավելացվել են ընթացիկ torrent-ում։ + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1-ը</font> <i>կողփվել է Ձեր IP ֆիլտրի կողմից</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>-ը արգելված է, քանզի հատվածները վնասված են</i> + + + + The network interface defined is invalid: %1 + Ցանցային միջներեսը սխալ է որոշվել. %1 + + + + Trying any other network interface available instead. + Հասանելի է այլ ցանցային միջներես։ + + + + Listening on IP address %1 on network interface %2... + Ստանում է %1 IP հասցեից՝ հետևյալ ցանցում՝ %2... + + + + Failed to listen on network interface %1 + Սխալ՝ %1 ցանցային միջներեսից ստանալիս + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + %1 ֆայլի ձեռադիր բեռնումը արգելված է %2 ֆայլում + + + + + Unable to decode %1 torrent file. + Հնարավոր չէ ապակոդավորել %1 torrent ֆայլը։ + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Այժմ համակարգիչը կանցնի "քուն" վիճակի՝ եթե իհարկե չկանգնեցնեք 15 վայրկյանի ընթացքում... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Այժմ համակարգիչը կանջատվի՝ եթե իհարկե չկանգնեցնեք 15 վայրկյանի ընթացքում... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent-ը կփակվի 15 վայրկյանից... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Հաջողությամբ կիրառվել է IP ֆիլտրը. %1 կանոններ կիրառվել են։ + + + + Error: Failed to parse the provided IP filter. + Սխալ՝ կապված IP ֆիլտրերի կիրառման հետ։ + + + + Torrent name: %1 + Torrent-ի անունը. %1 + + + + Torrent size: %1 + Torrent-ի չափը. %1 + + + + Save path: %1 + Պահպանելու տեղը. %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent-ը բեռնվել է %1ում։ + + + + Thank you for using qBittorrent. + Շնորհակալություն qBittorrent-ը օգտագործելու համար։ + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1-ի բեռնումը ավարտվեց + + + + An I/O error occured, '%1' paused. + Ն/Ա սխալ, '%1' դադարի մեջ է։ + + + + + Reason: %1 + Պատճառը. %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP. Դարպասի որոշումը ձախողվեց, հաղորդագրությունը՝ %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP. Դարպասի որոշումը հաջող էր, հաղորդագրությունը՝ %1 + + + + File sizes mismatch for torrent %1, pausing it. + Ֆայլի չափը չի համապատասխանում %1 torrent-ին, դադարեցվում է։ + + + + Fast resume data was rejected for torrent %1, checking again... + Վերսկսումը մերժվել է %1 torrent-ի համար, նորից է սկսվում... + + + + Url seed lookup failed for url: %1, message: %2 + Հղման փոխանցումը ձախողվեց %1 հղումների համար, հաղորդագրությունը՝ %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Բեռնվում է '%1'-ը, խնդրում ենք սպասել... + + + + RSS + + + Search + Փնտրում + + + + New subscription + Նոր բաժանորդագրում + + + + + + Mark items read + Նշել որպես կարդացված + + + + Update all + Թարմացնել բոլորը + + + + RSS Downloader... + RSS բեռնում... + + + + Settings... + Կարգավորումներ… + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrent-ներ.</span> <span style=" font-style:italic;">(կրկնակի սեղմեք՝ բեռնելու համար)</span></p></body></html> + + + Article title + Վերնագիրը + + + Feed URL + Ալիքի հղումը + + + + + Delete + Ջնջել + + + + Rename... + Անվանափոխել… + + + + Rename + Անվանափոխել + + + + + Update + Թարմացնել + + + + New subscription... + Նոր բաժանորդագրում… + + + + + Update all feeds + Թարմացնել բոլորը + + + + Download torrent + Բեռնել torrent-ը + + + + Open news URL + Բացել նորության հղումը + + + + Copy feed URL + Պատճենել ալիքի հղումը + + + + New folder... + Նոր թղթապանակ… + + + + Manage cookies... + Կառավարել cookie-ները… + + + + Refresh RSS streams + Թարմացնել RSS հոսքերը + + + + RSSImp + + + Please type a rss stream url + Նշեք rss հոսանքի հղումը + + + + Stream URL: + Հոսքի հղումը. + + + + + Are you sure? -- qBittorrent + Համոզվա՞ծ եք -- qBittorrent + + + + + &Yes + &Այո + + + + + &No + &Ոչ + + + + Please choose a folder name + Ընտրեք թղթապանակի անունը + + + + Folder name: + Թղթապանակի անունը. + + + + New folder + Նոր թղթապանակ + + + + Overwrite attempt + Թույլատրել վերագրումը + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Չեք կարող վերագրել %1-ը։ + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Այս rss ալիքը արդեն առկա է ցանկում։ + + + + Are you sure you want to delete these elements from the list? + Ջնջե՞լ այս մասրեը ցանկից։ + + + + Are you sure you want to delete this element from the list? + Ջնջե՞լ սա ցանկից։ + + + + Please choose a new name for this RSS feed + Ընտրեք RSS ալիքի անունը + + + + New feed name: + Անունը. + + + + Name already in use + Այս անունով արդեն առկա է + + + + This name is already used by another item, please choose another one. + Այս անունով արդեն առկա է, օգտագործեք այլ անուն։ + + + + Date: + Ամսաթիվը. + + + + Author: + Հեղինակը. + + + + Unread + Չկարդացած + + + + RssArticle + + No description available + Նկարագրություն չկա + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Միանգամից բեռնել %1 torrent-ը՝ %2 RSS ալիքից…... + + + + RssSettingsDlg + + + RSS Reader Settings + RSS կարդալու ընտրանքները + + + + RSS feeds refresh interval: + RSS ալիքները թարմացնելու ժ-ը. + + + + minutes + րոպե + + + + Maximum number of articles per feed: + Յուրաքանչյուր ալիքի համար հոդվածների առավ. ք-ը. + + + + ScanFoldersModel + + + Watched Folder + Հետևելու թղթապանակը + + + + Download here + Բեռնել այստեղ + + + + SearchCategories + + + All categories + Բոլոր բաժինները + + + + Movies + Ֆիլմեր + + + + TV shows + TV շոուներ + + + + Music + Երաժշտություն + + + + Games + Խաղեր + + + + Anime + Մուլտեր + + + + Software + Ծրագրեր + + + + Pictures + Նկարներ + + + + Books + Գրքեր + + + + SearchEngine + + + Cut + Կտրել + + + + Copy + Պատճենել + + + + Paste + Տեղադրել + + + + Clear field + Մաքրել + + + + Clear completion history + Մաքրել պատմությունը + + + + Confirmation + Հաստատեք + + + + Are you sure you want to clear the history? + Մաքրե՞լ պատմությունը։ + + + + + + Search + Փնտրել + + + + Missing Python Interpreter + Բացակայում է Python Interpreter-ը + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Պահանջվում է Python 2.x՝ օգտագործելու համար փնտրման հնարավորությունը, բայց կարծես թե այն տեղակայված չէ։ +Տեղակայե՞լ։ + + + + Empty search pattern + Դաշտը դատարկ է + + + + Please type a search pattern first + Նախ գրեք, թե ինչ փնտրել + + + + + Results + Արդյունքները + + + + Searching... + Փնտրվում է… + + + + Search Engine + Որոնում + + + + + Search has finished + Որոնումը ավարտվեց + + + + An error occured during search... + Սխալ՝ փնտրելիս… + + + + + Search aborted + Փնտրումը կանգնեցվել է + + + + Download error + Բեռնման սխալ + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Python-ի տեղակայիչը չի կարող բեռնվել, պատճառը՝ %1։ +Տեղակայեք այն ձեռադիր։ + + + + Search returned no results + Ոչնինչ չի գտնվել + + + + Results + i.e: Search results + Արդյունքները + + + + + Unknown + Անհայտ + + + + SearchTab + + + Name + i.e: file name + Անունը + + + + Size + i.e: file size + Չափը + + + + Seeders + i.e: Number of full sources + Seed-եր + + + + Leechers + i.e: Number of partial sources + Leech-եր + + + + Search engine + Փնտրել + + + + ShutdownConfirmDlg + + + Shutdown confirmation + Հաստատեք անջատումը + + + + SpeedLimitDialog + + + KiB/s + Կբիթ/վ + + + + StatusBar + + + + Connection status: + ՄԻացման ընթացքը. + + + + + No direct connections. This may indicate network configuration problems. + Չկան ուղիղ միացումներ։ + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + Բ. %1 Բ/վ - Ը. %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + Փ.: %1 Բ/վ - Ը. %2 + + + + + DHT: %1 nodes + DHT. %1 հանգույց + + + + qBittorrent needs to be restarted + Պահանջվում է ծրագրի վերագործարկում + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent-ը թարմացվել է։ Վերամեկնարկեք՝ փոփոխությունները կիրառելու համար։ + + + + + Connection Status: + Միացման վիճակը. + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Ցանցից դուրս. Սա նշանակում է, որ qBittorrent-ը չկարողացավ միանալ ընտրված դարպասին։ + + + + Online + Ցանցում է + + + + + %1/s + Per second + %1/վ + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Բ. %1/վ - Ը. %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Փ. %1/վ - Ը. %2 + + + + Click to switch to alternative speed limits + Սեղմեք՝ այլընտրանքային սահ-ներին անցնելու համար + + + + Click to switch to regular speed limits + Սեղմեք՝ հիմնական սահ-ներին անցնելու համար + + + Click to disable alternative speed limits + Սեղմեք անջատելու համար արագ-ան այլընտ. սահ-ումները + + + Click to enable alternative speed limits + Սեղմեք միացնելու համար արագ-ան այլընտ. սահ-ումները + + + + Global Download Speed Limit + Բեռնման արագ-ան գլոբալ սահ-ում + + + + Global Upload Speed Limit + Փոխանցման արագ-ան գլոբալ սահ-ում + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Ընտեք թղթապանակ՝ torrent-ում ավելացնելու համար + + + + Select a file to add to the torrent + Ընտեք ֆայլ՝ torrent-ում ավելացնելու համար + + + + No input path set + Նշված չէ ճանապարհը + + + + Please type an input path first + Նախ նշեք ճանապարհը + + + + Select destination torrent file + Ընտրեք torrent ֆայլը + + + + Torrent Files + Torrent ֆայլեր + + + + + + Torrent creation + Ստեղծել Torrent + + + + Torrent creation was unsuccessful, reason: %1 + Torrent-ի ստեղծումը ձախողվեց, պատճառը՝ %1 + + + + Created torrent file is invalid. It won't be added to download list. + Ստեղծված torrent ֆայլը ճիշտ չէ։ Այն չի կարող ավելացվել բեռնման ցանկին։ + + + + Torrent was created successfully: + Torrent-ը հաջողությամբ ստեղծվեց. + + + + TorrentFilesModel + + + Name + Անունը + + + + Size + Չափը + + + + Progress + Ընթացքը + + + + Priority + Առաջնայնությունը + + + + TorrentImportDlg + + + Torrent Import + Ներմուծել Torrent + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Օգնականը կուղղորդի Ձեզ qBittorrent-ի բեռնած torrent-ները տարածելու գործում։ + + + + Torrent file to import: + Ներմուծելու ֆայլը. + + + + + ... + + + + + Content location: + Պարունակության տեղը. + + + + Skip the data checking stage and start seeding immediately + Բաց թողնել տվյալների ստուգումը և միանգամից սկսել փոխանցումը + + + + Import + Ներմուծել + + + + Torrent file to import + Ներմուծելու ֆայլը + + + + Torrent files (*.torrent) + Torrent ֆայլեր (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 ֆայլեր + + + + Please provide the location of %1 + %1 is a file name + Նշեք %1-ի տեղադրությունը + + + + Please point to the location of the torrent: %1 + Նշեք տեղադրությունը. %1 + + + + Invalid torrent file + Սխալ torrent ֆայլ + + + + This is not a valid torrent file. + Սա ճիշտ torrent ֆայլ չէ։ + + + + TorrentModel + + + Name + i.e: torrent name + Անունը + + + + Size + i.e: torrent size + Չափը + + + + Done + % Done + -ը բեռնվել է + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Վիճակը + + + + Seeds + i.e. full sources (often untranslated) + Seed-եր + + + + Peers + i.e. partial sources (often untranslated) + Peer-եր + + + + Down Speed + i.e: Download speed + Բեռ. արագ-ը + + + + Up Speed + i.e: Upload speed + Փոխ. արագ-ը + + + + Ratio + Share ratio + Սահ-ը + + + + ETA + i.e: Estimated Time of Arrival / Time left + Մնացել է + + + + Label + Նիշը + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Ավելացվել է + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Ավարտվել է + + + + Tracker + Ուղղորդիչը + + + + Down Limit + i.e: Download limit + Բեռ. սահ-ում + + + + Up Limit + i.e: Upload limit + Փոխ. սահ-ում + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Բեռնվել է + + + + Amount left + Amount of data left to download (e.g. in MB) + Մնացել է + + + + Time Active + Time (duration) the torrent is active (not paused) + Ակտիվ ժ-ը + + + + TrackerList + + + URL + Հղումը + + + + Status + Վիճակը + + + + Peers + Peer-եր + + + + Message + Հաղորդագրություն + + + + [DHT] + [DHT] + + + + [PeX] + [PeX] + + + + [LSD] + [LSD] + + + + + + + + Working + Աշխատում է + + + + + + Disabled + Անջատված է + + + + This torrent is private + Այս torrent-ը անձնական է + + + + Updating... + Թարմացվում է… + + + + + Not working + Չի աշխատում + + + + + Not contacted yet + Դեռ չի կապնվել + + + + Add a new tracker... + Ավելացնել նոր ուղղորդիչ… + + + + Remove tracker + Ջնջել ուղղորդիչը + + + + Force reannounce + Ստիպողական վերահայտարարում + + + + TrackersAdditionDlg + + + Trackers addition dialog + Ուղղորդիչներ ավելացնելու պատուհան + + + + List of trackers to add (one per line): + Ավելացվող ուղղորդիչների ցանկը. + + + + µTorrent compatible list URL: + µTorrent-ի հետ համատեղելի հղումներ. + + + + I/O Error + Ն/Ա սխալ + + + + Error while trying to open the downloaded file. + Սխալ՝ բեռնված ֆայլը բացելիս։ + + + + No change + Չկա փոփոխություն + + + + No additional trackers were found. + Չեն գտնվել լրացուցիչ ուղղորդիչներ։ + + + + Download error + Բեռնման սխալ + + + + The trackers list could not be downloaded, reason: %1 + Ուղղորդիչների ցանկը չի կարող բեռնվել, պատճառը՝ %1 + + + + TransferListDelegate + + + Downloading + Բեռնվում է + + + + Paused + Դադարի մեջ է + + + + Queued + i.e. torrent is queued + Հերթում է + + + + Seeding + Torrent is complete and in upload-only mode + Փոխանցվում է + + + + Stalled + Torrent is waiting for download to begin + Սպասում է + + + + Checking + Torrent local data is being checked + Ստուգվում է + + + + /s + /second (.i.e per second) + + + + + KiB/s + KiB/second (.i.e per second) + Կբիթ/վ + + + + Seeded for %1 + e.g. Seeded for 3m10s + Փոխանցվել է՝ %1 + + + + TransferListFiltersWidget + + + + All + Բոլորը + + + + + Downloading + Բեռնվում է + + + + + Completed + Ավարտվել է + + + + + Paused + Դադարի մեջ + + + + + Active + Ակտիվ + + + + + Inactive + Ակտիվ չէ + + + + + All labels + Նշանագրվածները + + + + + Unlabeled + Նշանագրված չէ + + + + Remove label + Ջնջել նիշը + + + + Add label... + Ավելացնել նիշ… + + + + Resume torrents + Վերսկսել torrent-ները + + + + Pause torrents + Դադարեցնել + + + + Delete torrents + Ջնջել + + + + New Label + Նոր նիշ + + + + Label: + Նիշը. + + + + Invalid label name + Նիշի սխալ անուն + + + + Please don't use any special characters in the label name. + Մի օգտագործեք որևէ հատոկ նշան նիշի անվան մեջ։ + + + + TransferListWidget + + + Column visibility + Սյուների տեսքը + + + + Label + Նիշը + + + + Choose save path + Ընտրեք պահպանելու տեղը + + + + Torrent Download Speed Limiting + Torrent-ների բեռնման արագ. սահ-ում + + + + Torrent Upload Speed Limiting + Torrent-ների փոխանցման արագ. սահ-ում + + + + New Label + Նոր նիշ + + + + Label: + Նիշը. + + + + Invalid label name + Նշանի սխալ անուն + + + + Please don't use any special characters in the label name. + Անունը նշելիս մի օգտագործեք որևէ հատուկ նշան։ + + + + Rename + Անվանափոխել + + + + New name: + Նոր անունը. + + + + Resume + Resume/start the torrent + Վերսկսել + + + + Pause + Pause the torrent + Դադար + + + + Delete + Delete the torrent + Ջնջել + + + + Preview file... + Նախն. դիտում… + + + + Limit share ratio... + Արագ-ան սահ-ներ... + + + + Limit upload rate... + Փոխանցման սահմանափակումը… + + + + Limit download rate... + Բեռնման սահ-ը… + + + + Open destination folder + Բացել պարունակող թղթապանակը + + + + Move up + i.e. move up in the queue + Շարժել վերև + + + + Move down + i.e. Move down in the queue + Շարժել ներքև + + + + Move to top + i.e. Move to top of the queue + Հերթում առաջ + + + + Move to bottom + i.e. Move to bottom of the queue + Հերթում հետ + + + + Set location... + Բեռնման տեղը... + + + + Priority + Առաջնայնությունը + + + + Force recheck + Ստիպ. վերստուգում + + + + Copy magnet link + Պատճենել magnet հղումը + + + + Super seeding mode + Գերփոխանցման եղանակ + + + + Rename... + Անվանափոխել... + + + + Download in sequential order + Բեռնել հաջորդական կարգով + + + + Download first and last piece first + Բեռնել առաջին և վերջին մասերը + + + + New... + New label... + Նոր... + + + + Reset + Reset label + Ետարկել + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Torrent-ի բեռնման/փոխանցման սահ-եր + + + + Use global ratio limit + Օգտ. ընդհ. սահ-ներ + + + + + + buttonGroup + Խմբի կոճակը + + + + Set no ratio limit + Առանց սահ-ների + + + + Set ratio limit to + Արագ-ը սահ-ել՝ + + + + UsageDisplay + + + Usage: + Օգտագործվել է. + + + + displays program version + ցուցադրել ծրագրի տարբերակը + + + + disable splash screen + ցուցադրել ծրագրի պատկերը + + + + displays this help message + ցուցադրել այս օգնող հաղորդագրությունը + + + + changes the webui port (current: %1) + փոփոխություններ webui դարպասում (գործողը. %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [ֆայլեր կամ հղումներ].torrent-ների բեռնումը օգտագործողի կողմից (լրացուցիչ) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Շնորհակալություն բոլոր այս մարդկանց, որոնք սիրով թարգմանել են qBittorrent-ը. + + + + Please contact me if you would like to translate qBittorrent into your own language. + Խնդրում եմ կապնվել ինձ հետ, եթե ցանկանում եք թարգմանել qBittorrent-ը Ձեր մայրենի լեզվով։ + + + + addPeerDialog + + + Peer addition + Peer լրացում + + + + IP + IP-ին + + + + Port + Դարպասը + + + + addTorrentDialog + + + Torrent addition dialog + Torrent ավելացնելու պատուհան + + + + Save path: + Պահպանելու տեղը. + + + + ... + ... + + + + Torrent size: + Torrent-ի չափը. + + + + + Unknown + Անհայտ + + + + Free disk space: + Ազատ տեղը պնակի վրա. + + + + Label: + Նիշը. + + + + Torrent content: + Torrent-ի պարունակությունը. + + + + Select All + Ընտրել բոլորը + + + + Select None + Ոչ մեկը + + + + Download in sequential order (slower but good for previewing) + Բեռնել հաջորդական կարգով (դանդաղ է, բայց լավ դիտելու համար) + + + + Skip file checking and start seeding immediately + Բաց թողնել ֆայլերի ստուգումը և միանգամից սկսել փոխանցումը + + + + Add to download list in paused state + Ավելացնել բեռնումների ցանկին ՚դադարի մեջ՚ եղանակով + + + + Add + Ավելացնել + + + + Cancel + Մերժել + + + + Normal + Նորմալ + + + + High + Բարձր + + + + Maximum + Առավելագ. + + + + + Do not download + Չբեռնել + + + + authentication + + + + Tracker authentication + Ներկայացում ուղղորդիչում + + + + Tracker: + Ուղղորդիչը. + + + + Login + Մուտքաբառը + + + + Username: + Օգտվողը. + + + + Password: + Ծածկագիրը. + + + + Log in + Մուտք + + + + Cancel + Մերժել + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Հաստատեք ջնջումը + + + + Are you sure you want to delete the selected torrents from the transfer list? + Համոզվա՞ծ եք, որ պետք է ջնջել ընտրված torrent-ները ցանկից։ + + + + Remember choice + Հիշել ընտրությունը + + + + Also delete the files on the hard disk + Նաև ջնջել ֆայլերը պնակից + + + + createTorrentDialog + + + Cancel + Մերժել + + + + Torrent Creation Tool + Torrent ստեղծելու գործիք + + + + Torrent file creation + Torrent ֆայլի ստեղծում + + + + Add file + Ավելացնել ֆայլ + + + + Add folder + Ավելացնել թղթապանակ + + + + File or folder to add to the torrent: + Ավելացրեք torrent-ում ֆայլեր կամ թղթապանակներ. + + + + Tracker URLs: + Ուղղորդիչի հղումները. + + + + Web seeds urls: + Փոխանցողների հղումները. + + + + Comment: + Մեկնաբանություն. + + + + Piece size: + Մասի չափը. + + + + 32 KiB + 32 ԿԲ + + + + 64 KiB + 64 ԿԲ + + + + 128 KiB + 128 ԿԲ + + + + 256 KiB + 256 ԿԲ + + + + 512 KiB + 512 ԿԲ + + + + 1 MiB + 1 ՄԲ + + + + 2 MiB + 2 ՄԲ + + + + 4 MiB + 4 ՄԲ + + + + Auto + Ինքնա + + + + Private (won't be distributed on DHT network if enabled) + Գաղտնի (չի տեղորոշվի DHT ցանցում եթե թույլատրված է) + + + + Start seeding after creation + Ստեղծելուց հետո սկսել փոխանցումը + + + + Create and save... + Ստեղծել կամ պահպանել… + + + + Progress: + Ընթացքը. + + + + downloadFromURL + + Download Torrents from URLs + Բեռնել Torrent-ները հղումներից + + + Only one URL per line + Մեկ հղում տողի համար + + + + Add torrent links + Ավելացնել torrent-ի հղումներ + + + + Both HTTP and Magnet links are supported + Աջակցում է HTTP և Magnet հղումներ + + + + Download + Բեռնել + + + + Cancel + Մերժել + + + + Download from urls + Բեռնել հղումներից + + + + No URL entered + Գրեք հղումներ + + + + Please type at least one URL. + Նշեք գոնե մեկ հղում։ + + + + downloadThread + + I/O Error + I/O սխալ + + + The remote host name was not found (invalid hostname) + Հեռադիր հոսթի անունը չի գտնվել (հոսթի անունը սխալ է) + + + The operation was canceled + Գործողությունը ընդհատվել է + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Հեռադիր սպասարկիչը փակել է միացումը՝ մինչ կստացվեր պատասխանը + + + The connection to the remote server timed out + Հեռադիր սպասարկիչին միանալու ժ-ը լրացել է + + + SSL/TLS handshake failed + SSL/TLS փոխլրացումը ձախողվեց + + + The remote server refused the connection + Հեռադիր սպասարկիչը մերժել է միացումը + + + The connection to the proxy server was refused + Միացումը միջնորդ սպասարկիչին մերժվել է + + + The proxy server closed the connection prematurely + Միջնորդ սպասարկիչը փակել է միացումը + + + The proxy host name was not found + Չի գտնվել միջնորդի հոսթի անունը + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Միջնորդին միանալու ժ-ը լրացել է, միջնորդը հարցմանը ժամանակին չի պատասխանել + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Միջնորդը պահանջում է ներկայացում + + + The access to the remote content was denied (401) + Մուտքը հեռադիր կառավարմանը փակ է (401) + + + The operation requested on the remote content is not permitted + Գործողությունը, որը պահանջում է հեռադիր բովանդակություն, չի թույլատրվել + + + The remote content was not found at the server (404) + Հեռադիր բովանդակությունը չի գտնվել սպասարկիչում (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Հեռադիր սպասարկիչը պահանջում է ներկայացում + + + The Network Access API cannot honor the request because the protocol is not known + Network Access API-ին չի կարողանում ստանալ հարցում, որովհետեև արձանագր. հայտնի չէ + + + The requested operation is invalid for this protocol + Պահանջվող գործողությունը սխալ է այս արձանագր. համար + + + An unknown network-related error was detected + Անհայտ սխալ + + + An unknown proxy-related error was detected + Միջնորդի անհայտ սխալ + + + An unknown error related to the remote content was detected + Հեռադիր բովանդակության անհայտ սխալ + + + A breakdown in protocol was detected + Անհաջողություն արձանագրությունում + + + Unknown error + Անհայտ սխալ + + + + engineSelect + + + Search plugins + Որոնող խրոցակներ + + + + Installed search engines: + Տեղակայված որոնման խրոցակներ + + + + Name + Անունը + + + + Url + Հղումը + + + + + Enabled + Միացված է + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Կարող եք գտնել որոնման խրոցակներ այստեղից. <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Տեղակայել նորը + + + + Check for updates + Ստուգել թարմացումները + + + + Close + Փակել + + + Enable + Միացված է + + + Disable + Անջատված է + + + + Uninstall + Ջնջել + + + + engineSelectDlg + + + Uninstall warning + Զգուշացում ջնջելիս + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Որոշ խրոցակներ չեն կարող ջնջվել, որովհետև դրանք տեղադրված են qBittorrent-ում։ +Միայն Ձեր ավելացրածներն է հնարավոր ջնջել։ +Այնուհանդերձ այդ խրոցակները անջատվել են։ + + + + Uninstall success + Հաջողությամբ ջնջվեց + + + + Select search plugins + Ընտրեք փնտրման խրոցակը + + + + qBittorrent search plugins + qBittorrent-ի փնտրման խրոցակներ + + + + + + + + Search plugin install + Տեղակայել փնտրման խրոցակ + + + + + + Yes + Այո + + + + + + + No + Ոչ + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + %1 փնտրող խրոցակի ավելի նոր տարբերակն է տեղակայված։ + + + + + + + Search plugin update + Փնտրման խրոցակի թարմացում + + + + + Sorry, update server is temporarily unavailable. + Ցավոք թարմացումների հասանելիությունը հանարավոր չէ ստուգել։ + + + + All your plugins are already up to date. + Ձեր բոլոր խրոցակները նոր են։ + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 փնտրման խրոցակները չեն կարող թարմացվել, կպահվեն հները։ + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 փնտրման խրոցակները չեն կարող տեղակայվել։ + + + + All selected plugins were uninstalled successfully + Բոլոր ընտրված խրոցակները հաջողությամբ ջնջվեցին + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 խրոցակը հաջողությամբ ջնջվեց։ + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1 խրոցակը հաջողությամբ տեղակայվեց։ + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Ցավոք %1 խրոցակի տեղակայումը ձախողվեց։ + + + + New search engine plugin URL + Փնտրման խրոցակի հղումը + + + + URL: + Հղումը. + + + + misc + + + B + bytes + Բ + + + + KiB + kibibytes (1024 bytes) + ԿԲ + + + + MiB + mebibytes (1024 kibibytes) + ՄԲ + + + + GiB + gibibytes (1024 mibibytes) + ԳԲ + + + + TiB + tebibytes (1024 gibibytes) + ՏԲ + + + + %1h %2m + e.g: 3hours 5minutes + %1ժ %2ր + + + + %1d %2h + e.g: 2days 10hours + %1օր %2ժ + + + + Unknown + Unknown (size) + Անհայտ + + + + qBittorrent will shutdown the computer now because all downloads are complete. + Բոլոր բեռնումները ավարտվել են։ Համակարգիչը անջատվում է։ + + + + + + + + + Unknown + Անհայտ + + + + < 1m + < 1 minute + « 1ր + + + + %1m + e.g: 10minutes + %1րոպե + + + + options_imp + + + + Choose export directory + Ընտրեք արտածման տեղը + + + + + + + Choose a save directory + Ընտրեք պահպանելու տեղը + + + + + Choose an ip filter file + Ընտրեք ip ֆիլտր ֆայլը + + + + Add directory to scan + Ստուգելու համար ավելացնել թղթապանակ + + + + Folder is already being watched. + Թղթապանակը արդեն ստուգվել է։ + + + + Folder does not exist. + Թղթապանակը գոյություն չունի։ + + + + Folder is not readable. + Թղթապանակը կարդալու համար չէ։ + + + + Failure + Ձախողում + + + + Failed to add Scan Folder '%1': %2 + Հնարավոր չէ ստուգման համարավելացնել թղթապանակ՝ '%1': %2 + + + + + Filters + Ֆիլտրեր + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + Սխալ + + + + Failed to parse the provided IP filter + IP ֆիլտրի տրամադրման սխալ + + + + Successfully refreshed + Հաջողությամբ թարմացվեց + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + IP ֆիլտրի ներկայացումը հաջող էր. %1 կանոնները կիրառվեցին։ + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + + pluginSourceDlg + + + Plugin source + Խրոցակի աղբյուրը + + + + Search plugin source: + Փնտրման խրոցակի աղբյուրը. + + + + Local file + Լոկալ ֆայլ + + + + Web link + Վեբ հղում + + + + preview + + + Preview selection + Դիտել ընտրվածը + + + + File preview + Ֆայլի դիտում + + + + The following files support previewing, <br>please select one of them: + Հետևյալ ֆայլերը աջակցում են նախն. դիտում, <br> ընտրեք դրանցից մեկը. + + + + Preview + Դիտել + + + + Cancel + Մերժել + + + + previewSelect + + Preview impossible + Դիտումը հնարավոր չէ + + + Sorry, we can't preview this file + Հնարավոր չէ դիտել այս ֆայլը + + + Name + Անունը + + + Size + Չափը + + + Progress + Ընթացքը + + + + search_engine + + + + Search + Փնտրել + + + + Status: + Վիճակը. + + + + Stopped + Կանգնեցված + + + + Download + Բեռնել + + + + Go to description page + Անցնել նկարագրությանը + + + + Search engines... + Փնտրել… + + + + torrentAdditionDialog + + + Unable to decode magnet link: + Հնարավոր չէ ապակոդավորել magnet հղումը + + + + Magnet Link + Magnet հղում + + + + + Unable to decode torrent file: + Հնարավոր չէ ապակոդավորել torrent ֆայլը. + + + + Rename... + Անվանափոխել... + + + + Priority + Առաջ-ը + + + + Rename the file + Անվանափոխել + + + + New name: + Նոր անուն. + + + + + The file could not be renamed + Ֆայլը չի կարող անվանափոխվել + + + + This file name contains forbidden characters, please choose a different one. + Ֆայլի անունը պարունակում է արգելված նշաններ, ընտրեք այլ անուն։ + + + + + This name is already in use in this folder. Please use a different name. + Այս անունով արդեն առկա է տվյալ թղթապանակում։ Ընտրեք այլ անուն։ + + + + The folder could not be renamed + Հնարավոր չէ անվանափոխել թղթապանակը + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (torrent-ը բեռնելու համար մնացել է %1) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1-ը բեռնվել է պահանջվածից շատ) + + + + + + Choose save path + Ընտրեք պահպանելու ճանապարհը + + + + Empty save path + Դատարկել պահպանելու ճանապարհը + + + + Please enter a save path + Նշեք պահպանելու ճանապարհը + + + + Save path creation error + Պահպանելու ճանապարհի սխալ + + + + Could not create the save path + Հնարավոր չէ ստեղծել պահպանելու ճանապարհը + + + + Invalid label name + Նիշը սխալ է + + + + Please don't use any special characters in the label name. + Մի օգտագործեք որևէ հատուկ նշան անվան մեջ։ + + + + Seeding mode error + Փոխանցման եղանակի սխալ + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Դուք ընտրել եք ֆայլի ստուգման անտեսումը։ Լոկալ ֆայլերը կարծես գոյություն չունեն նշված տեղում։ Անջատեք սա կամ թարմացրեք պահպանելու ճանապարհը։ + + + + Invalid file selection + Սխալ ընտրություն + + + + You must select at least one file in the torrent + Torrent-ից պետք է նշեք գոնե մեկ ֆայլ + + + diff --git a/src/lang/qbittorrent_it.qm b/src/lang/qbittorrent_it.qm new file mode 100644 index 0000000000000000000000000000000000000000..2effcf1da4496a17307341943f59cedd47c92dfa GIT binary patch literal 121942 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∈R>VKfqgh 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 K`svwcp83Cd>?F4U literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_it.ts b/src/lang/qbittorrent_it.ts new file mode 100644 index 000000000..4a4a0a7c9 --- /dev/null +++ b/src/lang/qbittorrent_it.ts @@ -0,0 +1,6800 @@ + + + + + AboutDlg + + + About qBittorrent + Informazioni su qBittorrent + + + + About + Informazioni + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + Author + Autore + + + + Name: + Nome: + + + + Country: + Paese: + + + + E-mail: + E-mail: + + + + Christophe Dumez + Christophe Dumez + + + + France + Francia + + + + Translation + Traduzione + + + + License + Licenza + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta nome="qrichtext" contenuto="1" /><style tipo="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body stile=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Un client Bittorrent programmato in C++, basato sul toolkit Qt4 </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">e libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span stile=" font-family:'DejaVu Sans'; text-decoration: underline;"Pagina principale:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + chris@qbittorrent.org + chris@qbittorrent.org + + + + Thanks to + Grazie a + + + + AdvancedSettings + + Property + Proprietà + + + Value + Valore + + + + Disk write cache size + Dimensione della cache di scrittura su disco + + + + MiB + MiB + + + + Setting + Impostazione + + + + Value + Value set for this setting + Valore + + + + Outgoing ports (Min) [0: Disabled] + Porte in uscita (Min) [0:Disablitato] + + + + Outgoing ports (Max) [0: Disabled] + Porte in uscita (Max) [0:Disabilitato + + + + Ignore transfer limits on local network + Ignora limiti di trasferimento nella rete locale + + + + Exchange trackers with other peers + + + + Include TCP/IP overhead in transfer limits + includere overhead TCP / IP in termini di trasferimento + + + + Recheck torrents on completion + Ricontrolla torrent al completamento + + + + Transfer list refresh interval + Aggiorna lista trasferimenti torrent + + + + ms + milliseconds + millisecondi + + + + Resolve peer countries (GeoIP) + Risolvi localizzazione peer (GeoIP) + + + + Resolve peer host names + Risolvi gli host name dei peer + + + + Maximum number of half-open connections [0: Disabled] + Massimo numero di connesioni semi aperte [0: Disabilitato] + + + + Strict super seeding + Forza super seeding + + + + Network Interface (requires restart) + Interfaccia di rete (richiede il riavvio) + + + + Any interface + i.e. Any network interface + Una interfaccia + + + + IP Address to report to trackers (requires restart) + Indirizzo Ip da riportare ai tracker + + + + Display program on-screen notifications + Mostra notifiche del programma nello schermo + + + + Check for software updates + Controlla aggiornamenti programma + + + + Use system icon theme + Usa icone di sistema + + + + Confirm torrent deletion + Conferma eliminazione torrent + + + Display program notification baloons + Mostra fumetti di notifiche del programma + + + Display program notification balloons + Mostra fumetti di notifiche dei programmi + + + + Enable embedded tracker + Abilita i tracker connessi + + + + Embedded tracker port + Porte tracker collegate + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Gestore download RSS automatico + + + + Enable the automated RSS downloader + Abilita il gestore automatico di download RSS + + + + Download rules + Regole di download + + + + Rule definition + Definizione regole + + + + Must contain: + Deve contenere: + + + + Must not contain: + Non deve contenere: + + + + Assign label: + Assegna etichetta: + + + + Save to a different directory + Salva in una cartella differente + + + + Save to: + Salva in: + + + + ... + ... + + + + Use regular expressions + Usa espressioni regolari + + + + Apply rule to feeds: + Applica regola ai feed: + + + + Matching RSS articles + Collegamenti articoli RSS + + + + Import... + Importa... + + + + Export... + Esporta... + + + + New rule name + Nuovo nome regola + + + + Please type the name of the new download rule. + Per favore inserisci il nome della nuova regola di download. + + + + + Rule name conflict + Conflitto nel nome della regola + + + + + A rule with this name already exists, please choose another name. + Una regola con questo nome esiste già, per favore scegli un altro nome. + + + + Are you sure you want to remove the download rule named %1? + Sei sicuro che vuoi rimuovere la regola di download di nome %1? + + + + Are you sure you want to remove the selected download rules? + Sei sicuro che vuoi rimuovere la regola di download selezionata? + + + + Rule deletion confirmation + Conferma cancellazione della regola + + + + Destination directory + Cartella di destinazione + + + + Invalid action + Azione non valida + + + + The list is empty, there is nothing to export. + La lista è vuota, non c'è niente da esportare. + + + + Where would you like to save the list? + Dove si vuole salvare la lista? + + + + Rules list (*.rssrules) + Lista regole (*.rssrules) + + + + I/O Error + Errore I/O + + + + Failed to create the destination file + Creazione del file di destinazione fallita + + + + Please point to the RSS download rules file + Per favore indica il file della regola di download + + + + Rules list (*.rssrules *.filters) + Lista regole (*.rssrules *.filters) + + + + Import Error + Importa errore + + + + Failed to import the selected rules file + Importazione del file della regola fallita + + + + Add new rule... + Aggiungi nuova regola... + + + + Delete rule + Elimina regola + + + + Rename rule... + Rinomina regola... + + + + Delete selected rules + Elimina regole selezionate + + + + Rule renaming + Rinominazione regole + + + + Please type the new rule name + Per favore inserisci il nuovo nome della regola + + + + Regex mode: use Perl-like regular expressions + Modalità regex: usa espressioni regolari come Perl + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Modalità jolly: è possibile utilizzare <li>? per un singolo carattere </ li> <li> * per indicare zero o più caratteri </ li> <li> conteggio bianco Locali come operatori AND </ li> </ ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Modalità jolly: è possibile utilizzare <li>? per un singolo carattere </ li> <li> * per indicare zero o più caratteri </ li> <li> | è usato come operatore OR </ li> </ ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 ha raggiunto il rapporto massimo impostato. + + + Removing torrent %1... + Rimozione torrent %1... + + + Pausing torrent %1... + Torrent in pausa %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + per esempio: qBittorrent è in ascolto sulla porta: 6881 + qBittorrent è in ascolto sulla porta: TCP/%1 + + + UPnP support [ON] + Supporto UPnP [ON] + + + UPnP support [OFF] + Supporto UPnP [OFF] + + + NAT-PMP support [ON] + Supporto NAT-PMP [ON] + + + NAT-PMP support [OFF] + Supporto NAT-PMP [OFF] + + + HTTP user agent is %1 + Lo user agent HTTP è %1 + + + Using a disk cache size of %1 MiB + Cache disco in uso %1 MiB + + + DHT support [ON], port: UDP/%1 + Supporto DHT [ON], porta: UDP/%1 + + + DHT support [OFF] + Supporto DHT [OFF] + + + PeX support [ON] + Supporto PeX [ON] + + + PeX support [OFF] + Supporto PeX [OFF] + + + Restart is required to toggle PeX support + È richiesto il riavvio per modificare il supporto PeX + + + Local Peer Discovery [ON] + Supporto scoperta peer locali [ON] + + + Local Peer Discovery support [OFF] + Supporto scoperta peer locali [OFF] + + + Encryption support [ON] + Supporto cifratura [ON] + + + Encryption support [FORCED] + Supporto cifratura [FORZATO] + + + Encryption support [OFF] + Supporto cifratura [OFF] + + + The Web UI is listening on port %1 + L'interfaccia Web è in ascolto sulla porta %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Errore interfaccia web - Impossibile mettere l'interfaccia web in ascolto sulla porta %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + 'xxx.avi' è stato rimosso... + '%1' è stato rimosso dalla lista dei trasferimenti e dal disco. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + 'xxx.avi' è stato rimosso + '%1' è stato rimosso dalla lista dei trasferimenti. + + + '%1' is not a valid magnet URI. + '%1' non è un URI magnetico valido. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + per esempio: 'xxx.avi' è già nella lista di download. + '%1' è già nella lista dei download. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '/home/y/xxx.torrent' è stato ripreso. (recupero veloce) + '%1' ripreso. (recupero veloce) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '/home/y/xxx.torrent' è stato aggiunto alla lista di download. + '%1' è stato aggiunto alla lista dei download. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + per esempio: Impossibile decifrare il file torrent: '/home/y/xxx.torrent' + Impossibile decifrare il file torrent: '%1' + + + This file is either corrupted or this isn't a torrent. + Questo file è corrotto o non è un torrent. + + + Note: new trackers were added to the existing torrent. + Nota: sono stati aggiunti nuovi tracker al torrent esistente. + + + Note: new URL seeds were added to the existing torrent. + Nota: sono stati aggiunti nuovi URL al torrent esistente. + + + Error: The torrent %1 does not contain any file. + Errore.Il torrent %1 non contiene alcun file. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + x.y.z è stato bloccato + <font color='red'>%1</font> <i>è stato bloccato a causa dei tuoi filtri IP</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + x.y.z è stato bannato + <font color='red'>%1</font> <i>è stato bannato a causa di parti corrotte</i> + + + The network interface defined is invalid: %1 + L'interfaccia di rete definita non è valida: %1 + + + Trying any other network interface available instead. + Si sta provando qualsiasi interfaccia di rete disponibile. + + + Listening on IP address %1 on network interface %2... + Si sta ascoltano l'indirizzo IP %1 nell'interfaccia di rete %2... + + + Failed to listen on network interface %1 + Fallito l'ascolto sull'interfaccia di rete %1 + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Download ricorsivo del test .torrent incluso nel torrent test2 + Download ricorsivo del file %1 incluso nel torrent %2 + + + Unable to decode %1 torrent file. + Impossibile decifrare il file torrent %1. + + + Torrent name: %1 + Nome del torrent %1 + + + Torrent size: %1 + Dimensione del torrent %1 + + + Save path: %1 + Salva percorso %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Questo torrent è stato scaricato in 1 ora e 20 secondi + Questo torrent è stato scaricato in %1. + + + Thank you for using qBittorrent. + Grazie per aver usato qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 ha finito di scaricare + + + An I/O error occured, '%1' paused. + Si è verificato un errore I/O, %1 in pausa. + + + Reason: %1 + Ragioni: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: mappatura porte fallita, messaggio: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: mappatura porte riuscita, messaggio: %1 + + + File sizes mismatch for torrent %1, pausing it. + La dimensione del file discorda con il torrent %1, è in pausa. + + + Fast resume data was rejected for torrent %1, checking again... + Il recupero veloce del torrent %1 è stato rifiutato, altro tentativo in corso... + + + Url seed lookup failed for url: %1, message: %2 + Ricerca seed web fallita per l'url: %1, messaggio: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + per esempio:'Download 'xxx.torrent', in corso... + Download di '%1' in corso... + + + + ConsoleDlg + + qBittorrent log viewer + Visualizza log qBittorrent + + + General + Generali + + + Blocked IPs + IP bloccati + + + + CookiesDlg + + + Cookies management + Gestione cookie + + + + Key + As in Key/Value pair + Codice + + + + Value + As in Key/Value pair + Valore + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Tasti comuni per i cookie sono :%1, %2 +Si consiglia di controllare questa informazione nelle preferenze del tuo browser. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + Il tuo DNS è stato caricato con successo. + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Errore DNS dinamico: Il servizio non è temporaneamente disponibile, verrà ritirato tra 30 minuti. + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Errore DNS dinamico: tra gli hostname forniti non esiste l'account sprcificato. + + + + Dynamic DNS error: Invalid username/password. + Errore DNS dinamico: Nome utente/password non valido. + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Errore DNS dinamico: qBittorrent è stato bannato dal servizio, prego riporta un bug a http://bugs.qbittorrent.org. + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Errore DNS dinamico: %1 è stato ritornato dal servizio, prego riporta un bug al http://bugs.qbittorrent.org. + + + + Dynamic DNS error: Your username was blocked due to abuse. + Errore DNS dinamico: Il tuo nome utente è stato bloccato per abuso. + + + + Dynamic DNS error: supplied domain name is invalid. + Errore DNS dinamico: il nome del dominio fornito non è valido. + + + + Dynamic DNS error: supplied username is too short. + Errore DNS dinamico: il nome utente fornito è troppo corto. + + + + Dynamic DNS error: supplied password is too short. + Errore DNS dinamico: la password fornita è troppo corta. + + + + DownloadThread + + + + I/O Error + Errore I/O + + + + The remote host name was not found (invalid hostname) + L'host remoto non è stato trovato (hostname invalido) + + + + The operation was canceled + L'operazione è stata annullata + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Il server remoto ha interrotto la connessione prematuramente, prima che la risposta completa fosse ricevuta e processata + + + + The connection to the remote server timed out + La connessione al server remoto è scaduta + + + + SSL/TLS handshake failed + Handshake SSL/TLS fallito + + + + The remote server refused the connection + Il server remoto ha rifiutato la connessione + + + + The connection to the proxy server was refused + La connessione al server proxy è stata rifiutata + + + + The proxy server closed the connection prematurely + Il server proxy ha interrotto la connessione prematuramente + + + + The proxy host name was not found + L'hostname del proxy non è stato trovato + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + La connessione al proxy è scaduta o il proxy non ha risposto in tempo alla richiesta + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Il proxy richiede l'autenticazione per onorare la richiesta ma non ha accettato le credenziali fornite + + + + The access to the remote content was denied (401) + L'accesso al contenuto remoto è stato negato (401) + + + + The operation requested on the remote content is not permitted + L'operazione richiesta sul contenuto remoto non è permessa + + + + The remote content was not found at the server (404) + Il contenuto remoto non è stato trovato sul server (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Il server remoto richiede l'autenticazione per fornire il contenuto ma le credenziali fornite non sono state accettate + + + + The Network Access API cannot honor the request because the protocol is not known + Le API dell'Accesso Remoto non possono onorare la richiesta perché il protocollo è sconosciuto + + + + The requested operation is invalid for this protocol + L'operazione richiesta non è valida per questo protocollo + + + + An unknown network-related error was detected + Un errore di rete sconosciuto è stato rilevato + + + + An unknown proxy-related error was detected + Un errore proxy sconosciuto è stato rilevato + + + + An unknown error related to the remote content was detected + Un errore sconosciuto del contenuto remoto è stato rilevato + + + + A breakdown in protocol was detected + Un malfunzionamento del protocollo è stato rilevato + + + + Unknown error + Errore sconosciuto + + + + EventManager + + + + Working + In funzione + + + + Updating... + In aggiornamento... + + + + + Not working + Non in funzione + + + + + Not contacted yet + Non ancora contattato + + + + + this session + questa sessione + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Condiviso per %1 + + + + %1 max + e.g. 10 max + %1 max + + + + + %1/s + e.g. 120 KiB/s + %1/s + + + + ExecutionLog + + + General + Generali + + + + Blocked IPs + IP bloccati + + + + FeedDownloader + + RSS Feed downloader + Scaricatore di Feed RSS + + + RSS feed: + Feed RSS: + + + Feed name + Nome del feed + + + Automatically download torrents from this feed + Download automatico dei torrent da questo feed + + + Download filters + Scarica filtri + + + Filters: + Filtri: + + + Filter settings + Impostazioni dei filtri + + + Matches: + Corrisponde: + + + Does not match: + Non corrisponde: + + + Destination folder: + Cartella di destinazione: + + + ... + ... + + + Filter testing + Test del filtro + + + Torrent title: + Titolo del torrent: + + + Result: + Risultato: + + + Test + Test + + + Import... + Importa... + + + Export... + Esporta... + + + Rename filter + Rinomina filtro + + + Remove filter + Cancella filtro + + + Add filter + Aggiungi filtro + + + + FeedDownloaderDlg + + New filter + Nuovo filtro + + + Please choose a name for this filter + Per favore scegliere un nome per questo filtro + + + Filter name: + Nome del filtro: + + + Invalid filter name + Nome filtro non valido + + + The filter name cannot be left empty. + Il nome del filtro non può essere lasciato vuoto. + + + This filter name is already in use. + Questo nome filtro è già in uso. + + + Choose save path + Scegliere una directory di salvataggio + + + Filter testing error + Errore test del filtro + + + Please specify a test torrent name. + Per favore specificare il nome di un torrent di test. + + + matches + corrisponde + + + does not match + non corrisponde + + + Select file to import + Selezionare file da importare + + + Filters Files + File del filtro + + + Import successful + Importazione riuscita + + + Filters import was successful. + Importazione dei filtri riuscita. + + + Import failure + Importazione fallita + + + Filters could not be imported due to an I/O error. + Filtri non importati a causa di un errore I/O. + + + Select destination file + Selezionare file di destinazione + + + Export successful + Esportazione riuscita + + + Filters export was successful. + Esportazione dei filtri riuscita. + + + Export failure + Esportazione fallita + + + Filters could not be exported due to an I/O error. + Filtri non esportati a causa di un errore I/O. + + + + FeedList + + Unread + Non letti + + + + FeedListWidget + + + RSS feeds + Feed Rss + + + + Unread + Non letti + + + + GUI + + Open Torrent Files + Apri file torrent + + + Torrent Files + File torrent + + + Transfers + Trasferimenti + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Velocità DL: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Velocità UP: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 è stato scaricato. + + + I/O Error + i.e: Input/Output Error + Errore I/O + + + Search + Ricerca + + + Torrent file association + Associazione file torrent + + + Set the password... + Seleziona la password... + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent non è l'applicazione predefinita per l'apertura di torrent e magnet links. +Vuoi associare qBittorrent ai file .torrent e ai magnet links? + + + Password update + Aggiorna password + + + The UI lock password has been successfully updated + Il blocco password dell'UI è stato attivato con successo + + + RSS + RSS + + + Transfers (%1) + Trasferimenti (%1) + + + Download completion + Completamento download + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Si è verificato un errore I/O per il torrent %1. +Motivo: %2 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Recursive download confirmation + Conferma recursiva di download + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Il torrent %1 contiene file torrent, vuoi procedere al download di qeusti file? + + + Yes + + + + No + No + + + Never + Mai + + + A newer version is available + Una nuova versione è disponibile + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Una nuova versione di qBittorrent è disponibile su Sourceforge. +Vuoi aggiornare qBittorrent alla versione %1? + + + Impossible to update qBittorrent + Impossibile aggiornare qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent ha fallito l'aggiornamento, ragioni: %1 + + + UI lock password + Blocca password UI + + + Please type the UI lock password: + Per favore digita la password di blocco UI: + + + Invalid password + Password non valida + + + The password is invalid + La password non è valida + + + Exiting qBittorrent + Uscire da qBittorrent + + + Always + Sempre + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Down: %2/s, Up: %3/s) + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Errore download da indirizzo web + + + Couldn't download file at url: %1, reason: %2. + Impossibile scaricare il file all'indirizzo: %1, motivo: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Limite globale upload + + + Global Download Speed Limit + Limite globale download + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Alcuni file sono ancora in trasferimento. +Sei sicuro di voler chiudere qBittorrent? + + + Options were saved successfully. + Le opzioni sono state salvate. + + + + GeoIP + + Australia + Australia + + + Argentina + Argentina + + + Austria + Austria + + + United Arab Emirates + Emirati Arabi Uniti + + + Brazil + Brasile + + + Bulgaria + Bulgaria + + + Belarus + Bielorussia + + + Belgium + Belgio + + + Bosnia + Bosnia + + + Canada + Canada + + + Czech Republic + Repubblica Ceca + + + China + Cina + + + Costa Rica + Costa Rica + + + Switzerland + Svizzera + + + Germany + Germania + + + Denmark + Danimarca + + + Algeria + Algeria + + + Spain + Spagna + + + Egypt + Egitto + + + Finland + Finlandia + + + France + Francia + + + United Kingdom + Regno Unito + + + Greece + Grecia + + + Georgia + Georgia + + + Hungary + Ungheria + + + Croatia + Croazia + + + Italy + Italia + + + India + India + + + Israel + Israele + + + Ireland + Irlanda + + + Iceland + Islanda + + + Indonesia + Indonesia + + + Japan + Giappone + + + South Korea + Sud Corea + + + Luxembourg + Lussemburgo + + + Malaysia + Malesia + + + Mexico + Messico + + + Serbia + Serbia + + + Morocco + Marocco + + + Netherlands + Paesi Bassi + + + Norway + Norvegia + + + New Zealand + Nuova Zelanda + + + Portugal + Portogallo + + + Poland + Polonia + + + Pakistan + Pakistan + + + Philippines + Filippine + + + Russia + Russia + + + Romania + Romania + + + France (Reunion Island) + Francia (Isola di Reunion) + + + Saudi Arabia + Arabia Saudita + + + Sweden + Svezia + + + Slovakia + Repubblica Slovacca + + + Singapore + Singapore + + + Slovenia + Sloveno + + + Taiwan + Taiwan + + + Turkey + Turchia + + + Thailand + Tailandia + + + USA + USA + + + Ukraine + Ucraina + + + South Africa + Sud Africa + + + + HeadlessLoader + + + Information + Informazioni + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Per controllare qBittorrent, accedere all'interfaccia Web su http://localhost:%1 + + + + The Web UI administrator user name is: %1 + Il nome amministratore dell'interfaccia Web è: %1 + + + + The Web UI administrator password is still the default one: %1 + La password dell'interfaccia Web è ancora quella di default: %1 + + + + This is a security risk, please consider changing your password from program preferences. + Questo è un rischio per la sicurezza, per favore prendi in considerazione di cambiare la tua password dalle preferenze. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + Il tuo indirizzo IP è stato bannato dopo molti tentativi di autenticazione falliti. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - T: %2 + + + + HttpServer + + + File + File + + + + Edit + Modifica + + + + Help + Aiuto + + + Delete from HD + Cancella dal disco + + + + Download Torrents from their URL or Magnet link + Scarica torrent da indirizzo web o link magnetico + + + + Only one link per line + Solo un link per riga + + + + Download local torrent + Scarica torrent locale + + + + Torrent files were correctly added to download list. + Torrent aggiunti correttamente alla lista dei download. + + + + Point to torrent file + Indirizza al file torrent + + + + Download + Download + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Sei sicuro di voler cancellare i torrent selezionati dalla lista dei trasferimenti e dal disco? + + + + Download rate limit must be greater than 0 or disabled. + Il limite di download deve essere maggiore di 0 o disattivato. + + + + Upload rate limit must be greater than 0 or disabled. + Il limite di upload deve essere maggiore di 0 o disattivato. + + + + Maximum number of connections limit must be greater than 0 or disabled. + Il limite per il numero massimo di connessioni deve essere 0 o disattivato. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Il limite per il numero di connessioni per torrent deve essere 0 o disattivato. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Il numero massimo di slot in upload deve essere 0 o disattivato. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Impossibile salvare le preferenze, qBittorrent potrebbe essere irraggiungibile. + + + + Language + Lingua + + + + Downloaded + Is the file downloaded or not? + Scaricato + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + La porta in uso per le connessioni in entrata deve essere compresa tra 1024 e 65535. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + La porta in uso per l'interfaccia Web deve essere compresa tra 1024 e 65535. + + + + The Web UI username must be at least 3 characters long. + Il nome utente per l'interfaccia Web deve essere di almeno 3 caratteri. + + + + The Web UI password must be at least 3 characters long. + La password per l'interfaccia Web deve essere di almeno 3 caratteri. + + + + Save + Salva + + + + qBittorrent client is not reachable + Il client qBittorrent non è raggiungibile + + + + HTTP Server + Server HTTP + + + + The following parameters are supported: + I seguenti parametri sono supportati: + + + + Torrent path + Percordo Torrent + + + + Torrent name + Nome Torrent + + + + LegalNotice + + + Legal Notice + Informazioni Legali + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent è un programma di file sharing. Quando si esegue un torrent, i suoi dati saranno resi disponibili agli altri per mezzo di upload.Ogni contenuto tu condividi è di tua responsabilità +Non verranno emessi avvisi. + + + + Press %1 key to accept and continue... + Premi %1 tasto per accettare e continuare... + + + + Legal notice + Notizie legali + + + + Cancel + Cancella + + + + I Agree + Accetto + + + + LineEdit + + + Clear the text + Pulisci il testo + + + + MainWindow + + + &Edit + &Modifica + + + + &Tools + &Strumenti + + + + &File + &File + + + + &Help + &Aiuto + + + + &View + &Visualizza + + + &Add File... + &Aggiungi file... + + + E&xit + E&sci + + + + &Options... + &Opzioni... + + + Add &URL... + Aggiungi &URL... + + + + Torrent &creator + Creatore &Torrent + + + + Set upload limit... + Imposta limite upload... + + + + Set download limit... + Imposta limite di download... + + + + &About + &Informazioni + + + + &Pause + &Pausa + + + + &Delete + &Cancella + + + + P&ause All + &Pausa tutti + + + + &Resume + &Riprendi + + + + &Add torrent file... + &Aggiungi file torrent... + + + + + Exit + Esci + + + + R&esume All + &Riprendi tutti + + + + Visit &Website + Visita &Sito web + + + + Auto-Shutdown on downloads completion + Spegni al completamento dei download + + + + Add &link to torrent... + Aggiungi &link al torrent... + + + + Report a &bug + Segnala un &Bug + + + + &Documentation + &Documentazione + + + + Set global download limit... + Imposta limiti di download globali... + + + + Set global upload limit... + Imposta limiti di upload globali... + + + + Execution &Log + &Log di esecuzione + + + + + Execution Log + Log di esecuzione + + + + Exit qBittorrent + Chiudi qBittorrent + + + + Suspend system + Sospendi il sistema + + + + Shutdown system + Chiudi il sistema + + + + Disabled + Disattivata + + + &Log viewer... + &Visualizzatore Log... + + + Log viewer + Visualizzatore log + + + Shutdown computer when downloads complete + Arresta il sistema quando i download sono completi + + + + + Lock qBittorrent + Blocca qBittorrent + + + + Ctrl+L + Ctrl+L + + + + Import existing torrent... + Importa torrent esistente... + + + + Donate money + Dona soldi + + + + If you like qBittorrent, please donate! + Se ti piace qBittorrent, per favore dona! + + + Shutdown qBittorrent when downloads complete + Chiudi qBittorrent quando i download sono completi + + + + Import torrent... + Importa torrent... + + + + + Alternative speed limits + Limiti di velocità alternativi + + + + &RSS reader + &Lettore RSS + + + + Search &engine + Motore &di ricerca + + + + Top &tool bar + Barra superiore &Strumenti + + + + Display top tool bar + Mostra barra degli strumenti in alto + + + + &Speed in title bar + &Velocità nella barra del titolo + + + + Show transfer speed in title bar + Mostra barra dei trasferimenti + + + Preview file + Anteprima file + + + Clear log + Cancella log + + + + Decrease priority + Diminuisci priorità + + + + Increase priority + Aumenta priorità + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + p.esempio qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + Imposta la password... + + + + Transfers + Trasferimenti + + + + Torrent file association + Associazione file torrent + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent non è l'applicazione predefinita per l'apertura di torrent e magnet links. +Vuoi associare qBittorrent ai file .torrent e ai magnet links? + + + + + + UI lock password + Blocca password UI + + + + + + Please type the UI lock password: + Per favore digita la password di blocco UI: + + + + The password should contain at least 3 characters + La password deve contenere almeno 3 caratteri + + + + Password update + Aggiorna password + + + + The UI lock password has been successfully updated + Il blocco password dell'UI è stato attivato con successo + + + + RSS + RSS + + + + Search + Ricerca + + + + Transfers (%1) + Trasferimenti (%1) + + + + Download completion + Completamento download + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + p.esempio: xxx.avi ha terminato il download + %1 è stato scaricato. + + + + I/O Error + i.e: Input/Output Error + Errore I/O + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Si è verificato un errore I/O per il torrent %1. +Motivo: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Conferma recursiva di download + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Il torrent %1 contiene file torrent, vuoi procedere al download di qeusti file? + + + + + Yes + + + + + + No + No + + + + Never + Mai + + + + Url download error + Errore download da indirizzo web + + + + Couldn't download file at url: %1, reason: %2. + Impossibile scaricare il file all'indirizzo: %1, motivo: %2. + + + + Global Upload Speed Limit + Limite globale upload + + + + Global Download Speed Limit + Limite globale download + + + + + Invalid password + Password non valida + + + + The password is invalid + La password non è valida + + + + Exiting qBittorrent + Uscire da qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Alcuni file sono ancora in trasferimento. +Sei sicuro di voler chiudere qBittorrent? + + + + Always + Sempre + + + + Open Torrent Files + Apri file torrent + + + + Torrent Files + File torrent + + + + Options were saved successfully. + Le opzioni sono state salvate. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Velocità DL: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Velocità UP: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Down: %2/s, Up: %3/s) + + + + A newer version is available + Una nuova versione è disponibile + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Una nuova versione di qBittorrent è disponibile su Sourceforge. +Vuoi aggiornare qBittorrent alla versione %1? + + + + Impossible to update qBittorrent + Impossibile aggiornare qBittorrent + + + + qBittorrent failed to update, reason: %1 + qBittorrent ha fallito l'aggiornamento, ragioni: %1 + + + + PeerAdditionDlg + + + Invalid IP + IP invalido + + + + The IP you provided is invalid. + L'IP fornito non è valido. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + IP + + + + Connection + Connessione + + + + Client + i.e.: Client application + Client + + + + Progress + i.e: % downloaded + Avanzamento + + + + Down Speed + i.e: Download speed + Velocità download + + + + Up Speed + i.e: Upload speed + Velocità upload + + + + Downloaded + i.e: total data downloaded + Scaricati + + + + Uploaded + i.e: total data uploaded + Caricati + + + + Add a new peer... + Aggiungi un nuovo peer... + + + + Copy IP + Copia IP + + + + Limit download rate... + Tasso di limite download... + + + + Limit upload rate... + Tasso di limite upload... + + + + Ban peer permanently + Banna peer permanentemente + + + + + Peer addition + Aggiunta di peer + + + + The peer was added to this torrent. + Il peer è stato aggiunto a questo torrent. + + + + The peer could not be added to this torrent. + Non è stato possibile aggiungere il peer a questo torrent. + + + + Are you sure? -- qBittorrent + Sei sicuro? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Sei sicuro di voler bannare permanentemente il peer selezionato? + + + + &Yes + &Sì + + + + &No + &No + + + + Manually banning peer %1... + Banno manualmente il peer %1... + + + + Upload rate limiting + Rapporto di upload in limitazione + + + + Download rate limiting + Rapporto di download in limitazione + + + + Preferences + + UI + User Interface + Interfaccia + + + + Downloads + Download + + + + Connection + Connessione + + + Bittorrent + Bittorrent + + + Proxy + Proxy + + + + Web UI + Interfaccia Web + + + Language: + Lingua: + + + + (Requires restart) + (Richiede riavvio) + + + Visual style: + Stile grafico: + + + Transfer list + Trasferimenti + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Usa colori di riga alternati + + + + Tray icon style: + Stile icona di sistema + + + + Normal + Normale + + + + Monochrome (Dark theme) + Monocromatico (Tema scuro) + + + + Monochrome (Light theme) + Monocromatico (Tema chiaro) + + + File system + File system + + + + This server requires a secure connection (SSL) + Questo server richiede una connessione sicura (SSL) + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + I parametri seguenti sono supportati +<ul> +<li>%f: Percorso torrent</li> +<li>%n: Nome torrent</li> +</ul> + + + + Listening Port + Porta in ascolto + + + + Connections Limits + Limiti di connessione + + + + Proxy Server + Server Proxy + + + + Otherwise, the proxy server is only used for tracker connections + Altrimenti, il server proxy viene solo usato per connessioni tracker + + + + Use proxy for peer connections + Usa il proxy per connessioni peer + + + + Global Rate Limits + Limiti Frequenza Globale + + + + Apply rate limit to uTP connections + Applica limiti di frequenza alle connessioni uTP + + + + Apply rate limit to transport overhead + Applica limiti di frequenza ai trasporti sovraccarico + + + + Alternative Global Rate Limits + Limiti di Frequenza Globale alternativi + + + + Schedule the use of alternative rate limits + Organizza l'uso di limti di frequenza alternativi + + + + Enable Local Peer Discovery to find more peers + Abilita Ricerca Locale Peer per trovare più peer + + + + Encryption mode: + Modalità criptazione: + + + + Prefer encryption + Preferisci criptazione + + + + Require encryption + Richiedi criptazione + + + + Disable encryption + Disabilita criptazione + + + Torrent queueing + Accodamento torrent + + + + Maximum active downloads: + Numero massimo di download attivi: + + + + Maximum active uploads: + Numero massimo di upload attivi: + + + + Maximum active torrents: + Numero massimo di torrent attivi: + + + + When adding a torrent + All'aggiunta di un torrent + + + Visual Appearance + Apparenza Visuale + + + + Action on double-click + Azioni con il doppio click + + + + Downloading torrents: + Scaricamento torrent: + + + Start / Stop + Avvia / Stop + + + + + Open destination folder + Apri cartella di destinazione + + + + Completed torrents: + Torrent Completati: + + + + Desktop + Desktop + + + + Show splash screen on start up + Mostra schermata di avvio in fase di start up + + + + Start qBittorrent minimized + Avvia qBittorrent minimizzato + + + Show qBittorrent icon in notification area + Mostra l'icona di qBittorrent nell'area di notifica + + + + Minimize qBittorrent to notification area + Minimizza qBittorrent nell'area di notifica + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Chiudi qBittorrent nell'area di notifica + + + + Display torrent content and some options + Mostra il contenuto del torrent ed alcune opzioni + + + Listening port + Porta in ascolto + + + + Port used for incoming connections: + Porta usata per connessioni in entrata: + + + + Random + Casuale + + + Enable UPnP port mapping + Abilita mappatura porte UPnP + + + Enable NAT-PMP port mapping + Abilita mappatura porte NAT-PMP + + + Connections limit + Limiti di connessione + + + + Global maximum number of connections: + Numero massimo globale di connessioni: + + + + Maximum number of connections per torrent: + Numero massimo di connessioni per torrent: + + + + Maximum number of upload slots per torrent: + Numero massimo di slot in upload per torrent: + + + + + Upload: + Upload: + + + + + Download: + Download: + + + + + + + KiB/s + KiB/s + + + Bittorrent features + Caratteristiche di Bittorrent + + + Enable DHT network (decentralized) + Abilita rete DHT (decentralizzata) + + + Use a different port for DHT and Bittorrent + Usa una porta diversa per DHT e Bittorrent + + + + DHT port: + Porta DHT: + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Scambia peer con client compatibili con qBittorrent (µTorrent, Vuze, ...) + + + Enable Peer Exchange / PeX (requires restart) + Abilita scambio peer / (PeX) (richiede riavvio) + + + Enable Local Peer Discovery + Abilita scoperta peer locali + + + Enabled + Attivata + + + Forced + Forzata + + + Disabled + Disattivata + + + HTTP Communications (trackers, Web seeds, search engine) + Comunicazioni HTTP (tracker, Seed Web, motore di ricerca) + + + + Host: + Host: + + + Peer Communications + Comunicazioni Peer + + + + SOCKS4 + SOCKS4 + + + + Type: + Tipo: + + + + + Options + Opzioni + + + + + Behavior + Comportamento + + + + Speed + Velocità + + + + Advanced + Avanzate + + + + User Interface Language: + Lingua di interfaccia d'uso: + + + + Transfer List + Lista trasferimenti + + + + + No action + Nessuna azione + + + + Append .!qB extension to incomplete files + Aggiungi .l'estensione !qB ai file incompleti + + + + Remove folder + Rimuovi cartella + + + + Copy .torrent files to: + Copia i file .torrent in: + + + Global speed limits + Limite di velocità globale + + + Alternative global speed limits + Limiti alternativi di velocità globale + + + + to + time1 to time2 + a + + + + Do not start the download automatically + The torrent will be added to download list in pause state + Non avviare il download automaticamente + + + + BitTorrent + BitTorrent + + + + Language + Lingua + + + + + Start / Stop Torrent + Avvia /Ferma Torrent + + + Use monochrome system tray icon (requires restart) + Usa icona monocromatica nella barra di sistema ( richiede riavvio) + + + + Ask for program exit confirmation + Chiedi per la conferma di chiusura del programma + + + + Show qBittorrent in notification area + Mostra qBittorrent nell'area di notifica + + + + Power Management + Gestione della Potenza + + + + Inhibit system sleep when torrents are active + Inibizione riposo del sistema quando i torrent sono attivi + + + + Hard Disk + Disco Rigido + + + + Save files to location: + Salva file nella posizione: + + + + Append the label of the torrent to the save path + Aggiungere l'etichetta del torrent per salvare il percorso + + + + Pre-allocate disk space for all files + Pre-alloca lo spazio su disco per tutti i file + + + + Keep incomplete torrents in: + Tieni torrent incompleti in: + + + Append .!qB extension to incomplete files' names + Aggiungi .l'estensione !qB ai file incompleti + + + + Automatically add torrents from: + Aggiungi automaticamente i torrent da: + + + + Add folder... + Aggiungi cartella... + + + + Email notification upon download completion + Notifica e-mail al completamento del download + + + + Destination email: + Destinazione e-mail: + + + + SMTP server: + Server SMTP: + + + + Run an external program on torrent completion + Avvia + + + Use %f to pass the torrent path in parameters + Usa %f per passare il percorso del torrent nei parametri + + + + Use UPnP / NAT-PMP port forwarding from my router + Usa port forwarding di UPnP / NAT-PMP dal mio router + + + Proxy server + Server proxy + + + + IP Filtering + Filtraggio IP + + + + Reload the filter + Ricarica il filtro + + + Schedule the use of alternative speed limits + Organizza l'uso dei limiti alternativi di velocità + + + + from + from (time1 to time2) + Da + + + + When: + Quando: + + + + Every day + Ogni giorno + + + + Week days + Giorni feriali + + + + Week ends + Fine settimana + + + + Privacy + Riservatezza + + + + Enable DHT (decentralized network) to find more peers + Abilita DHT ( rete decentralizzata) per cercare più peer + + + + Use a different port for DHT and BitTorrent + Usa una porta differente per DHT e BitTorrent + + + + Enable Peer Exchange (PeX) to find more peers + Abilita Scambio Peer ( PeX) per trovare più peer + + + + Look for peers on your local network + Cerca peer nella rete locale + + + + Torrent Queueing + Accodamento Torrent + + + + Share Ratio Limiting + Limitazione Rapporto di Condivisione + + + + Use UPnP / NAT-PMP to forward the port from my router + Usa UPnP /NAT-PMP per inoltrare la porta dal mio router + + + + Use HTTPS instead of HTTP + Usa HTTPS invece di HTTP + + + + Import SSL Certificate + Importa CErtificato SSL + + + + Import SSL Key + Importa Chiave SSL + + + + Certificate: + Certificato + + + + Key: + Chiave: + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + Bypass authentication for localhost + Aggira autenticazione per host locale + + + + Update my dynamic domain name + Aggiorna il mio nome di dominio dinamico + + + + Service: + Servizio + + + + Register + Registra + + + + Domain name: + + + + Protocol encryption: + Protocollo di criptazione: + + + Share ratio limiting + Limitazione del rapporto di condivisione + + + + Seed torrents until their ratio reaches + Favorisci il seed dei torrent finchè il rapport raggiunge + + + + then + allora + + + + Pause them + Metti in pausa + + + + Remove them + Rimuovilo + + + + (None) + (Nessuno) + + + + HTTP + HTTP + + + + + Port: + Porta: + + + + + + Authentication + Autenticazione + + + + + + + Username: + Nome utente: + + + + + + + Password: + Password: + + + + Enable bandwidth management (uTP) + Abilita gestione banda (uTP) + + + + Enable Web User Interface (Remote control) + Abilita l'interfaccia utente internet + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + Percorso filtro (.dat, .p2p, p2b): + + + HTTP Server + Server HTTP + + + + PreviewSelect + + + Name + Nome + + + + Size + Dimensione + + + + Progress + Avanzamento + + + + + + Preview impossible + Anteprima impossibile + + + + + + Sorry, we can't preview this file + Spiacente, non è possibile visuallizzare l'anteprima di questo file + + + + ProgramUpdater + + Could not create the file %1 + Il file non è stato creato %1 + + + Failed to download the update at %1 + %1 is an URL + Download dell'update fallito al %1 + + + + PropListDelegate + + + + Normal + Normal (priority) + Normale + + + + + High + High (priority) + Alta + + + + Mixed + Mixed (priorities + Mista + + + + Not downloaded + Non scaricato + + + + + Maximum + Maximum (priority) + Massima + + + + PropTabBar + + + General + Generali + + + + Trackers + Tracker + + + + Peers + Peer + + + + HTTP Sources + Codici HTTP + + + + Content + Contenuto + + + URL Seeds + Seed da URL + + + Files + File + + + + PropertiesWidget + + + Save path: + Directory di salvataggio: + + + + Torrent hash: + Hash del torrent: + + + + Comment: + Commento: + + + + Share ratio: + Rapporto di condivisione: + + + + + Downloaded: + Scaricati: + + + + Availability: + Disponibilità: + + + + Transfer + Trasferimento + + + + Uploaded: + Caricati: + + + + Wasted: + Sprecati: + + + + Time active: + Time (duration) the torrent is active (not paused) + Tempo attivo: + + + + Pieces size: + Dimensione parti: + + + + Torrent content: + Contenuto del torrent: + + + + Select All + Seleziona tutti + + + + Select None + Deseleziona tutti + + + + + Do not download + Non scaricati + + + + UP limit: + Limite Upload: + + + + DL limit: + Limite Download: + + + Time elapsed: + Tempo trascorso: + + + + Connections: + Connessioni: + + + + Reannounce in: + Riannuncia in: + + + + Information + Informazioni + + + + Created on: + Creato il: + + + General + Generali + + + Trackers + Tracker + + + Peers + Peer + + + URL seeds + Seed web + + + Files + File + + + + Priority + Priorità + + + + Normal + Normale + + + + Maximum + Massima + + + + High + Alta + + + + + this session + questa sessione + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Condiviso per %1 + + + + %1 max + e.g. 10 max + Max %1 + + + + + I/O Error + Errore I/O + + + + This file does not exist yet. + Questo file non esiste ancora. + + + + This folder does not exist yet. + Questa cartella non esiste ancora. + + + + Rename... + Rinomina... + + + + Rename the file + Rinomina file + + + + New name: + Nuovo nome: + + + + + The file could not be renamed + Impossibile rinominare il file + + + + This file name contains forbidden characters, please choose a different one. + Il nome di questo file contiene caratteri vietati, per favore scegli un nome differente. + + + + + This name is already in use in this folder. Please use a different name. + Questo nome è già in uso in questa cartella. Per favore sceglierne un altro. + + + + The folder could not be renamed + Impossibile rinominare cartella + + + + New url seed + New HTTP source + Nuovo seed web + + + + New url seed: + Nuovo seed web: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Questo seed web è già nella lista. + + + + + Choose save path + Scegliere una directory di salvataggio + + + Save path creation error + Errore nella creazione della directory di salvataggio + + + Could not create the save path + Impossibile creare la directory di salvataggio + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 ha raggiunto il rapporto massimo impostato. + + + + Removing torrent %1... + Rimozione torrent %1... + + + + Pausing torrent %1... + Torrent in pausa %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent è in ascolto sulla porta: TCP/%1 + + + UPnP support [ON] + Supporto UPnP [ON] + + + UPnP support [OFF] + Supporto UPnP [OFF] + + + NAT-PMP support [ON] + Supporto NAT-PMP [ON] + + + NAT-PMP support [OFF] + Supporto NAT-PMP [OFF] + + + + HTTP user agent is %1 + Lo user agent HTTP è %1 + + + Using a disk cache size of %1 MiB + Cache disco in uso %1 MiB + + + + DHT support [ON], port: UDP/%1 + Supporto DHT [ON], porta: UDP/%1 + + + + + DHT support [OFF] + Supporto DHT [OFF] + + + + PeX support [ON] + Supporto PeX [ON] + + + + PeX support [OFF] + Supporto PeX [OFF] + + + + Restart is required to toggle PeX support + È richiesto il riavvio per modificare il supporto PeX + + + Local Peer Discovery [ON] + Supporto scoperta peer locali [ON] + + + + Local Peer Discovery support [OFF] + Supporto scoperta peer locali [OFF] + + + + Encryption support [ON] + Supporto cifratura [ON] + + + + Encryption support [FORCED] + Supporto cifratura [FORZATO] + + + + Encryption support [OFF] + Supporto cifratura [OFF] + + + + Embedded Tracker [ON] + Tracker collegato [ON] + + + + Failed to start the embedded tracker! + Avvio fallito di collegamento al tracker! + + + + Embedded Tracker [OFF] + Tracker connesso + + + + The Web UI is listening on port %1 + L'interfaccia Web è in ascolto sulla porta %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Errore interfaccia web - Impossibile mettere l'interfaccia web in ascolto sulla porta %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' è stato rimosso dalla lista dei trasferimenti e dal disco. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' è stato rimosso dalla lista dei trasferimenti. + + + + '%1' is not a valid magnet URI. + '%1' non è un URI magnetico valido. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' è già nella lista dei download. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' ripreso. (recupero veloce) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' è stato aggiunto alla lista dei download. + + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP supporto [ON] + + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP supporto [OFF] + + + + Reporting IP address %1 to trackers... + Comunicaione indirizzo IP %1 ai tracker... + + + + Local Peer Discovery support [ON] + Supporto Ricerca Peer Locali [ON] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Impossibile decifrare il file torrent: '%1' + + + + This file is either corrupted or this isn't a torrent. + Questo file è corrotto o non è un torrent. + + + + Error: The torrent %1 does not contain any file. + Errore.Il torrent %1 non contiene alcun file. + + + + Note: new trackers were added to the existing torrent. + Nota: sono stati aggiunti nuovi tracker al torrent esistente. + + + + Note: new URL seeds were added to the existing torrent. + Nota: sono stati aggiunti nuovi URL al torrent esistente. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>è stato bloccato a causa dei tuoi filtri IP</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>è stato bannato a causa di parti corrotte</i> + + + + The network interface defined is invalid: %1 + L'interfaccia di rete definita non è valida: %1 + + + + Trying any other network interface available instead. + Si sta provando qualsiasi interfaccia di rete disponibile. + + + + Listening on IP address %1 on network interface %2... + Si sta ascoltano l'indirizzo IP %1 nell'interfaccia di rete %2... + + + + Failed to listen on network interface %1 + Fallito l'ascolto sull'interfaccia di rete %1 + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Download ricorsivo del file %1 incluso nel torrent %2 + + + + + Unable to decode %1 torrent file. + Impossibile decifrare il file torrent %1. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Il computer andrà in modalità riposo a meno che tu neghi per i prossimi 15 secondi... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Il computer verrà spento a meno che tu neghi entro i prossimi 15 secondi... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent adesso si chiude a meno che tu neghi entro i prossimi 15 secondi... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Analizzato con successo il cui filtro IP: 1% sono state applicate le regole. + + + + Error: Failed to parse the provided IP filter. + Errore: Impossibile analizzare la condizione del filtro IP. + + + + Torrent name: %1 + Nome del torrent %1 + + + + Torrent size: %1 + Dimensione del torrent %1 + + + + Save path: %1 + Salva percorso %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Questo torrent è stato scaricato in %1. + + + + Thank you for using qBittorrent. + Grazie per aver usato qBittorrent. + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 ha finito di scaricare + + + + An I/O error occured, '%1' paused. + Si è verificato un errore I/O, %1 in pausa. + + + + + Reason: %1 + Ragioni: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: mappatura porte fallita, messaggio: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: mappatura porte riuscita, messaggio: %1 + + + + File sizes mismatch for torrent %1, pausing it. + La dimensione del file discorda con il torrent %1, è in pausa. + + + + Fast resume data was rejected for torrent %1, checking again... + Il recupero veloce del torrent %1 è stato rifiutato, altro tentativo in corso... + + + + Url seed lookup failed for url: %1, message: %2 + Ricerca seed web fallita per l'url: %1, messaggio: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Download di '%1' in corso... + + + + RSS + + + Search + Ricerca + + + + New subscription + Nuova iscrizione + + + + + + Mark items read + Segna come letti + + + + Update all + Aggiorna tutti + + + + RSS Downloader... + Gestore download RSS... + + + + Settings... + Impostazioni... + + + RSS feed downloader... + Gestore di download dei feed RSS... + + + + New folder... + Nuova cartella... + + + + Manage cookies... + Gestisci cookie... + + + Feed URL + URL del Feed + + + + Rename... + Rinomina... + + + + + Update + Aggiorna + + + RSS feeds + Feed Rss + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrent:</span> <span style=" font-style:italic;">(doppio clic per scaricare)</span></p></body></html> + + + Article title + Titolo dell'articolo + + + + New subscription... + Nuova registrazione... + + + + + Update all feeds + Aggiorna tutti i Feed + + + + + Delete + Cancella + + + + Rename + Rinomina + + + + Download torrent + Scarica torrent + + + + Open news URL + Apri URL delle notizie + + + + Copy feed URL + Copia URL del Feed + + + + Refresh RSS streams + Aggiorna i flussi RSS + + + + RSSImp + + + Please type a rss stream url + Per favore digitare l'indirizzo di un flusso rss + + + + Stream URL: + Indirizzo del flusso: + + + + + Are you sure? -- qBittorrent + Sei sicuro? -- qBittorrent + + + + + &Yes + &Sì + + + + + &No + &No + + + + Please choose a folder name + Per favore scegliere un nome cartella + + + + Folder name: + Nome cartella: + + + + New folder + Nuova cartella + + + + Overwrite attempt + Tentativo di sovrascrittura + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Impossibile sovrascrivere %1. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Questo feed rss è già nella lista. + + + + Are you sure you want to delete these elements from the list? + Sei sicuro di voler cancellare questi elementi dalla lista? + + + + Are you sure you want to delete this element from the list? + Sei sicuro di voler cancellare questo elemento dalla lista? + + + + Please choose a new name for this RSS feed + Per favore scegliere un nuovo nome per questo Feed RSS + + + + New feed name: + Nuovo nome Feed: + + + + Name already in use + Nome già in uso + + + + This name is already used by another item, please choose another one. + Questo nome è già in uso da un altro elemento, per favore sceglierne un altro. + + + + Date: + Data: + + + + Author: + Autore: + + + + Unread + Non letti + + + + RssArticle + + No description available + Descrizione non disponibile + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Download automatico del torrent %1 dal Feed RSS %2... + + + + RssItem + + No description available + Descrizione non disponibile + + + + RssSettings + + RSS Reader Settings + Impostazioni lettore RSS + + + RSS feeds refresh interval: + Intervallo aggiornamento feed RSS: + + + minutes + minuti + + + Maximum number of articles per feed: + Numero massimo di articoli per feed: + + + + RssSettingsDlg + + + RSS Reader Settings + Impostazioni lettore RSS + + + + RSS feeds refresh interval: + Intervallo aggiornamento feed RSS: + + + + minutes + minuti + + + + Maximum number of articles per feed: + Numero massimo di articoli per feed: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Download automatico del torrent %1 dal Feed RSS %2... + + + + ScanFoldersModel + + + Watched Folder + Cartella controllata + + + + Download here + Scarica qui + + + + SearchCategories + + + All categories + Tutte le categorie + + + + Movies + Film + + + + TV shows + Programmi TV + + + + Music + Musica + + + + Games + Giochi + + + + Anime + Anime + + + + Software + Software + + + + Pictures + Immagini + + + + Books + Libri + + + + SearchEngine + + + Empty search pattern + Campo di ricerca vuoto + + + + Please type a search pattern first + Per favore inserire prima un campo di ricerca + + + + + Results + Risultati + + + + Searching... + Ricerca in corso... + + + + Cut + Taglia + + + + Copy + Copia + + + + Paste + Incolla + + + + Clear field + Azzera campo + + + + Clear completion history + Azzera cronologia completamento + + + + Confirmation + Confermazione + + + + Are you sure you want to clear the history? + Sei sicuro di voler cancellare la cronologia? + + + + + + Search + Ricerca + + + + Missing Python Interpreter + Manca l'interprete python + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Pyhton 2.x è necessario per usare il motore di ricerca ma non risulta installato. +Vuoi installarlo ora? + + + + Search Engine + Motore di Ricerca + + + + + Search has finished + La ricerca è terminata + + + + An error occured during search... + Si è verificato un errore durante la ricerca... + + + + + Search aborted + Ricerca annullata + + + + Download error + Errore download + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Il setup di python non è stato scaricato, motivi: %1 +Per favore installalo manualmente. + + + + Search returned no results + La ricerca non ha prodotto risultati + + + + Results + i.e: Search results + Risultati + + + + + Unknown + Sconosciuto + + + + SearchTab + + + Name + i.e: file name + Nome + + + + Size + i.e: file size + Dimensione + + + + Seeders + i.e: Number of full sources + Seeders + + + + Leechers + i.e: Number of partial sources + Leechers + + + + Search engine + Motore di ricerca + + + + ShutdownConfirmDlg + + + Shutdown confirmation + Conferma la chiusura + + + + SpeedLimitDialog + + + KiB/s + KiB/s + + + + StatusBar + + + + Connection status: + Stato della connessione: + + + + + No direct connections. This may indicate network configuration problems. + Nessuna connessione diretta. Questo potrebbe indicare problemi di configurazione della rete. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + D: %1 B/s - T: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + U: %1 B/s - T: %2 + + + + + DHT: %1 nodes + DHT: %1 nodi + + + + qBittorrent needs to be restarted + qBittorrent ha bisogno di essere riavviato + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent è stato appena aggiornato e ha bisogno di riavviarsi per rendere effettive le modifiche. + + + + + Connection Status: + Stato della connessione: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Non in linea. Questo di solito significa che qBittorrent non è riuscito a mettersi in ascolto sulla porta selezionata per le connessioni in entrata. + + + + Online + Online + + + + + %1/s + Per second + %1/s + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - T: %2 + + + + Click to switch to alternative speed limits + Clicca per passare ai limiti alternativi di velocità + + + + Click to switch to regular speed limits + Clicca per passare ai limiti normali di velocità + + + Click to disable alternative speed limits + Clicca per disabilitare i limiti alternativi di velocità + + + Click to enable alternative speed limits + Clicca per abilitare i limiti alternativi di velocità + + + + Global Download Speed Limit + Limite globale download + + + + Global Upload Speed Limit + Limite globale upload + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Seleziona una cartella da aggiungere al torrent + + + + Select a file to add to the torrent + Selezionare un file da aggiungere al torrent + + + Please type an announce URL + Per favore digitare un indirizzo web di annuncio + + + Announce URL: + Tracker URL + Indirizzo web di annuncio: + + + Please type a web seed url + Per favore inserire l'indirizzo di un seed web + + + Web seed URL: + Indirizzo del seed web: + + + + No input path set + Nessun percorso da inserire definito + + + + Please type an input path first + Per favore scegliere prima un percorso da inserire + + + + Select destination torrent file + Selezionare il file torrent di destinazione + + + + Torrent Files + File torrent + + + + + + Torrent creation + Creazione di un torrent + + + + Torrent creation was unsuccessful, reason: %1 + Creazione torrent fallita, motivo: %1 + + + + Created torrent file is invalid. It won't be added to download list. + Il torrent creato non è valido. Non sarà aggiunto alla lista dei download. + + + + Torrent was created successfully: + Il torrent è stato creato correttamente: + + + + TorrentFilesModel + + + Name + Nome + + + + Size + Dimensione + + + + Progress + Avanzamento + + + + Priority + Priorità + + + + TorrentImportDlg + + + Torrent Import + Importazione torrent + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Questo assistente ti aiuterà a condividere un torrent che hai appena scaricato con qBittorrent. + + + + Torrent file to import: + File torrent da importare: + + + + + ... + ... + + + + Content location: + Locazione del contenuto: + + + + Skip the data checking stage and start seeding immediately + Salta la fase di verifica dei dati e iniziare immediatamente il seeding + + + + Import + Importa + + + + Torrent file to import + File torrent da importare + + + + Torrent files (*.torrent) + File torrent (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 File + + + + Please provide the location of %1 + %1 is a file name + Fornire la posizione di %1 + + + + Please point to the location of the torrent: %1 + Si prega di scegliere il percorso del torrent: %1 + + + + Invalid torrent file + File torrent non valido + + + + This is not a valid torrent file. + Questo non è un file torrent valido. + + + + TorrentModel + + + Name + i.e: torrent name + Nome + + + + Size + i.e: torrent size + Dimensione + + + + Done + % Done + % Completo + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + + Seeds + i.e. full sources (often untranslated) + Seeds + + + + Peers + i.e. partial sources (often untranslated) + Peer + + + + Down Speed + i.e: Download speed + Velocità download + + + + Up Speed + i.e: Upload speed + Velocità upload + + + + Ratio + Share ratio + Rapporto + + + + ETA + i.e: Estimated Time of Arrival / Time left + ETA + + + + Label + Etichetta + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Aggiunto il + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Completato il + + + + Tracker + Tracker + + + + Down Limit + i.e: Download limit + Limite di download + + + + Up Limit + i.e: Upload limit + Limiti di upload + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + + + + + Amount left + Amount of data left to download (e.g. in MB) + Quantità rimanente + + + + Time Active + Time (duration) the torrent is active (not paused) + Tempo attivo + + + + TrackerList + + + URL + URL + + + + Status + Status + + + + Peers + Peer + + + + Message + Messaggio + + + + [DHT] + [DHT] + + + + [PeX] + [PeX] + + + + [LSD] + [LSD] + + + + + + + + Working + In funzione + + + + + + Disabled + Disattivata + + + + This torrent is private + Questo torrent è privato + + + + Updating... + In aggiornamento... + + + + + Not working + Non in funzione + + + + + Not contacted yet + Non ancora contattato + + + + Add a new tracker... + Aggiungi un nuovo tracker... + + + + Remove tracker + Rimuovi tracker + + + + Force reannounce + Forza riannuncio + + + + TrackersAdditionDlg + + + Trackers addition dialog + Dialogo per l'aggiunta dei tracker + + + + List of trackers to add (one per line): + Lista dei tracker da aggiungere (uno per riga): + + + + µTorrent compatible list URL: + URL lista compatibile µTorrent: + + + + I/O Error + Errore I/O + + + + Error while trying to open the downloaded file. + Errore durante il tentativo di apertura del file scaricato. + + + + No change + Nessun cambiamento + + + + No additional trackers were found. + Nessun tracker aggiuntivo è stato trovato. + + + + Download error + Errore download + + + + The trackers list could not be downloaded, reason: %1 + Non è stato possibile scaricare la lista dei tracker, motivo: %1 + + + + TransferListDelegate + + + Downloading + In download + + + + Paused + In pausa + + + + Queued + i.e. torrent is queued + In coda + + + + Seeding + Torrent is complete and in upload-only mode + In distribuzione + + + + Stalled + Torrent is waiting for download to begin + In stallo + + + + Checking + Torrent local data is being checked + Controllo in corso + + + + /s + /second (.i.e per second) + /s (i.e per secondo) + + + + KiB/s + KiB/second (.i.e per second) + KiB/s (i.e. per secondo) + + + + Seeded for %1 + e.g. Seeded for 3m10s + Condiviso per %1 + + + + TransferListFiltersWidget + + + + All + Tutti + + + + + Downloading + In download + + + + + Completed + Completati + + + + + Paused + In pausa + + + + + Active + Attivi + + + + + Inactive + Inattivi + + + + + All labels + Tutte le etichette + + + + + Unlabeled + Senza etichetta + + + + Remove label + Rimuovi etichetta + + + + Add label... + Aggiungi cartella... + + + + Resume torrents + Riprendi i torrent + + + + Pause torrents + Metti in pausa i torrent + + + + Delete torrents + Cancella i torrent + + + + New Label + Nuova etichetta + + + + Label: + Etichetta: + + + + Invalid label name + Nome etichetta non valido + + + + Please don't use any special characters in the label name. + Per favore non usare alcun carattere speciale nel nome dell'etichetta. + + + + TransferListWidget + + Down Speed + i.e: Download speed + Velocità download + + + Up Speed + i.e: Upload speed + Velocità upload + + + ETA + i.e: Estimated Time of Arrival / Time left + ETA + + + + Column visibility + Visibilità colonna + + + Name + i.e: torrent name + Nome + + + Size + i.e: torrent size + Dimensione + + + Done + % Done + % Completo + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + Seeds + i.e. full sources (often untranslated) + Seeds + + + Peers + i.e. partial sources (often untranslated) + Peers + + + Ratio + Share ratio + Rapporto + + + + Label + Etichetta + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Aggiunto il + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Completato il + + + Tracker + Tracker + + + Down Limit + i.e: Download limit + Limite di download + + + Up Limit + i.e: Upload limit + Limiti di upload + + + + Choose save path + Scegliere una directory di salvataggio + + + Save path creation error + Errore nella creazione della directory di salvataggio + + + Could not create the save path + Impossibile creare la directory di salvataggio + + + + Torrent Download Speed Limiting + Limitazione velocità download + + + + Torrent Upload Speed Limiting + Limitazione velocità upload + + + + New Label + Nuova etichetta + + + + Label: + Etichetta: + + + + Invalid label name + Nome etichetta invalida + + + + Please don't use any special characters in the label name. + Per favore non usare caratteri speciali per il nome dell'etichetta. + + + + Rename + Rinomina + + + + New name: + Nuovo nome: + + + + Resume + Resume/start the torrent + Riprendi/avvia il torrent + + + + Pause + Pause the torrent + Ferma + + + + Delete + Delete the torrent + Cancella + + + + Preview file... + Anteprima file... + + + + Limit share ratio... + Limite rapporto parti... + + + + Limit upload rate... + Tasso di limite upload... + + + + Limit download rate... + Tasso di limite download... + + + + Priority + Priorità + + + + Open destination folder + Apri cartella di destinazione + + + + Move up + i.e. move up in the queue + Muovi in alto + + + + Move down + i.e. Move down in the queue + Muovi in basso + + + + Move to top + i.e. Move to top of the queue + Muovi in cima + + + + Move to bottom + i.e. Move to bottom of the queue + Muovi in fondo + + + + Set location... + Seleziona locazione... + + + + Force recheck + Forza ricontrollo + + + + Copy magnet link + Copia link magnetico + + + + Super seeding mode + Modalità super seeding + + + + Rename... + Rinomina... + + + + Download in sequential order + Scarica in ordine sequenziale + + + + Download first and last piece first + Scarica prima il primo e l'ultimo pezzo + + + + New... + New label... + Nuova... + + + + Reset + Reset label + Azzera + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Upload Torrent/Limitazione Ratio Download + + + + Use global ratio limit + Usa limite ratio globale + + + + + + buttonGroup + pulsanteGruppo + + + + Set no ratio limit + Imposta nessun limite ratio + + + + Set ratio limit to + Imposta limite ratio a + + + + UsageDisplay + + + Usage: + Utilizzo: + + + + displays program version + mostra la versione del programma + + + + disable splash screen + disabilita spalsh screen + + + + displays this help message + mostra questo messaggio di aiuto + + + + changes the webui port (current: %1) + cambia la porta per l'interfaccia web (attuale: %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [file o url] scarica il torrent passato dall'utente (opzionale) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Vorrei ringraziare le seguenti persone che si sono rese volontarie per tradurre qBittorrent: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Per favore contattami se vorresti tradurre qBittorrent nella tua lingua. + + + + addPeerDialog + + + Peer addition + Aggiunta di peer + + + + IP + IP + + + + Port + Porta + + + + addTorrentDialog + + + Torrent addition dialog + Dialogo per l'aggiunta di un torrent + + + + Save path: + Directory di salvataggio: + + + + ... + ... + + + + Torrent size: + Dimensione del torrent: + + + + + Unknown + Sconosciuta + + + + Free disk space: + Spazio libero sul disco: + + + + Label: + Etichetta: + + + + Torrent content: + Contenuto del torrent: + + + + Select All + Seleziona tutti + + + + Select None + Deseleziona tutti + + + + Download in sequential order (slower but good for previewing) + Scarica nell'ordine giusto (più lento ma migliore per le anteprime) + + + + Skip file checking and start seeding immediately + Salta il controllo file e inizia subito la distribuzione + + + + + Do not download + Non scaricare + + + + Add to download list in paused state + Aggiungi fra i download mettendolo in pausa + + + + Add + Aggiungi + + + + Cancel + Cancella + + + + Normal + Normale + + + + High + Alta + + + + Maximum + Massima + + + + authentication + + + + Tracker authentication + Autenticazione del tracker + + + + Tracker: + Tracker: + + + + Login + Accesso + + + + Username: + Nome utente: + + + + Password: + Password: + + + + Log in + Log in + + + + Cancel + Annulla + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Conferma di cancellazione - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Sei sicuro di voler cancellare i torrent selezionati dalla lista dei trasferimenti? + + + + Remember choice + Ricorda scelta + + + + Also delete the files on the hard disk + Elimina anche il relativo file nell'hard disk + + + + createTorrentDialog + + + Torrent Creation Tool + Strumento di creazione torrent + + + + Cancel + Annulla + + + + Torrent file creation + Creazione file torrent + + + Announce urls (trackers): + Indirizzo.web.di annuncio (tracker): + + + Comment (optional): + Commento (facoltativo): + + + Web seeds urls (optional): + Indirizzo dei seed web (facoltativo): + + + + File or folder to add to the torrent: + File o cartella da aggiungere al torrent: + + + + Add file + Aggiungi file + + + + Add folder + Aggiungi cartella + + + + Tracker URLs: + URL dei tracker: + + + + Web seeds urls: + URL seed web: + + + + Comment: + Commento: + + + + Piece size: + Dimensione parte: + + + + 32 KiB + 32 KiB + + + + 64 KiB + 64 KiB + + + + 128 KiB + 128 KiB + + + + 256 KiB + 256 KiB + + + + 512 KiB + 512 KiB + + + + 1 MiB + 1 MiB + + + + 2 MiB + 2 MiB + + + + 4 MiB + 4 MiB + + + + Auto + Auto + + + + Private (won't be distributed on DHT network if enabled) + Privato (non sarà condiviso su rete DHT se abilitata) + + + + Start seeding after creation + Iniziare a distribuire dopo la creazione + + + + Create and save... + Crea e salva... + + + + Progress: + Avanzamento: + + + + createtorrent + + Select destination torrent file + Selezionare il file torrent di destinazione + + + Torrent Files + File torrent + + + No input path set + Nessun percorso da inserire definito + + + Please type an input path first + Per favore scegliere prima un percorso da inserire + + + Torrent creation + Creazione di un torrent + + + Torrent was created successfully: + Il torrent è stato creato correttamente: + + + Select a folder to add to the torrent + Seleziona una cartella da aggiungere al torrent + + + Please type an announce URL + Per favore digitare un indirizzo web di annuncio + + + Torrent creation was unsuccessful, reason: %1 + Creazione torrent fallita, motivo: %1 + + + Announce URL: + Tracker URL + URL del tracker + Indirizzo web di annuncio: + + + Please type a web seed url + Per favore inserire l'indirizzo di un seed web + + + Web seed URL: + Indirizzo del seed web: + + + Select a file to add to the torrent + Selezionare un file da aggiungere al torrent + + + Created torrent file is invalid. It won't be added to download list. + Il torrent creato non è valido. Non sarà aggiunto alla lista dei download. + + + + downloadFromURL + + Download Torrents from URLs + Scarica torrent da indirizzo web + + + Only one URL per line + Solo un indirizzo.web per riga + + + + Add torrent links + Aggiungi link torrent + + + + Both HTTP and Magnet links are supported + Sono supportati sia HTTP che Magnet Link + + + + Download + Download + + + + Cancel + Annulla + + + + Download from urls + Download da indirizzo web + + + + No URL entered + Nessun indirizzo.web inserito + + + + Please type at least one URL. + Per favore inserire almeno un indirizzo web. + + + + downloadThread + + I/O Error + Errore I/O + + + The remote host name was not found (invalid hostname) + L'host remoto non è stato trovato (hostname invalido) + + + The operation was canceled + L'operazione è stata annullata + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Il server remoto ha interrotto la connessione prematuramente, prima che la risposta completa fosse ricevuta e processata + + + The connection to the remote server timed out + La connessione al server remoto è scaduta + + + SSL/TLS handshake failed + Handshake SSL/TLS fallito + + + The remote server refused the connection + Il server remoto ha rifiutato la connessione + + + The connection to the proxy server was refused + La connessione al server proxy è stata rifiutata + + + The proxy server closed the connection prematurely + Il server proxy ha interrotto la connessione prematuramente + + + The proxy host name was not found + L'hostname del proxy non è stato trovato + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + La connessione al proxy è scaduta o il proxy non ha risposto in tempo alla richiesta + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Il proxy richiede l'autenticazione per onorare la richiesta ma non ha accettato le credenziali fornite + + + The access to the remote content was denied (401) + L'accesso al contenuto remoto è stato negato (401) + + + The operation requested on the remote content is not permitted + L'operazione richiesta sul contenuto remoto non è permessa + + + The remote content was not found at the server (404) + Il contenuto remoto non è stato trovato sul server (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Il server remoto richiede l'autenticazione per fornire il contenuto ma le credenziali fornite non sono state accettate + + + The Network Access API cannot honor the request because the protocol is not known + Le API dell'Accesso Remoto non possono onorare la richiesta perché il protocollo è sconosciuto + + + The requested operation is invalid for this protocol + L'operazione richiesta non è valida per questo protocollo + + + An unknown network-related error was detected + Un errore di rete sconosciuto è stato rilevato + + + An unknown proxy-related error was detected + Un errore proxy sconosciuto è stato rilevato + + + An unknown error related to the remote content was detected + Un errore sconosciuto del contenuto remoto è stato rilevato + + + A breakdown in protocol was detected + Un malfunzionamento del protocollo è stato rilevato + + + Unknown error + Errore sconosciuto + + + + engineSelect + + + Search plugins + Plugin di ricerca + + + + Installed search engines: + Motori di ricerca installati: + + + + Name + Nome + + + + Url + Indirizzo + + + + + Enabled + Attivato + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Puoi ottenere altri plugin di ricerca qui: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Installane uno nuovo + + + + Check for updates + Controlla gli aggiornamenti + + + + Close + Chiudi + + + Enable + Abilita + + + Disable + Disabilita + + + + Uninstall + Disinstalla + + + + engineSelectDlg + + + Uninstall warning + Avviso di disinstallazione + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Alcuni plugin non possono essere disinstallati perché sono inclusi in qBittorrent. + Solo quelli aggiunti possono essere disinstallati. +Comunque, quei plugin sono stati disabilitati. + + + + Uninstall success + Disinstallazione riuscita + + + + Select search plugins + Seleziona plugin di ricerca + + + + qBittorrent search plugins + Plugin di ricerca di qBittorrent + + + + + + + + Search plugin install + Installare plugin di ricerca + + + + + + Yes + + + + + + + + No + No + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Una versione più recente del plugin di ricerca %1 è già installata. + + + + + + + Search plugin update + Aggiornato il plugin di ricerca + + + + + Sorry, update server is temporarily unavailable. + Spiacente, il server è momentaneamente non disponibile. + + + + All your plugins are already up to date. + Tutti i plugin sono già aggiornati. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + Non è stato possibile aggiornare %1, mantengo la versione attuale. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Non è stato possibile installare il plugin di ricerca %1. + + + + All selected plugins were uninstalled successfully + Tutti i plugin selezionati sono stati disinstallati con successo + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + Il plugin di ricerca %1 è stato aggiornato con successo. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Il plugin di ricerca %1 è stato installato con successo. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Spiacente, l'installazione del plugin di ricerca %1 è fallita. + + + + New search engine plugin URL + Indirizzo del nuovo plugin di ricerca + + + + URL: + Indirizzo web: + + + + misc + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent arresterà il sistema adesso perchè tutti i download sono stati completati. + + + + B + bytes + B + + + + KiB + kibibytes (1024 bytes) + KiB + + + + MiB + mebibytes (1024 kibibytes) + MiB + + + + GiB + gibibytes (1024 mibibytes) + GiB + + + + TiB + tebibytes (1024 gibibytes) + TiB + + + + %1h %2m + e.g: 3hours 5minutes + %1h %2m + + + + %1d %2h + e.g: 2days 10hours + %1d %2h + + + + + + + + + Unknown + Sconosciuto + + + + Unknown + Unknown (size) + Sconosciuta + + + + < 1m + < 1 minute + < 1m + + + + %1m + e.g: 10minutes + %1m + + + + options_imp + + + + + + Choose a save directory + Scegliere una directory di salvataggio + + + + Add directory to scan + Aggiungi una cartella da scansionare + + + + Folder is already being watched. + La cartella è già stata controllata. + + + + Folder does not exist. + La cartella non esiste. + + + + Folder is not readable. + La cartella è illeggibile. + + + + Failure + Fallimento + + + + Failed to add Scan Folder '%1': %2 + Impossibile aggiungere lo scan alla cartella '%1: %2 + + + + + Choose export directory + Scegli cartella di esportazione + + + + + Choose an ip filter file + Scegliere un file ip filter + + + + + Filters + Filtri + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + Errore di analisi + + + + Failed to parse the provided IP filter + Impossibile analizzare la condizione del filtro IP + + + + Successfully refreshed + Aggiornato con successo + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Analizzato correttamente la condizione del filtro IP:% 1 le regole sono state applicate. + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + + pluginSourceDlg + + + Plugin source + Origine del plugin + + + + Search plugin source: + Origine del plugin di ricerca: + + + + Local file + File locale + + + + Web link + Link web + + + + preview + + + Preview selection + Anteprima della selezione + + + + File preview + Anteprima del file + + + + The following files support previewing, <br>please select one of them: + I seguenti file supportano l'anteprima, <br>per favore sceglierne uno: + + + + Preview + Anteprima + + + + Cancel + Annulla + + + + previewSelect + + Preview impossible + Anteprima impossibile + + + Sorry, we can't preview this file + Spiacente, non è possibile visuallizzare l'anteprima di questo file + + + Name + Nome + + + Size + Dimensione + + + Progress + Avanzamento + + + + search_engine + + + + Search + Ricerca + + + + Status: + Stato: + + + + Stopped + Fermato + + + + Download + Download + + + + Go to description page + Vai alla pagina di descrizione + + + + Search engines... + Motori di ricerca... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + Impossibile decifrare il file torrent: + + + + + + Choose save path + Scegliere una directory di salvataggio + + + + Unable to decode magnet link: + Impossibile decifrare il link magnetico: + + + + Magnet Link + Link magnetico + + + + Rename... + Rinomina... + + + + Rename the file + Rinomina file + + + + New name: + Nuovo nome: + + + + + The file could not be renamed + Impossibile rinominare il file + + + + This file name contains forbidden characters, please choose a different one. + Il nome di questo file contiene caratteri vietati, per favore scegliere un altro nome. + + + + + This name is already in use in this folder. Please use a different name. + Questo nome è già in uso in questa cartella. Per favore sceglierne un altro. + + + + The folder could not be renamed + Impossibile rinominare la cartella + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 rimasti dopo il download del torrent) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 ancora per il download del torrent) + + + + Empty save path + Directory di salvataggio vuota + + + + Please enter a save path + Inserire per favore una directory di salvataggio + + + + Save path creation error + Errore nella creazione della directory di salvataggio + + + + Could not create the save path + Impossibile creare la directory di salvataggio + + + + Invalid label name + Nome etichetta invalido + + + + Please don't use any special characters in the label name. + Per favore non usare alcun carattere speciale nel nome dell'etichetta. + + + + Seeding mode error + Errore modalità upload + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Hai deciso di saltare il controllo dei file. Tuttavia, i file locali nella attuale cartella di destinazione sembrano non esistere. Per favore disattiva questa funzione o aggiorna il percorso di salvataggio. + + + + Invalid file selection + Selezione file non valida + + + + You must select at least one file in the torrent + Devi selezionare almeno un file nel torrent + + + + Priority + Priorità + + + diff --git a/src/lang/qbittorrent_ja.qm b/src/lang/qbittorrent_ja.qm new file mode 100644 index 0000000000000000000000000000000000000000..b89a626155a364b446cd8a3f48d9d371f02515a6 GIT binary patch literal 98040 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 EAH=jdasU7T literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_ja.ts b/src/lang/qbittorrent_ja.ts new file mode 100644 index 000000000..e1c96bdd2 --- /dev/null +++ b/src/lang/qbittorrent_ja.ts @@ -0,0 +1,5231 @@ + + + + + AboutDlg + + + About qBittorrent + qBittorrent について + + + + About + 情報 + + + + Author + 作者 + + + + Name: + 名前: + + + + Country: + 国籍: + + + + E-mail: + 電子メール: + + + + Christophe Dumez + Christophe Dumez + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Qt4 toolkit および libtorrent-rasterbar ベースの C++ でプログラムされた高度な BitTorrent クライアント<br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">ホームページ:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">バグトラッカー:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">フォーラム:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + France + フランス + + + + Translation + 翻訳 + + + + License + ライセンス + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + + chris@qbittorrent.org + chris@qbittorrent.org + + + + Thanks to + 謝辞 + + + + AdvancedSettings + + + Disk write cache size + ディスク書き込みキャッシュサイズ + + + + MiB + MiB + + + + Outgoing ports (Min) [0: Disabled] + 送出側ポート (最小) [0: 無効] + + + + Outgoing ports (Max) [0: Disabled] + 送出側ポート (最大) [0: 無効] + + + + Recheck torrents on completion + Torrent 完了時に再チェックする + + + + Transfer list refresh interval + 転送リストのリフレッシュ間隔 + + + + ms + milliseconds + ms + + + + Setting + 設定 + + + + Value + Value set for this setting + + + + + Resolve peer countries (GeoIP) + ピアの国籍を解決する (GeoIP) + + + + Resolve peer host names + ピアのホスト名を解決する + + + + Maximum number of half-open connections [0: Disabled] + 最大半開接続数 [0 無効] + + + + Strict super seeding + 厳密なスーパーシード + + + + Network Interface (requires restart) + ネットワークインターフェイス (再起動が必要) + + + + Exchange trackers with other peers + 他のピアとトラッカー情報を交換する + + + + Any interface + i.e. Any network interface + どれか + + + + IP Address to report to trackers (requires restart) + トラッカーに報告する IP アドレス (再起動が必要) + + + + Display program on-screen notifications + オンスクリーン通知を表示する + + + + Enable embedded tracker + 埋め込みトラッカーを有効にする + + + + Embedded tracker port + 埋め込みトラッカーポート + + + + Check for software updates + ソフトウェアアップデートをチェックする + + + + Use system icon theme + システムのアイコンテーマを使用する + + + + Confirm torrent deletion + Torrent の削除を確認する + + + + Ignore transfer limits on local network + ローカルネットワーク内では転送速度を制限しない + + + + AutomatedRssDownloader + + + Automated RSS Downloader + 自動 RSS ダウンローダ + + + + Enable the automated RSS downloader + 自動 RSS ダウンローダを有効にする + + + + Download rules + ダウンロードルール + + + + Rule definition + ルール定義 + + + + Must contain: + マッチする文字列: + + + + Must not contain: + 除外する文字列: + + + + Use regular expressions + 正規表現を使用する + + + + Import... + インポート... + + + + Export... + エクスポート... + + + + ... + ... + + + + Assign label: + 割り当てレベル: + + + + Save to a different directory + 別のディレクトリへ保存する + + + + Save to: + 保存先: + + + + Apply rule to feeds: + ルールを適用するフィード: + + + + Matching RSS articles + マッチする RSS 記事 + + + + New rule name + 新しいルール名 + + + + Please type the name of the new download rule. + 新しいダウンロードルールの名前を入力してください。 + + + + + Rule name conflict + ルール名の衝突 + + + + + A rule with this name already exists, please choose another name. + この名前のルールはすでに存在しています。別の名前を選んでください。 + + + + Are you sure you want to remove the download rule named %1? + ダウンロードルール %1 を削除してよろしいですか? + + + + Are you sure you want to remove the selected download rules? + 選択したダウンロードルールを削除してよろしいですか? + + + + Rule deletion confirmation + ルールの削除の確認 + + + + Destination directory + 保存先ディレクトリ + + + + Invalid action + 不正な操作 + + + + The list is empty, there is nothing to export. + リストは空です。エクスポートするものはありません。 + + + + Where would you like to save the list? + どこへリストを保存しますか? + + + + Rules list (*.rssrules) + ルールリスト (*.rssrules) + + + + I/O Error + I/O エラー + + + + Failed to create the destination file + 保存先ファイルの作成に失敗しました + + + + Please point to the RSS download rules file + RSS ダウンロードルールファイルを指定してください + + + + Rules list (*.rssrules *.filters) + ルールリスト (*.rssrules *.filters) + + + + Import Error + インポートエラー + + + + Failed to import the selected rules file + 選択したルールファイルのインポートに失敗しました + + + + Add new rule... + 新しいルールの追加... + + + + Delete rule + ルールの削除 + + + + Rename rule... + ルール名の変更... + + + + Delete selected rules + 選択したルールの削除 + + + + Rule renaming + ルール名の変更 + + + + Please type the new rule name + 新しいルール名を入力してください + + + + Regex mode: use Perl-like regular expressions + 正規表現モード: Perl ライクな正規表現を使用してください + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + ワイルドカードモード: <ul><li>? はあらゆる 1 文字にマッチします</li><li>* は 0 個以上のあらゆる文字にマッチします</li><li>空白で区切ると AND 条件とみなされます</li></ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + ワイルドカードモード: <ul><li>? はあらゆる 1 文字とマッチします</li><li>* は 0 個以上のあらゆる文字にマッチします</li><li>| で区切ると OR 条件とみなされます</li></ul> + + + + CookiesDlg + + + Cookies management + Cookie 管理 + + + + Key + As in Key/Value pair + キー + + + + Value + As in Key/Value pair + + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Cookie の共通キー: '%1', '%2'. +この情報はウェブブラウザの初期設定から確認できるはずです。 + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + ダイナミック DNS は正常に更新されました。 + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + ダイナミック DNS エラー: サービスは一時的に利用できません。30 分後に再試行します。 + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + ダイナミック DNS エラー: 設定されたホスト名は指定アカウント下に存在しません。 + + + + Dynamic DNS error: Invalid username/password. + ダイナミック DNS エラー: 不正なユーザ名/パスワードです。 + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + ダイナミック DNS エラー: qBittorrent はこのサービスによってブラックリストに載せられています。http://bugs.qbittorrent.org にバグ報告してください。 + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + ダイナミック DNS エラー: このサービスから %1 が返されました。http://bugs.qbittorrent.org にバグ報告してください。 + + + + Dynamic DNS error: Your username was blocked due to abuse. + ダイナミック DNS エラー: あなたのユーザ名はその悪用を理由にブロックされています。 + + + + Dynamic DNS error: supplied domain name is invalid. + ダイナミック DNS エラー: 設定されたドメイン名が不正です。 + + + + Dynamic DNS error: supplied username is too short. + ダイナミック DNS エラー: 設定されたユーザ名が短すぎます。 + + + + Dynamic DNS error: supplied password is too short. + ダイナミック DNS エラー: 設定されたパスワードが短すぎます。 + + + + DownloadThread + + + + I/O Error + I/O エラー + + + + The remote host name was not found (invalid hostname) + リモートホスト名が見つかりませんでした (不正なホスト名) + + + + The operation was canceled + 操作はキャンセルされました + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + リモートサーバは応答全体が受信および処理される前に接続を切断しました + + + + The connection to the remote server timed out + リモートサーバへの接続がタイムアウトしました + + + + SSL/TLS handshake failed + SSL/TLS ハンドシェイクが失敗しました + + + + The remote server refused the connection + リモートサーバが接続を拒否しました + + + + The connection to the proxy server was refused + プロキシサーバへの接続が拒否されました + + + + The proxy server closed the connection prematurely + プロキシサーバが接続を切断しました + + + + The proxy host name was not found + プロキシホスト名が見つかりませんでした + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + プロキシへの接続がタイムアウトしたかプロキシは要求の送信中に応答しませんでした + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + プロキシは要求を履行するために認証を必要としますが提出した証明書のどれも受け付けませんでした + + + + The access to the remote content was denied (401) + リモートコンテンツへのアクセスは拒否されました (401) + + + + The operation requested on the remote content is not permitted + リモートコンテンツに対して要求された操作は許可されていません + + + + The remote content was not found at the server (404) + リモートコンテンツはサーバ上に見つかりませんでした (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + リモートサーバはコンテンツを供給するために認証を必要としますが提出した証明書は受け付けられませんでした + + + + The Network Access API cannot honor the request because the protocol is not known + プロトコルが不明なためネットワークアクセス API は要求を履行できません + + + + The requested operation is invalid for this protocol + 要求された操作はこのプロトコルでは無効です + + + + An unknown network-related error was detected + 未知のネットワーク関連エラーが検出されました + + + + An unknown proxy-related error was detected + 未知のプロキシ関連エラーが検出されました + + + + An unknown error related to the remote content was detected + 未知のリモートコンテンツ関連エラーが検出されました + + + + A breakdown in protocol was detected + プロトコルの破壊が検出されました + + + + Unknown error + 未知のエラーです + + + + EventManager + + + + Working + 動作中 + + + + Updating... + 更新しています... + + + + + Not working + 非動作中 + + + + + Not contacted yet + 未接触 + + + + + this session + このセッション + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + シード時間 %1 + + + + %1 max + e.g. 10 max + 最大 %1 + + + + + %1/s + e.g. 120 KiB/s + %1/s + + + + ExecutionLog + + + General + 全般 + + + + Blocked IPs + ブロック IP + + + + FeedListWidget + + + RSS feeds + RSS フィード + + + + Unread + 未読 + + + + HeadlessLoader + + + Information + 情報 + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + qBittorrent を操作するには Web UI http://localhost:%1 にアクセスしてください + + + + The Web UI administrator user name is: %1 + Web UI 管理者ユーザ名: %1 + + + + The Web UI administrator password is still the default one: %1 + Web UI 管理者パスワードはまだデフォルトのままです: %1 + + + + This is a security risk, please consider changing your password from program preferences. + これはセキュリティリスクになります。プログラムインターフェイスからパスワードを変更してください。 + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + あなたの IP アドレスはあまりに多くの回数認証に失敗したためアクセス禁止になりました。 + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - T: %2 + + + + HttpServer + + + File + ファイル + + + + Edit + 編集 + + + + Help + ヘルプ + + + + Download Torrents from their URL or Magnet link + URL やマグネットリンクから Torrent をダウンロード + + + + Only one link per line + 1 行に 1 リンクを入力してください + + + + Download local torrent + ローカルの Torrent ファイルでダウンロード + + + + Torrent files were correctly added to download list. + Torrent ファイルは正しくダウンロードリストに追加されました。 + + + + Point to torrent file + Torrent ファイルを指定してください + + + + Download + ダウンロード + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + 選択した Torrent を転送リストおよびハードディスクから削除しますか? + + + + Download rate limit must be greater than 0 or disabled. + ダウンロード速度上限は 0 より大きいか無効でなくてはなりません。 + + + + Upload rate limit must be greater than 0 or disabled. + アップロード速度上限は 0 より大きいか無効でなくてはなりません。 + + + + Maximum number of connections limit must be greater than 0 or disabled. + 最大接続数は 0 より大きいか無効でなくてはなりません。 + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Torrent ごとの最大接続数は 0 より大きいか無効でなくてはなりません。 + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + 最大アップロートスロット数は 0 より大きいか無効でなくてはなりません。 + + + + Unable to save program preferences, qBittorrent is probably unreachable. + プログラム設定の保存ができません。qBittorrent はおそらく通信可能状態にありません。 + + + + Language + 言語 + + + + Downloaded + Is the file downloaded or not? + コンテンツタブのダウンロードする/しないチェックボックスカラムのタイトル QtUIでは Name + ダウンロード + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + 着信接続で使用するポートは 1024 より大きく 65535 より小さくなくてはなりません。 + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Web UI で使用するポートは 1024 より大きく 65535 より小さくなくてはなりません。 + + + + The Web UI username must be at least 3 characters long. + Web UI ユーザ名は 3 文字以上でなくてはなりません。 + + + + The Web UI password must be at least 3 characters long. + Web UI パスワードは 3 文字以上でなくてはなりません。 + + + + Save + 保存 + + + + qBittorrent client is not reachable + qBittorrent クライアントと通信できません + + + + HTTP Server + HTTP サーバ + + + + The following parameters are supported: + 以下のパラメータがサポートされています: + + + + Torrent path + Torrent のパス + + + + Torrent name + Torrent の名前 + + + + LegalNotice + + + Legal Notice + 法的通知 + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent はファイル共有プログラムです。あなたが Torrent を動作させるとき、そのデータはそれがアップロードされることで他人からも利用できるようになります。いかなるコンテンツでもあなたが共有することはあなた個人の責任になります。 + +これ以上の通知は行われません。 + + + + Press %1 key to accept and continue... + 続行するには %1 キーを押してください... + + + + Legal notice + 法的通知 + + + + Cancel + キャンセル + + + + I Agree + 同意する + + + + LineEdit + + + Clear the text + テキストをクリア + + + + MainWindow + + + &Edit + 編集(&E) + + + + &Tools + ツール(&T) + + + + &File + ファイル(&F) + + + + &Help + ヘルプ(&H) + + + + &View + 表示(&V) + + + + &Options... + オプション(&O)... + + + + &About + 情報(&A) + + + + &Pause + 停止(&P) + + + + &Delete + 削除(&D) + + + + P&ause All + すべて停止(&A) + + + + &Resume + 再開(&R) + + + + &Add torrent file... + Torrent ファイルの追加(&A)... + + + + + Exit + 終了 + + + + R&esume All + すべて再開(&E) + + + + Visit &Website + ウェブサイト(&W) + + + + Auto-Shutdown on downloads completion + ダウンロード完了時の自動シャットダウン + + + + Torrent &creator + Torrent クリエータ(&C) + + + + Report a &bug + バグを報告(&B) + + + + Set upload limit... + アップロード制限の設定... + + + + Set download limit... + ダウンロード制限の設定... + + + + &Documentation + ドキュメント(&D) + + + + Set global download limit... + 全体のダウンロード速度上限の設定... + + + + Set global upload limit... + 全体のアップロード速度上限の設定... + + + + + Alternative speed limits + 代替速度制限 + + + + &RSS reader + RSS リーダ(&R) + + + + Search &engine + 検索エンジン(&E) + + + + Exit qBittorrent + qBittorrent を終了 + + + + Suspend system + システムをサスペンド + + + + Shutdown system + システムをシャットダウン + + + + Disabled + 無効 + + + + + Lock qBittorrent + qBittorrent をロック + + + + Ctrl+L + Ctrl+L + + + + Import existing torrent... + 既存の Torrent のインポート... + + + + Import torrent... + Torrent のインポート... + + + + Donate money + 寄付する + + + + If you like qBittorrent, please donate! + qBittorrent を気に入っていただけましたか? でしたら寄付をお願いします! + + + + Execution &Log + 実行ログ(&L) + + + + + Execution Log + 実行ログ + + + + Top &tool bar + トップツールバー(&T) + + + + Add &link to torrent... + Torrent へのリンクの追加(&L)... + + + + Display top tool bar + トップツールバーを表示します + + + + &Speed in title bar + タイトルバーに速度を表示(&S) + + + + Show transfer speed in title bar + タイトルバーに転送スピードを表示します + + + + Decrease priority + 優先度を下げる + + + + Increase priority + 優先度を上げる + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + パスワードの設定... + + + + Transfers + 転送 + + + + Torrent file association + Torrent ファイルの関連付け + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent は Torrent ファイルやマグネットリンクを開くデフォルトアプリケーションではありません。 +qBittorrent を Torrent ファイルおよびマグネットリンクに関連付けますか? + + + + + + UI lock password + UI ロックパスワード + + + + + + Please type the UI lock password: + UI ロックパスワードを入力してください: + + + + The password should contain at least 3 characters + パスワードは 3 文字以上でなくてはなりません + + + + Password update + パスワードの更新 + + + + The UI lock password has been successfully updated + UI ロックパスワードは正常に更新されました + + + + RSS + RSS + + + + Search + 検索 + + + + Transfers (%1) + 転送 (%1) + + + + Download completion + ダウンロード完了 + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 はダウンロードが完了しました。 + + + + I/O Error + i.e: Input/Output Error + I/O エラー + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Torrent %1 で I/O error が発生しました。 + 理由: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + 再帰的ダウンロードの確認 + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent %1 は Torrent ファイルを含んでいます。それらのダウンロードも開始しますか? + + + + + Yes + はい + + + + + No + いいえ + + + + Never + すべてしない + + + + Url download error + URL のダウンロード エラー + + + + Couldn't download file at url: %1, reason: %2. + 次の url にあるファイルをダウンロードできませんでした: %1、理由: %2。 + + + + Global Upload Speed Limit + 全体のアップロード速度上限 + + + + Global Download Speed Limit + 全体のダウンロード速度上限 + + + + + Invalid password + 不正なパスワード + + + + The password is invalid + パスワードが正しくありません + + + + Exiting qBittorrent + qBittorrent の終了 + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + 現在転送中のファイルがあります。。 +qBittorrent を終了しますか? + + + + Always + 常に終了する + + + + Open Torrent Files + Torrent ファイルを開く + + + + Torrent Files + Torrent ファイル + + + + Options were saved successfully. + オプションは正常に保存されました。 + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + DL 速度: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + UP 速度: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (DL: %2/s, UP: %3/s) + + + + A newer version is available + 新しいバージョンが利用可能です + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + 新しいバージョンの qBittorrent が Sourceforgeから入手可能です。 +qBittorrent をバージョン %1 へアップデートしますか? + + + + Impossible to update qBittorrent + Impossible のアップデートはできません + + + + qBittorrent failed to update, reason: %1 + qBittorrent のアップデートに失敗しました。理由: %1 + + + + PeerAdditionDlg + + + Invalid IP + 不正な IP + + + + The IP you provided is invalid. + 指定された IP は正しくありません。 + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + IP + + + + Connection + 接続 + + + + Client + i.e.: Client application + クライアント + + + + Progress + i.e: % downloaded + 進行状況 + + + + Down Speed + i.e: Download speed + DL 速度 + + + + Up Speed + i.e: Upload speed + UP 速度 + + + + Downloaded + i.e: total data downloaded + DL 量 + + + + Uploaded + i.e: total data uploaded + UP 量 + + + + Add a new peer... + 新しいピアの追加... + + + + Copy IP + IP をコピー + + + + Limit download rate... + ダウンロード速度制限... + + + + Limit upload rate... + アップロード速度制限... + + + + Ban peer permanently + ピアを永遠にアクセス禁止にする + + + + + Peer addition + ピアの追加 + + + + The peer was added to this torrent. + ピアはこの Torrent に追加されました。 + + + + The peer could not be added to this torrent. + ピアはこの Torrent に追加できませんでした。 + + + + Are you sure? -- qBittorrent + よろしいですか? ― qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + 選択したピアを永遠にアク禁にしてよろしいですか? + + + + &Yes + はい(&Y) + + + + &No + いいえ(&N) + + + + Manually banning peer %1... + ピア %1 を手動でアク禁にしています... + + + + Upload rate limiting + アップロード速度制限 + + + + Download rate limiting + ダウンロード速度制限 + + + + Preferences + + + Downloads + ダウンロード + + + + Connection + 接続 + + + + Speed + 速度 + + + + Web UI + Web UI + + + + Advanced + 拡張 + + + + (Requires restart) + (再起動が必要) + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + 行の色を交互に変える + + + + + Start / Stop Torrent + Torrent の開始/停止 + + + + + No action + なにもしない + + + + Append .!qB extension to incomplete files + 未完了のファイル名に拡張子 .!qB を付加する + + + + Copy .torrent files to: + .torrent ファイルの保存先: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + 以下のパラメータがサポートされています: +<ul> +<li>%f: Torrent のパス</li> +<li>%n: Torrent の名前</li> +</ul> + + + + Connections Limits + 接続制限 + + + + Proxy Server + プロキシサーバ + + + + Global Rate Limits + 全体の速度制限 + + + + Apply rate limit to uTP connections + uTP 接続に対しても制限する + + + + Apply rate limit to transport overhead + トランスポートオーバーヘッドにも制限を適用する + + + + Alternative Global Rate Limits + 全体の代替速度制限 + + + + Schedule the use of alternative rate limits + 代替速度制限の使用スケジュール + + + + Enable Local Peer Discovery to find more peers + より多くのピアを見つけるためにローカルピア検出 (LSD) を有効にする + + + + Encryption mode: + 暗号化モード: + + + + Prefer encryption + 暗号化を許可 + + + + Require encryption + 暗号化を強制 + + + + Disable encryption + 暗号化しない + + + + Maximum active downloads: + 最大アクティブダウンロード数: + + + + Maximum active uploads: + 最大アクティブアップロード数: + + + + Maximum active torrents: + 最大アクティブ Torrent 数: + + + + When adding a torrent + Torrent の追加時 + + + + Display torrent content and some options + Torrent の内容とオプションの一部を表示する + + + + Port used for incoming connections: + 着信接続で使用するポート: + + + + Random + ランダム + + + + Global maximum number of connections: + 全体の最大接続数: + + + + Maximum number of connections per torrent: + Torrent あたりの最大接続数: + + + + Maximum number of upload slots per torrent: + Torrent あたりの最大アップロードスロット数: + + + + + Upload: + アップロード: + + + + + Download: + ダウンロード: + + + + + + + KiB/s + KiB/s + + + + Remove folder + フォルダを除去 + + + + to + time1 to time2 + 「from 08:00 to 20:00」 → 「開始 08:00 終了 20:00」 + 終了 + + + + Every day + 毎日 + + + + Week days + 平日 + + + + Week ends + 週末 + + + + DHT port: + DHT ポート: + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Bittorrent 互換クライアント (µTorrent, Vuze など) とピア情報を交換します + + + + Host: + ホスト: + + + + SOCKS4 + SOCKS4 + + + + Type: + 種類: + + + + + Options + オプション + + + + Action on double-click + ダブルクリック時の動作 + + + + Downloading torrents: + ダウンロード中の Torrent: + + + + + Open destination folder + 作成先のフォルダを開く + + + + Completed torrents: + 完了している Torrent: + + + + Desktop + デスクトップ + + + + Show splash screen on start up + 起動時にスプラッシュスクリーンを表示する + + + + Start qBittorrent minimized + qBittorrent を最小化して起動する + + + + Minimize qBittorrent to notification area + 最小化したら qBittorrent を通知エリアへ最小化する + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + 閉じたら qBittorrent を通知エリアへ最小化する + + + + Tray icon style: + トレイアイコンのスタイル: + + + + Normal + 通常 + + + + Monochrome (Dark theme) + モノクローム (暗いテーマ) + + + + Monochrome (Light theme) + モノクローム (明るいテーマ) + + + + Ask for program exit confirmation + プログラム終了時に確認する + + + + User Interface Language: + ユーザインターフェイスの言語: + + + + Transfer List + 転送リスト + + + + Show qBittorrent in notification area + qBittorrent を通知エリアに表示する + + + + Power Management + 電源管理 + + + + Inhibit system sleep when torrents are active + Torrent がアクティブの時システムをスリープさせない + + + + Do not start the download automatically + The torrent will be added to download list in pause state + 停止状態で追加する + + + + Hard Disk + ハードディスク + + + + Save files to location: + ファイルの保存場所: + + + + Append the label of the torrent to the save path + Torrent のラベルを保存先パスに付加する + + + + Pre-allocate disk space for all files + すべてのファイルに対して事前にディスクスペースを割り当てる + + + + Keep incomplete torrents in: + 未完了の Torrent の格納先: + + + + Automatically add torrents from: + 自動的に Torrent を追加するフォルダ: + + + + Add folder... + フォルダを追加... + + + + Email notification upon download completion + ダウンロード完了時にEメールで通知する + + + + Destination email: + 送信先Eメール: + + + + SMTP server: + SMTP サーバ: + + + + This server requires a secure connection (SSL) + このサーバではセキュアな接続 (SSL) が必要 + + + + Run an external program on torrent completion + Torrent 完了時に外部プログラムを実行する + + + + Listening Port + 待ち受けポート + + + + Use UPnP / NAT-PMP port forwarding from my router + ルータからのポートフォワードに UPnP / NAT-PMP を使用する + + + + Otherwise, the proxy server is only used for tracker connections + このオプションを有効にしない場合、プロキシはトラッカーとの接続のみに使用されます + + + + Use proxy for peer connections + ピアとの接続にプロキシを使用する + + + + IP Filtering + IP フィルタリング + + + + Reload the filter + フィルタの再読み込み + + + + Enable bandwidth management (uTP) + 帯域幅管理 (uTP) を有効にする + + + + from + from (time1 to time2) + 「from 08:00 to 20:00」 → 「開始 08:00 終了 20:00」 + 開始 + + + + When: + 代替速度制限を行う曜日を指定するドロップダウンリストのラベル + 曜日: + + + + Privacy + プライバシー + + + + Enable DHT (decentralized network) to find more peers + より多くのピアを見つけるため DHT (分散ネットワーク) を有効にする + + + + Use a different port for DHT and BitTorrent + DHT と BitTorrent で異なるポートを使用する + + + + Enable Peer Exchange (PeX) to find more peers + より多くのピアを見つけるためにピア交換 (PeX) を有効にする + + + + Look for peers on your local network + ローカルネットワーク内のピアも探す + + + + Seed torrents until their ratio reaches + 指定共有比に達するまでシードする ― 共有比が + + + + then + に達したとき + + + + Pause them + 停止する + + + + Remove them + 削除する + + + + Use UPnP / NAT-PMP to forward the port from my router + ルータからのポートフォワードに UPnP / NAT-PMP を使用する + + + + Use HTTPS instead of HTTP + HTTP ではなく HTTPS を使用する + + + + Import SSL Certificate + SSL 証明書をインポート + + + + Import SSL Key + SSL 公開鍵をインポート + + + + Certificate: + 証明書: + + + + Key: + 公開鍵: + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>SSL 証明書について</a> + + + + Bypass authentication for localhost + localhost では認証を行わない + + + + Update my dynamic domain name + ダイナミックドメイン名を更新する + + + + Service: + サービス: + + + + Register + 登録 + + + + Domain name: + ドメイン名: + + + + (None) + (なし) + + + + + Behavior + 振る舞い + + + + BitTorrent + BitTorrent + + + + Language + 言語 + + + + HTTP + HTTP + + + + + Port: + ポート: + + + + + + Authentication + 認証 + + + + + + + Username: + ユーザー名: + + + + + + + Password: + パスワード: + + + + Torrent Queueing + Torrent キュー + + + + Share Ratio Limiting + 共有比制限 + + + + Enable Web User Interface (Remote control) + ウェブユーザインターフェイス (リモート制御) を有効にする + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + フィルタパス (.dat, .p2p, .p2b): + + + + PreviewSelect + + + Name + 名前 + + + + Size + サイズ + + + + Progress + 進行状況 + + + + + + Preview impossible + プレビューできません + + + + + + Sorry, we can't preview this file + すみません、このファイルをプレビューできません + + + + PropListDelegate + + + Not downloaded + ダウンロードしない + + + + + Normal + Normal (priority) + 通常 + + + + + High + High (priority) + 高い + + + + Mixed + Mixed (priorities + 混在 + + + + + Maximum + Maximum (priority) + 最高 + + + + PropTabBar + + + General + 全般 + + + + Trackers + トラッカー + + + + Peers + ピア + + + + HTTP Sources + HTTP ソース + + + + Content + コンテンツ + + + + PropertiesWidget + + + Save path: + 保存先パス: + + + + Torrent hash: + Torrent ハッシュ: + + + + Comment: + コメント: + + + + Share ratio: + 共有比: + + + + + Downloaded: + ダウンロード量: + + + + Availability: + 可用性: + + + + Transfer + 転送 + + + + Uploaded: + アップロード量: + + + + Wasted: + 破棄: + + + + Time active: + Time (duration) the torrent is active (not paused) + アクティブ時間: + + + + Pieces size: + ピースサイズ: + + + + Torrent content: + Torrent の内容: + + + + Select All + すべて選択 + + + + Select None + すべて解除 + + + + + Do not download + ダウンロードしない + + + + UP limit: + アップロード速度上限: + + + + DL limit: + ダウンロード速度上限: + + + + Connections: + 接続数: + + + + Reannounce in: + 次のアナウンス: + + + + Information + 情報 + + + + Created on: + 作成日時: + + + + Priority + 優先度 + + + + Normal + 通常 + + + + Maximum + 最高 + + + + High + 高い + + + + + this session + このセッション + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + シード時間 %1 + + + + %1 max + e.g. 10 max + 最大 %1 + + + + + I/O Error + I/O エラー + + + + This file does not exist yet. + このファイルはまだ存在していません。 + + + + This folder does not exist yet. + このフォルダはまだ存在していません。 + + + + Rename... + 名前の変更... + + + + Rename the file + ファイル名の変更 + + + + New name: + 新しい名前: + + + + + The file could not be renamed + ファイル名は変更できませんでした + + + + This file name contains forbidden characters, please choose a different one. + ファイル名に利用できない文字が含まれています。他の文字を使用してください。 + + + + + This name is already in use in this folder. Please use a different name. + この名前はこのフォルダ内ですでに使われています。別の名前をつけてください。 + + + + The folder could not be renamed + フォルダ名を変更できませんでした + + + + New url seed + New HTTP source + 新しい url シード + + + + New url seed: + 新しい url シード: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + この url シードはすでにリストにあります。 + + + + + Choose save path + 保存パスの選択 + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 は指定された共有比に達しました。 + + + + Removing torrent %1... + Torrent %1 を削除しています... + + + + Pausing torrent %1... + Torrent %1 を停止しています... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent はポート TCP/%1 にバインドされます + + + + HTTP user agent is %1 + HTTP ユーザエージェントは %1 です + + + + DHT support [ON], port: UDP/%1 + DHT サポート [オン]、ポート UDP/%1 + + + + + DHT support [OFF] + DHT サポート [オフ] + + + + PeX support [ON] + PeX サポート [オン] + + + + PeX support [OFF] + PeX サポート [オフ] + + + + Restart is required to toggle PeX support + PeX サポートを切り替える場合は再起動が必要です + + + + Local Peer Discovery support [OFF] + ローカルピア検出 [オフ] + + + + Encryption support [ON] + 暗号化サポート [オン] + + + + Encryption support [FORCED] + 暗号化サポート [強制] + + + + Encryption support [OFF] + 暗号化サポート [オフ] + + + + Embedded Tracker [ON] + 埋め込みトラッカー[オン] + + + + Failed to start the embedded tracker! + 埋め込みトラッカーの起動に失敗しました! + + + + Embedded Tracker [OFF] + 埋め込みトラッカー [オフ] + + + + The Web UI is listening on port %1 + Web UI の待ち受けポート %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Web UI エラー ― Web UI をポート %1 へバインド出来ません + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + %1 は転送リストおよびハードディスクから削除されました。 + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + %1 は転送リストから削除されました。 + + + + '%1' is not a valid magnet URI. + %1 は正しいマグネット URI ではありません。 + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' はすでにダウンロードリストにあります。 + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' が再開されました。 (高速再開) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' がダウンロードリストに追加されました。 + + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP サポート [オン] + + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP サポート [オフ] + + + + Reporting IP address %1 to trackers... + IP アドレス %1 をトラッカーに報告しています... + + + + Local Peer Discovery support [ON] + ローカルピア検出 [オン] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Torrent ファイルをデコードすることができません: '%1' + + + + This file is either corrupted or this isn't a torrent. + このファイルは壊れているか Torrent ではないかのどちらかです。 + + + + Error: The torrent %1 does not contain any file. + エラー: Torrent %1 にはファイルが含まれていません。 + + + + Note: new trackers were added to the existing torrent. + メモ: 新しいトラッカーが既存の Torrent に追加されました。 + + + + Note: new URL seeds were added to the existing torrent. + メモ: 新しい URI シードが既存の Torrent に追加されました。 + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>はあなたの IP フィルタによってブロックされました。</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>は破壊されたピースであるためアク禁になりました</i> + + + + The network interface defined is invalid: %1 + 定義されたネットワークインターフェイスが正しくありません: %1 + + + + Trying any other network interface available instead. + ほかのネットワークインターフェイスの利用を試みます。 + + + + Listening on IP address %1 on network interface %2... + ネットワークインターフェイス %2、IP アドレス %1 で待ち受けています... + + + + Failed to listen on network interface %1 + ネットワークインターフェイス %1 での待受に失敗しました + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Torrent %2 に埋めこまれたファイル %1 の再帰ダウンロード + + + + + Unable to decode %1 torrent file. + %1 Torrent ファイルをデコードできません。 + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + 15 秒以内にキャンセルされなければ、コンピュータはスリープモードに遷移します... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + 15 秒以内にキャンセルされなければ、コンピュータは停止します... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + 15 秒以内にキャンセルされなければ、 qBittorrent は終了します... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + 与えられた IP フィルタは正しく解析されました: %1 ルールが適用されました。 + + + + Error: Failed to parse the provided IP filter. + エラー: 与えられた IP フィルタの解析に失敗しました。 + + + + Torrent name: %1 + Torrent 名: %1 + + + + Torrent size: %1 + Torrent サイズ: %1 + + + + Save path: %1 + 保存先パス: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent は %1 でダウンロードされました。 + + + + Thank you for using qBittorrent. + qBittorrent をご利用いただきありがとうございます。 + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 はダウンロードが完了しました + + + + An I/O error occured, '%1' paused. + I/O error が発生しました。 '%1' は停止しました。 + + + + + Reason: %1 + 理由: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: ポートマッピングに失敗しました。メッセージ: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: ポートマッピングに成功しました。メッセージ: %1 + + + + File sizes mismatch for torrent %1, pausing it. + Torrent %1 のファイルサイズが一致しません。停止します。 + + + + Fast resume data was rejected for torrent %1, checking again... + 高速再開データは Torrent %1 を拒絶しました。再度チェックしています... + + + + Url seed lookup failed for url: %1, message: %2 + 次の url の url シードの参照に失敗しました: %1、メッセージ: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + '%1' をダウンロードしています、お待ちください... + + + + RSS + + + Search + 検索 + + + + New subscription + 新規購読 + + + + + + Mark items read + 既読にマークする + + + + Update all + すべて更新 + + + + RSS Downloader... + RSS ダウンローダ... + + + + Settings... + 設定... + + + + Rename... + 名前の変更... + + + + + Update + 更新 + + + + New subscription... + 新規購読... + + + + New folder... + 新規フォルダ... + + + + Manage cookies... + Cookie の管理... + + + + + Update all feeds + すべてのフィードの更新 + + + + + Delete + 削除 + + + + Rename + 名前の変更 + + + + Download torrent + Torrent のダウンロード + + + + Open news URL + ニュースの URL を開く + + + + Copy feed URL + フィード URL を開く + + + + Refresh RSS streams + RSS ストリームの更新 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrent:</span> <span style=" font-style:italic;">(ダブルクリックでダウンロード)</span></p></body></html> + + + + RSSImp + + + Please type a rss stream url + RSS ストリームの URL を入力してください + + + + Stream URL: + ストリームの URL: + + + + + Are you sure? -- qBittorrent + よろしいですか? ― qBittorrent + + + + + &Yes + はい(&Y) + + + + + &No + いいえ(&N) + + + + Please choose a folder name + フォルダ名を選択してください + + + + Folder name: + フォルダ名: + + + + New folder + 新しいフォルダ + + + + Overwrite attempt + 上書き試行 + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + %1 のアイテム上書きできません。 + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + この RSS フィードはすでにリストにあります。 + + + + Are you sure you want to delete these elements from the list? + これらの要素をリストから削除してよろしいですか? + + + + Are you sure you want to delete this element from the list? + この要素をリストから削除してよろしいですか? + + + + Please choose a new name for this RSS feed + この RSS フィードの新しい名前を選択してください + + + + New feed name: + 新しいフィード名: + + + + Name already in use + 名前はすでに使用されています + + + + This name is already used by another item, please choose another one. + この名前はすでに別のアイテムで使用されています。他の名前を選んでください。 + + + + Date: + 日付: + + + + Author: + 作者: + + + + Unread + 未読 + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + %1 Torrent を %2 RSS フィードから自動的にダウンロードしています... + + + + RssSettingsDlg + + + RSS Reader Settings + RSS リーダ設定 + + + + RSS feeds refresh interval: + RSS フィードの更新の間隔: + + + + minutes + + + + + Maximum number of articles per feed: + フィードあたりの最大記事数: + + + + ScanFoldersModel + + + Watched Folder + 監視フォルダ + + + + Download here + そこにダウンロードする + + + + SearchCategories + + + All categories + すべてのカテゴリ + + + + Movies + 映画 + + + + TV shows + TV 番組 + + + + Music + 音楽 + + + + Games + ゲーム + + + + Anime + アニメ + + + + Software + ソフトウェア + + + + Pictures + 画像 + + + + Books + 書籍 + + + + SearchEngine + + + Empty search pattern + 検索パターンが入力されていません + + + + Please type a search pattern first + まず検索パターンを入力してください + + + + + Results + 結果 + + + + Searching... + 検索しています... + + + + Cut + 切り取り + + + + Copy + コピー + + + + Paste + 貼り付け + + + + Clear field + フィールドをクリア + + + + Clear completion history + 完了履歴をクリア + + + + Confirmation + 確認 + + + + Are you sure you want to clear the history? + 履歴をクリアしますか? + + + + + + Search + 検索 + + + + Missing Python Interpreter + Python インタプリタが見つかりません + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + 検索エンジンを使用するには Python2.x が必要ですがインストールされていないようです。 +今すぐインストールしますか? + + + + Search Engine + 検索エンジン + + + + + Search has finished + 検索が完了しました + + + + An error occured during search... + 検索中にエラーが発生しました... + + + + + Search aborted + 検索を中止しました + + + + Download error + ダウンロードエラー + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Python セットアップをダウンロードできませんでした。理由: %1。 +手動でインストールしてください。 + + + + Search returned no results + 検索条件に一致する情報は見つかりませんでした + + + + Results + i.e: Search results + 検索結果 + + + + + Unknown + 不明 + + + + SearchTab + + + Name + i.e: file name + 名前 + + + + Size + i.e: file size + サイズ + + + + Seeders + i.e: Number of full sources + シーダ + + + + Leechers + i.e: Number of partial sources + リーチャ + + + + Search engine + 検索エンジン + + + + ShutdownConfirmDlg + + + Shutdown confirmation + シャットダウンの確認 + + + + SpeedLimitDialog + + + KiB/s + KiB/s + + + + StatusBar + + + + Connection status: + 接続状態: + + + + + No direct connections. This may indicate network configuration problems. + 直接接続はありません。これはネットワーク構成に問題があることを示しているのかもしれません。 + + + + + DHT: %1 nodes + DHT: %1 ノード + + + + qBittorrent needs to be restarted + qBittorrent の再起動が必要です + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent はアップデートされ、それを反映するために再起動が必要です。 + + + + + Connection Status: + 接続状態: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + オフライン。これは通常 qBittorrent が選択されたポートでの着信接続の待ち受けに失敗したことを意味します。 + + + + Online + オンライン + + + + + %1/s + Per second + %1/s + + + + Click to switch to alternative speed limits + クリックすると代替速度制限に切り替えます + + + + Click to switch to regular speed limits + クリックすると通常の速度制限に切り替えます + + + + Global Download Speed Limit + 全体のダウンロード速度制限 + + + + Global Upload Speed Limit + 全体のアップロード速度制限 + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Torrent に追加するフォルダを選択してください + + + + Select a file to add to the torrent + Torrent に追加するファイルを選択してください + + + + No input path set + 入力パスが設定されていません + + + + Please type an input path first + まず入力パスを入力してください + + + + Select destination torrent file + 作成先の Torrent ファイルを選択してください + + + + Torrent Files + Torrent ファイル + + + + + + Torrent creation + Torrent の作成 + + + + Torrent creation was unsuccessful, reason: %1 + Torrent の作成に失敗しました、理由: %1 + + + + Created torrent file is invalid. It won't be added to download list. + 作成された Torrent ファイルは正常ではありません。これはダウンロードリストに追加されません。 + + + + Torrent was created successfully: + Torrent は正常に作成されました: + + + + TorrentFilesModel + + + Name + 名前 + + + + Size + サイズ + + + + Progress + 進行状況 + + + + Priority + 優先度 + + + + TorrentImportDlg + + + Torrent Import + Torrent のインポート + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + このアシスタントはあなたがすでにダウンロード済みの Torrent を qBittorrent で共有する際のお手伝いをします。 + + + + Torrent file to import: + インポートする Torrent ファイル: + + + + + ... + ... + + + + Content location: + コンテンツの場所: + + + + Skip the data checking stage and start seeding immediately + データチェックステージをスキップし、直ちにシードを開始する + + + + Import + インポート + + + + Torrent file to import + インポートする Torrent ファイル + + + + Torrent files (*.torrent) + Torrent ファイル (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 ファイル + + + + Please provide the location of %1 + %1 is a file name + %1 の場所を指定してください + + + + Please point to the location of the torrent: %1 + Torrent の場所を指定してください: %1 + + + + Invalid torrent file + 不正な Torrent ファイル + + + + This is not a valid torrent file. + これは正常な Torrent ファイルではありません。 + + + + TorrentModel + + + Name + i.e: torrent name + 名前 + + + + Size + i.e: torrent size + サイズ + + + + Done + % Done + 進行状況 + + + + Status + Torrent status (e.g. downloading, seeding, paused) + 状態 + + + + Seeds + i.e. full sources (often untranslated) + シード + + + + Peers + i.e. partial sources (often untranslated) + ピア + + + + Down Speed + i.e: Download speed + DL 速度 + + + + Up Speed + i.e: Upload speed + UP 速度 + + + + Ratio + Share ratio + 共有比 + + + + ETA + i.e: Estimated Time of Arrival / Time left + 予想残り時間 + + + + Label + ラベル + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + 追加日時 + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + 完了日時 + + + + Tracker + トラッカー + + + + Down Limit + i.e: Download limit + DL 速度上限 + + + + Up Limit + i.e: Upload limit + UP 速度上限 + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + 総ダウンロード量 + + + + Amount left + Amount of data left to download (e.g. in MB) + 総残りダウンロード量 + + + + Time Active + Time (duration) the torrent is active (not paused) + アクティブ時間 + + + + TrackerList + + + URL + URL + + + + Status + 状態 + + + + Peers + ピア + + + + Message + メッセージ + + + + [DHT] + [DHT] + + + + [PeX] + [PeX] + + + + [LSD] + [LSD] + + + + + + + + Working + 動作中 + + + + + + Disabled + 無効 + + + + This torrent is private + この Torrent はプライベートです + + + + Updating... + 更新しています... + + + + + Not working + 非動作中 + + + + + Not contacted yet + 未接触 + + + + Add a new tracker... + 新しいトラッカーの追加... + + + + Remove tracker + トラッカーの削除 + + + + Force reannounce + 強制再アナウンス + + + + TrackersAdditionDlg + + + Trackers addition dialog + トラッカーの追加ダイアログ + + + + List of trackers to add (one per line): + 追加するトラッカーを入力してください (1行に1トラッカー): + + + + µTorrent compatible list URL: + µTorrent 互換リスト URL: + + + + I/O Error + I/O エラー + + + + Error while trying to open the downloaded file. + ダウンロードしたファイルを開くときにエラーが発生しました。 + + + + No change + 変更なし + + + + No additional trackers were found. + 追加されたトラッカーはありません。 + + + + Download error + ダウンロードエラー + + + + The trackers list could not be downloaded, reason: %1 + トラッカーリストをダウンロードできませんでした。理由: %1 + + + + TransferListDelegate + + + Downloading + ダウンロード中 + + + + Paused + 停止 + + + + Queued + i.e. torrent is queued + 待機中 + + + + Seeding + Torrent is complete and in upload-only mode + シード中 + + + + Stalled + Torrent is waiting for download to begin + ダウンロード待ち + + + + Checking + Torrent local data is being checked + チェック中 + + + + /s + /second (.i.e per second) + /s + + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + + Seeded for %1 + e.g. Seeded for 3m10s + シード時間 %1 + + + + TransferListFiltersWidget + + + + All + すべて + + + + + Downloading + ダウンロード中 + + + + + Completed + 完了済み + + + + + Paused + 停止中 + + + + + Active + アクティブ + + + + + Inactive + 非アクティブ + + + + + All labels + すべてのラベル + + + + + Unlabeled + ラベルなし + + + + Remove label + ラベルの削除 + + + + Add label... + ラベルの追加... + + + + Resume torrents + Torrent の再開 + + + + Pause torrents + Torrent の停止 + + + + Delete torrents + Torrent の削除 + + + + New Label + 新しいラベル + + + + Label: + ラベル: + + + + Invalid label name + 不正なラベル名 + + + + Please don't use any special characters in the label name. + ラベル名に特殊文字は使わないでください。 + + + + TransferListWidget + + + Column visibility + 表示カラム + + + + Label + ラベル + + + + Choose save path + 保存先パスの選択 + + + + Torrent Download Speed Limiting + Torrent ダウンロード速度制限 + + + + Torrent Upload Speed Limiting + Torrent アップロード速度制限 + + + + New Label + 新しいラベル + + + + Label: + ラベル: + + + + Invalid label name + 不正なラベル名 + + + + Please don't use any special characters in the label name. + ラベル名に特殊文字は使わないでください。 + + + + Rename + 名前の変更 + + + + New name: + 新しい名前: + + + + Resume + Resume/start the torrent + 再開 + + + + Pause + Pause the torrent + 停止 + + + + Delete + Delete the torrent + 削除 + + + + Preview file... + ファイルのプレビュー... + + + + Limit share ratio... + 共有比制限... + + + + Limit upload rate... + アップロード速度制限... + + + + Limit download rate... + ダウンロード速度制限... + + + + Open destination folder + 作成先のフォルダを開く + + + + Move up + i.e. move up in the queue + 上げる + + + + Move down + i.e. Move down in the queue + 下げる + + + + Move to top + i.e. Move to top of the queue + 先頭へ + + + + Move to bottom + i.e. Move to bottom of the queue + 最後へ + + + + Set location... + 場所の移動... + + + + Priority + 優先度 + + + + Force recheck + 強制再チェック + + + + Copy magnet link + マグネットリンクのコピー + + + + Super seeding mode + スーパーシードモード + + + + Rename... + 名前の変更... + + + + Download in sequential order + シーケンシャルにダウンロード + + + + Download first and last piece first + 最初と最後のピースを最初にダウンロード + + + + New... + New label... + 新しいラベル... + + + + Reset + Reset label + リセット + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Torrent: アップロード量/ダウンロード量 比率制限 + + + + Use global ratio limit + 全体の共有比上限を使う + + + + + + buttonGroup + ボタングループ + + + + Set no ratio limit + 制限しない + + + + Set ratio limit to + 共有比上限を設定する + + + + UsageDisplay + + + Usage: + 使用法: + + + + displays program version + プログラムのバージョン情報を表示する + + + + disable splash screen + スプラッシュスクリーンを無効にする + + + + displays this help message + このヘルプメッセージを表示する + + + + changes the webui port (current: %1) + Web UI ポートを変更する (現在: %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [ファイルまたは URL]: ユーザから渡された Torrent をダウンロードする (任意) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + ボランティアで qBittorrent の翻訳に協力してくださった以下の方々に感謝します: + + + + Please contact me if you would like to translate qBittorrent into your own language. + qBittorrent を自分の言語に翻訳したいとお思いならご連絡ください。 + + + + addPeerDialog + + + Peer addition + ピアの追加 + + + + IP + IP + + + + Port + ポート + + + + addTorrentDialog + + + Torrent addition dialog + Torrent の追加ダイアログ + + + + Save path: + 保存先パス: + + + + ... + ... + + + + Torrent size: + Torrent サイズ: + + + + + Unknown + 不明 + + + + Free disk space: + ディスクの空き容量: + + + + Label: + ラベル: + + + + Torrent content: + Torrent の内容: + + + + Select All + すべて選択 + + + + Select None + すべて解除 + + + + Download in sequential order (slower but good for previewing) + シーケンシャルにダウンロードする (時間はかかりますがプレビューには向いています) + + + + Skip file checking and start seeding immediately + ファイルチェックをスキップし、直ちにシードを開始する + + + + + Do not download + ダウンロードしない + + + + Add to download list in paused state + 停止状態でダウンロードリストに追加する + + + + Add + 追加 + + + + Cancel + キャンセル + + + + Normal + 通常 + + + + High + 高い + + + + Maximum + 最高 + + + + authentication + + + + Tracker authentication + トラッカ認証 + + + + Tracker: + トラッカ: + + + + Login + ログイン + + + + Username: + ユーザー名: + + + + Password: + パスワード: + + + + Log in + ログ イン + + + + Cancel + キャンセル + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + 削除の確認 - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + 選択した Torrent を転送リストから削除しますか? + + + + Remember choice + 選択を記憶する + + + + Also delete the files on the hard disk + ハードディスク上のファイルも削除する + + + + createTorrentDialog + + + Cancel + キャンセル + + + + Torrent Creation Tool + Torrent 作成ツール + + + + Torrent file creation + Torrent ファイルの作成 + + + + File or folder to add to the torrent: + Torrent に追加するファイルまたはフォルダ: + + + + Add file + ファイルを追加 + + + + Add folder + フォルダを追加 + + + + Tracker URLs: + トラッカー URL: + + + + Web seeds urls: + ウェブシード URL: + + + + Comment: + コメント: + + + + Piece size: + ピースサイズ: + + + + 32 KiB + 32 KiB + + + + 64 KiB + 64 KiB + + + + 128 KiB + 128 KiB + + + + 256 KiB + 256 KiB + + + + 512 KiB + 512 KiB + + + + 1 MiB + 1 MiB + + + + 2 MiB + 2 MiB + + + + 4 MiB + 4 MiB + + + + Auto + 自動 + + + + Private (won't be distributed on DHT network if enabled) + プライベート (DHT ネットワークが有効でも使用されません) + + + + Start seeding after creation + 作成後にシードを開始する + + + + Create and save... + 作成と保存... + + + + Progress: + 進行状況: + + + + downloadFromURL + + + Add torrent links + Torrent リンクの追加 + + + + Both HTTP and Magnet links are supported + HTTP およびマグネットリンクの両方をサポートしています + + + + Download + ダウンロード + + + + Cancel + キャンセル + + + + Download from urls + URL からダウンロード + + + + No URL entered + URL が入力されていません + + + + Please type at least one URL. + 少なくとも 1 つの URL を入力してください。 + + + + engineSelect + + + Search plugins + 検索プラグイン + + + + Installed search engines: + インストールされている検索エンジン: + + + + Name + 名前 + + + + Url + URL + + + + + Enabled + 有効 + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + 新しい検索エンジンはここから入手できます: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + 新しいエンジンのインストール + + + + Check for updates + 更新のチェック + + + + Close + 閉じる + + + + Uninstall + アンインストール + + + + engineSelectDlg + + + Uninstall warning + アンインストールの警告 + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + 検索プラグインは qBittorrent に含まれているのでアンインストールできません。 + あなた自身で追加されたもののみアンインストールできます。 +しかし、それらのプラグインは無効になります。 + + + + Uninstall success + アンインストール成功 + + + + Select search plugins + 検索プラグインの選択 + + + + qBittorrent search plugins + qBittorrent 検索プラグイン + + + + + + + + Search plugin install + 検索プラグインのインストール + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + %1 検索エンジン プラグインのより最近のバージョンはすでにインストールされています。 + + + + + + + Search plugin update + 検索プラグインの更新 + + + + + Sorry, update server is temporarily unavailable. + すみません、更新サーバーが一時的に利用できません。 + + + + All your plugins are already up to date. + お使いのプラグインはすべて最新です。 + + + + All selected plugins were uninstalled successfully + 選択されたすべてのプラグインのアンインストールに成功しました + + + + + + Yes + はい + + + + + + + No + いいえ + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 検索エンジン プラグインはインストールできませんでした。 + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 検索エンジン プラグインは更新できませんでした、古いバージョンを維持します。 + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 検索エンジン プラグインの更新に成功しました。 + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1 検索エンジン プラグインのインストールに成功しました。 + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + すみません、%1 検索エンジン プラグインのインストールに失敗しました。 + + + + New search engine plugin URL + 新しい検索エンジン プラグインの URL + + + + URL: + URL: + + + + misc + + + B + bytes + B + + + + KiB + kibibytes (1024 bytes) + KiB + + + + MiB + mebibytes (1024 kibibytes) + MiB + + + + GiB + gibibytes (1024 mibibytes) + GiB + + + + TiB + tebibytes (1024 gibibytes) + TiB + + + + + + + + + Unknown + 不明 + + + + %1h %2m + e.g: 3hours 5minutes + %1時間 %2分 + + + + %1d %2h + e.g: 2days 10hours + %1日 %2時間 + + + + Unknown + Unknown (size) + 不明 + + + + qBittorrent will shutdown the computer now because all downloads are complete. + すべてのダウンロードが完了したので qBittorrent はコンピュータをシャットダウンします。 + + + + < 1m + < 1 minute + < 1 分 + + + + %1m + e.g: 10minutes + %1 分 + + + + options_imp + + + + + + Choose a save directory + 保存ディレクトリの選択 + + + + Add directory to scan + スキャンするディレクトリの追加 + + + + Folder is already being watched. + フォルダはすでに監視されています。 + + + + Folder does not exist. + フォルダが存在しません。 + + + + Folder is not readable. + フォルダが読み込み可能ではありません。 + + + + Failure + 失敗 + + + + Failed to add Scan Folder '%1': %2 + スキャンフォルダ '%1' の追加に失敗しました: %2 + + + + + Choose export directory + エクスポートディレクトリの選択 + + + + + Choose an ip filter file + IP フィルタファイルの選択 + + + + + Filters + フィルタ + + + + SSL Certificate (*.crt *.pem) + SSL 証明書 (*.crt *.pem) + + + + SSL Key (*.key *.pem) + SSL 鍵 (*.key *.pem) + + + + Parsing error + 解析エラー + + + + Failed to parse the provided IP filter + 与えられた IP フィルタの解析に失敗しました + + + + Successfully refreshed + 正常にリフレッシュされました + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + 与えられた IP フィルタは正しく解析されました: %1 ルールが適用されました。 + + + + Invalid key + 不正な鍵 + + + + This is not a valid SSL key. + これは正常な SSL 鍵ではありません。 + + + + Invalid certificate + 不正な証明書 + + + + This is not a valid SSL certificate. + これは正常な SSL 証明書ではありません。 + + + + pluginSourceDlg + + + Plugin source + プラグインソース + + + + Search plugin source: + 検索エンジンソース: + + + + Local file + ローカルファイル + + + + Web link + ウェブリンク + + + + preview + + + Preview selection + 選択範囲のプレビュー + + + + File preview + ファイルのプレビュー + + + + The following files support previewing, <br>please select one of them: + 以下のファイルのプレビューがサポートされています、<br>これらのうちから 1 つ選択してください: + + + + Preview + プレビュー + + + + Cancel + キャンセル + + + + search_engine + + + + Search + 検索 + + + + Status: + 状態: + + + + Stopped + 停止 + + + + Download + ダウンロード + + + + Go to description page + 説明ページへ移動 + + + + Search engines... + 検索エンジン... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + Torrent ファイルをデコードできません: + + + + + + Choose save path + 保存先パスの選択 + + + + Unable to decode magnet link: + マグネットリンクをデコードできません: + + + + Magnet Link + マグネットリンク + + + + Rename... + 名前の変更... + + + + Rename the file + ファイル名の変更 + + + + New name: + 新しい名前: + + + + + The file could not be renamed + ファイル名の変更が出来ませんでした + + + + This file name contains forbidden characters, please choose a different one. + このファイル名には利用できない文字が含まれています。他の文字を選んでください。 + + + + + This name is already in use in this folder. Please use a different name. + この名前はこのフォルダ内ですでに使用されています。他の名前を使用してください。 + + + + The folder could not be renamed + フォルダ名の変更が出来ませんでした + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (ダウンロード完了後の空き: %1) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (ダウンロードには %1 以上が必要です) + + + + Empty save path + 空の保存パス + + + + Please enter a save path + 保存先のパスを入力してください + + + + Save path creation error + 保存パスの作成エラー + + + + Could not create the save path + 保存パスを作成できませんでした + + + + Invalid label name + 不正なラベル名 + + + + Please don't use any special characters in the label name. + ラベル名に特殊文字は使わないでください。 + + + + Seeding mode error + シードモードエラー + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + ファイルチェックのスキップが選択されています。しかし、ローカルファイルは現在の保存先フォルダには存在しないようです。この機能を無効にするか、、保存先パスを修正してください。 + + + + Invalid file selection + 不正なファイル選択 + + + + You must select at least one file in the torrent + Torrent 内に少なくとも 1 つのファイルを選択する必要があります + + + + Priority + 優先度 + + + diff --git a/src/lang/qbittorrent_ko.qm b/src/lang/qbittorrent_ko.qm new file mode 100644 index 0000000000000000000000000000000000000000..f89897258d00e3bb4c3f8745a296dc1650502b78 GIT binary patch literal 55836 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 literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_ko.ts b/src/lang/qbittorrent_ko.ts new file mode 100644 index 000000000..4e0d383fd --- /dev/null +++ b/src/lang/qbittorrent_ko.ts @@ -0,0 +1,6244 @@ + + + + + AboutDlg + + + About qBittorrent + 큐비토런트에 대하여 + + + + About + 정보 + + + + Author + 저자 + + + + Name: + 이름: + + + + Country: + 국가: + + + + E-mail: + E-메일: + + + + Christophe Dumez + 크리스토프 두메스 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + + France + 프랑스 + + + + Translation + 번역 + + + + License + 라이센스 + + + + <h3><b>qBittorrent</b></h3> + <h3><b>큐비토런트</b></h3> + + + + chris@qbittorrent.org + + + + + Thanks to + 다음 분들에게 감사의 말씀을 드립니다 + + + + AdvancedSettings + + Property + 사항 + + + Value + + + + + Disk write cache size + 디스크 쓰기 케쉬 크기 + + + + MiB + 메가바이트 + + + + Outgoing ports (Min) [0: Disabled] + 송신 포트(최하) [0: 사용하지 않기] + + + + Outgoing ports (Max) [0: Disabled] + 송신 포트(최고) [0: 사용하지 않기] + + + + Recheck torrents on completion + 다 된 토렌트 다시 확인하기 + + + + Transfer list refresh interval + 전송 목록 재생 간격 + + + + ms + milliseconds + 밀리세컨 + + + + Setting + + + + + Value + Value set for this setting + + + + + Resolve peer countries (GeoIP) + 공유자 국가 (GeoIP) 재설정하기 + + + + Resolve peer host names + 공유자 호스트 이름 재설정하기 + + + + Maximum number of half-open connections [0: Disabled] + + + + + Strict super seeding + + + + + Network Interface (requires restart) + + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + + + + + IP Address to report to trackers (requires restart) + + + + + Display program on-screen notifications + + + + + Enable embedded tracker + + + + + Embedded tracker port + + + + + Check for software updates + + + + + Use system icon theme + + + + + Confirm torrent deletion + + + + + Ignore transfer limits on local network + 근접 통신망에서는 전송 속도 제한 무시하기 + + + Include TCP/IP overhead in transfer limits + TCP/IP에 사용되는 부과 데이타량 전송속도에 포함해서 보기 + + + + AutomatedRssDownloader + + + Automated RSS Downloader + + + + + Enable the automated RSS downloader + + + + + Download rules + + + + + Rule definition + + + + + Must contain: + + + + + Must not contain: + + + + + Use regular expressions + + + + + Import... + 가져오기... + + + + Export... + 내보내기... + + + + ... + ... + + + + Assign label: + + + + + Save to a different directory + + + + + Save to: + + + + + Apply rule to feeds: + + + + + Matching RSS articles + + + + + New rule name + + + + + Please type the name of the new download rule. + + + + + + Rule name conflict + + + + + + A rule with this name already exists, please choose another name. + + + + + Are you sure you want to remove the download rule named %1? + + + + + Are you sure you want to remove the selected download rules? + + + + + Rule deletion confirmation + + + + + Destination directory + + + + + Invalid action + + + + + The list is empty, there is nothing to export. + + + + + Where would you like to save the list? + + + + + Rules list (*.rssrules) + + + + + I/O Error + I/O 에러 + + + + Failed to create the destination file + + + + + Please point to the RSS download rules file + + + + + Rules list (*.rssrules *.filters) + + + + + Import Error + + + + + Failed to import the selected rules file + + + + + Add new rule... + + + + + Delete rule + + + + + Rename rule... + + + + + Delete selected rules + + + + + Rule renaming + + + + + Please type the new rule name + + + + + Regex mode: use Perl-like regular expressions + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + + Bittorrent + + %1 reached the maximum ratio you set. + '%1' 는 설정된 최대 공유 비율에 도달했습니다. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + 큐비토런트는 다음 포트을 사용하고 있습니다: TCP/%1 + + + UPnP support [ON] + UPnp 지원 [사용] + + + UPnP support [OFF] + UPnP 지원 [사용안함] + + + NAT-PMP support [ON] + NAT-PMP 지원 [사용] + + + NAT-PMP support [OFF] + NAT-PMP 지원 [사용안함] + + + HTTP user agent is %1 + HTTP 사용자 에이전트: %1 + + + Using a disk cache size of %1 MiB + 사용중인 디스크 케쉬 용량: %1 MiB + + + DHT support [ON], port: UDP/%1 + DHT 지원 [사용], 포트:'UDP/%1 + + + DHT support [OFF] + DHT 지원 [사용안함] + + + PeX support [ON] + PeX 지원 [사용] + + + PeX support [OFF] + PeX 지원 [사용안함] + + + Restart is required to toggle PeX support + Pex 기능을 재설정하기 위해서 프로그램을 다시 시작해야 합니다 + + + Local Peer Discovery [ON] + Local Peer Discovery (로컬 공유자 찾기) [사용] + + + Local Peer Discovery support [OFF] + Local Peer Discovery (로컬 공유자 찾기) [사용안함] + + + Encryption support [ON] + 암호화 지원 [사용] + + + Encryption support [FORCED] + 암호화 지원 [강제사용] + + + Encryption support [OFF] + 암호화 지원 [사용안함] + + + The Web UI is listening on port %1 + 웹 사용자 인터페이스는 포트 %1 를 사용하고 있습니다 + + + Web User Interface Error - Unable to bind Web UI to port %1 + 웹 유저 인터페이스 에러 - 웹 유저 인터페이스를 다음 포트에 연결 할수 없습니다:%1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + 전송목록과 디스크에서 '%1' 를 삭제하였습니다. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + 전송목록에서 '%1'를 삭제하였습니다. + + + '%1' is not a valid magnet URI. + '%1'는 유효한 마그넷 URI (magnet URI)가 아닙니다. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1'는/은 이미 전송목록에 포함되어 있습니다. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1'가 다시 시작되었습니다. (빠른 재개) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1'가 전송목록에 추가되었습니다. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + 토렌트 파일을 해독할수 없음: '%1' + + + This file is either corrupted or this isn't a torrent. + 파일에 오류가 있거나 토런트 파일이 아닙니다. + + + Note: new trackers were added to the existing torrent. + 참고: 새 트렉커가 토렌트에 추가 되었습니다. + + + Note: new URL seeds were added to the existing torrent. + 참고: 새 URL 완전체 공유자가 토렌트에 추가 되었습니다. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>은/는 IP 필터에 의해 접속이 금지되었습니다</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>은/는 유효하지 않은 파일 공유에 의해 접속이 금지되었습니다</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + 토렌트 %2 에는 또 다른 토렌트 파일 %1이 포함되어 있습니다 + + + Unable to decode %1 torrent file. + %1 토렌트를 해독할수 없습니다. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: 포트 설정(Port Mapping) 실패, 메세지: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: 포트 설정(Port mapping) 성공, 메세지: %1 + + + Fast resume data was rejected for torrent %1, checking again... + %1 의 빨리 이어받기가 실퍠하였습니다, 재확인중... + + + Reason: %1 + 이유: %1 + + + An I/O error occured, '%1' paused. + I/O 에러가 있습니다, '%1' 정지. + + + Url seed lookup failed for url: %1, message: %2 + Url 완전체(Url seed)를 찾을 수 없습니다: %1, 관련내용: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + '%1'을 다운 중입니다, 기다려 주세요... + + + + ConsoleDlg + + General + 일반 + + + Blocked IPs + 접속이 금지된 IP + + + + CookiesDlg + + + Cookies management + + + + + Key + As in Key/Value pair + + + + + Value + As in Key/Value pair + + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + + + + + Dynamic DNS error: Invalid username/password. + + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: Your username was blocked due to abuse. + + + + + Dynamic DNS error: supplied domain name is invalid. + + + + + Dynamic DNS error: supplied username is too short. + + + + + Dynamic DNS error: supplied password is too short. + + + + + DownloadThread + + + + I/O Error + I/O 에러 + + + + The remote host name was not found (invalid hostname) + 리모트 호스트(remote host)를 찾을 수 없습니다(잘못된 호스트 이름) + + + + The operation was canceled + 작업 취소됨 + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + 리모트 서버(Remote server)으로 부터 회신을 다 받기 전에 연결이 닫혔습니다 + + + + The connection to the remote server timed out + 리모트 서버(Remote Server) 연결 타임아웃 + + + + SSL/TLS handshake failed + SSL/TLS 핸드쉐이크 (handshake) 실패 + + + + The remote server refused the connection + 리모트 서버(Remote Server) 연결 거부 + + + + The connection to the proxy server was refused + 프락시 서버가 연결을 거부하였음 + + + + The proxy server closed the connection prematurely + 프락시 서버 연결을 영구적으로 제한하였음 + + + + The proxy host name was not found + 프락시 서버 이름을 찾을 수 없음 + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + 프락시 서버에 요청하신 작업에 대한 회신을 받기 전에 연결이 타임아웃(Timeout) 되었습니다 + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + 요청하신 작업을 하기 위해선 프락시 서버의 인증과정을 거쳐합니다. 하지만 입력하신 인증은 인정되지 않았습니다 + + + + The access to the remote content was denied (401) + 리모트 자료(Remote content) 접속이 거부됨(401) + + + + The operation requested on the remote content is not permitted + 리모트 자료(Remote content)에 요청하신 작업은 허용되지 않습니다 + + + + The remote content was not found at the server (404) + 리모트 자료(Remote content)가 서버에 없습니다(404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + 자료에 접근하기 위해선 리모트 서버읜 인증과정을 거쳐합니다. 하지만 입력하신 인증은 인정되지 않았습니다 + + + + The Network Access API cannot honor the request because the protocol is not known + 알려지지 않은 프로토콜 사용으로 인해 네트워크 접촉 API( Network Access API)가 사용하실수 없습니다 + + + + The requested operation is invalid for this protocol + 요청하신 작업은 현재 사용중에 프로토콜에 적당하지 않습니다 + + + + An unknown network-related error was detected + 네트웍크 관련 오류가 감지 되었습니다 + + + + An unknown proxy-related error was detected + 프락시 관련 오류가 감지되었습니다 + + + + An unknown error related to the remote content was detected + 리모트 자료(Remote content)관련된 오류가 감지되었습니다 + + + + A breakdown in protocol was detected + 프로토콜 파손이 감지 되었습니다 + + + + Unknown error + 알수 없는 오류 + + + + EventManager + + + + Working + 잘됨 + + + + Updating... + 업데이트중... + + + + + Not working + 안됨 + + + + + Not contacted yet + 아직 접속되지 않음 + + + + + this session + 이 세션 + + + + + /s + /second (i.e. per second) + /초 + + + + Seeded for %1 + e.g. Seeded for 3m10s + 완전체 공유한 시간: %1 + + + + %1 max + e.g. 10 max + 최고 %1 + + + + + %1/s + e.g. 120 KiB/s + %1/초 + + + + ExecutionLog + + + General + 일반 + + + + Blocked IPs + 접속이 금지된 IP + + + + FeedDownloader + + RSS Feed downloader + RSS 피드 다운로더 + + + RSS feed: + RSS 피드: + + + Feed name + 피드 이름 + + + Automatically download torrents from this feed + 이 피드에서 자동으로 다운하기 + + + Download filters + 다운로트 필터 + + + Filters: + 필터: + + + Filter settings + 필터 설정사항 + + + Matches: + 해당: + + + Does not match: + 해당하지 않음: + + + Destination folder: + 저장 폴더: + + + ... + ... + + + Filter testing + 필터 시험 + + + Torrent title: + 토렌트 이름: + + + Result: + 결과: + + + Test + 시험 + + + Import... + 가져오기... + + + Export... + 내보내기... + + + Rename filter + 필터 이름 바꾸기 + + + Remove filter + 필터 지우기 + + + Add filter + 필터 추가 + + + + FeedDownloaderDlg + + New filter + 새 필터 + + + Please choose a name for this filter + 이 필터 이름을 고르세요 + + + Filter name: + 필터 이름: + + + Invalid filter name + 부적당한 필터 이름 + + + The filter name cannot be left empty. + 필터 이름을 꼭 입력하셔야 합니다. + + + This filter name is already in use. + 이 필터 이름은 벌써 사용되고 있습니다. + + + Choose save path + 저장 경로 선택 + + + Filter testing error + 핕터 테스트 오류 + + + Please specify a test torrent name. + 시험용 토렌트 이름을 입력하세요. + + + matches + 해당 + + + does not match + 해당하지 않음 + + + Select file to import + 가져올 파일을 선택하세요 + + + Filters Files + 필터 파일 + + + Import successful + 가져오기 성공 + + + Filters import was successful. + 필터 가져오기가 성공적으로 이루어졌습니다. + + + Import failure + 가져오기 실패 + + + Filters could not be imported due to an I/O error. + I/O 에러에 의하여 필터를 가져 올수 없었습니다. + + + Select destination file + 저장경로를 선택하세요 + + + Export successful + 내보내기 성공 + + + Filters export was successful. + 핕터 내보내기가 성공적으로 이루어졌습니다. + + + Export failure + 내보내기 실패 + + + Filters could not be exported due to an I/O error. + I/O 에러에 의하여 필터 내보내기가 실패하였습니다. + + + + FeedList + + Unread + 안 읽음 + + + + FeedListWidget + + + RSS feeds + RSS 피드 + + + + Unread + 안 읽음 + + + + GUI + + Open Torrent Files + 토런트 파일 열기 + + + Torrent Files + 토런트 파일 + + + qBittorrent + 큐비토런트 + + + Transfers + 전송 + + + qBittorrent %1 + e.g: qBittorrent v0.x + 큐비토런트 %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + 다운로딩 속도: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + 업로딩 속도: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1가 다운로드를 완료하였습니다. + + + I/O Error + i.e: Input/Output Error + I/O 에러 + + + Search + 검색 + + + Download completion + 다운 완료 + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + 다음 파일에서 IO오류가 발생하였습니다 (%1). + 이유: %2 + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + 큐비토렌트 %1 (다운:%2/초, 업:%3/초) + + + Url download error + Url 다운로드 오류 + + + Couldn't download file at url: %1, reason: %2. + 다음 주소(Url)에서 파일을 다운로드할수 없습니다: %1, 이유:%2. + + + Yes + + + + No + 아니오 + + + Never + 전혀 사용안함 + + + Global Upload Speed Limit + 전체 업로드 속도 제한 + + + Global Download Speed Limit + 전체 다운 속도 제한 + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + 현재 몇몇 파일은 아직 전송 중에 있습니다. 큐비토렌트를 종료하시겠습니까? + + + Options were saved successfully. + 설정이 성공적으로 저장되었습니다. + + + + GeoIP + + France + 프랑스 + + + + HeadlessLoader + + + Information + 정보 + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + 큐비토렌트를 관리하시려면 다음 주소로 웹인터페이스를 접속하십시오 http://localhost:%1 + + + + The Web UI administrator user name is: %1 + 웹인터페이스 관리자 아이디:%1 + + + + The Web UI administrator password is still the default one: %1 + 웹인터페이스는 기본 비밀번호를 사용중에 있습니다: %1 + + + + This is a security risk, please consider changing your password from program preferences. + 보안상 위험하므로 프로그램 설정에서 비밀번호를 바꾸십시오. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + 확인 과정을 여러차례 통과하지 못했으므로 님의 현재 IP 주소는 금지되었습니다. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + 다운: '%1'/초당 - 전송: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + 업: %1/초당 - 전송: %2 + + + + HttpServer + + + File + 파일 + + + + Edit + 편집 + + + + Help + 도움 + + + Delete from HD + 하드디스크에서 지우기 + + + + Download Torrents from their URL or Magnet link + 웹주소(url)이나 마그네틱 링크에서 토렌트 다운받기 + + + + Only one link per line + 한 줄에 링크 한개씩 + + + + Download local torrent + 로컬 토렌트 다운받기 + + + + Torrent files were correctly added to download list. + 전송목록에 토렌트 파일이 성공적으로 추가되었습니다. + + + + Point to torrent file + 토렌트 파일 지정하기 + + + + Download + 다운로드 + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + 선택하신 토렌트 파일을 전송목록과 디스크에서 삭제하시겠습니까? + + + + Download rate limit must be greater than 0 or disabled. + 다운로드 비율제한은 0보다 높게 설정되어야 합니다. 0으로 설정시 다운로드 제한 기능이 사용되지 않습니다. + + + + Upload rate limit must be greater than 0 or disabled. + 업로드 비율제한은 0보다 높게 설정되어야 합니다. 0으로 설정시 업로드 제한 기능이 사용되지 않습니다. + + + + Maximum number of connections limit must be greater than 0 or disabled. + 최대 연결수는 0보다 높게 설정되어야 합니다. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + 토렌트 당 최대 연결수는 0보다 높게 설정 되어야 합니다. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + 토렌트 당 최대 업로드 연결 수는 0보다 높게 설정 되어야 합니다. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + 설정을 저장 훌수 없습니다. 큐비토렌트에 연결 할수 없습니다. + + + + Language + 언어 + + + + Downloaded + Is the file downloaded or not? + 다운됨 + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + 송신 포트는 1024 이상 65535 이하로 설정되어야 합니다. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + 웹 사용자 인터페이스용 포트는 1024 이상 65535 이하로 설정되어야 합니다. + + + + The Web UI username must be at least 3 characters long. + 웹 사용자 인터페이스의 사용자 이름은 3글자 이상이어야 합니다. + + + + The Web UI password must be at least 3 characters long. + 웹 사용자 인터페이스의 비밀번호는 3글자 이상이어야 합니다. + + + + Save + + + + + qBittorrent client is not reachable + + + + + HTTP Server + HTTP 서버 + + + + The following parameters are supported: + + + + + Torrent path + + + + + Torrent name + + + + + LegalNotice + + + Legal Notice + 이용 약관 + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + 큐비토렌트는 파일 공유 프로그램으로서 사용시 공유중인 파일은 다른 사용자에게 업로드 될수 있으며 모든 공유 파일의 법적 책임은 사용자에 있슴을 알려드립니다. + +이에 관한 더 이상의 이의를 없을 것입니다. + + + + Press %1 key to accept and continue... + %1 키를 눌러 확인해 주십시오... + + + + Legal notice + 이용 약관 + + + + Cancel + 취소 + + + + I Agree + 동의 + + + + LineEdit + + + Clear the text + + + + + MainWindow + + + &Edit + &편집 + + + + &Help + &도움말 + + + + &Tools + + + + + Auto-Shutdown on downloads completion + + + + + &File + &파일 + + + + &View + + + + + &Options... + + + + + Torrent &creator + + + + + Set upload limit... + + + + + Set download limit... + + + + + Exit qBittorrent + + + + + Suspend system + + + + + Shutdown system + + + + + Disabled + 사용하지 않기 + + + + Execution &Log + + + + + + Execution Log + + + + + &About + + + + + &Pause + + + + + &Delete + + + + + P&ause All + + + + + &Resume + + + + + &Add torrent file... + + + + + + Exit + + + + + R&esume All + + + + + Visit &Website + + + + + Add &link to torrent... + + + + + Report a &bug + + + + + &Documentation + + + + + Set global download limit... + + + + + Set global upload limit... + + + + + + Lock qBittorrent + + + + + Ctrl+L + + + + + Import existing torrent... + + + + + Import torrent... + + + + + Donate money + + + + + If you like qBittorrent, please donate! + + + + + + Alternative speed limits + + + + + &RSS reader + + + + + Search &engine + + + + + Top &tool bar + + + + + Display top tool bar + + + + + &Speed in title bar + + + + + Show transfer speed in title bar + + + + Preview file + 미리보기 + + + Clear log + 로그 지우기 + + + + Decrease priority + 우선순위(priority)를 낮추기 + + + + Increase priority + 우선순위(priority)를 낮추기 + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + 큐비토런트 %1 + + + + Set the password... + + + + + Transfers + 전송 + + + + Torrent file association + + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + + + + + + + UI lock password + + + + + + + Please type the UI lock password: + + + + + The password should contain at least 3 characters + + + + + Password update + + + + + The UI lock password has been successfully updated + + + + + RSS + + + + + Search + 검색 + + + + Transfers (%1) + + + + + Download completion + 다운 완료 + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1가 다운로드를 완료하였습니다. + + + + I/O Error + i.e: Input/Output Error + I/O 에러 + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + 다음 파일에서 IO오류가 발생하였습니다 (%1). + 이유: %2 + + + + Alt+1 + shortcut to switch to first tab + + + + + Alt+2 + shortcut to switch to third tab + + + + + Ctrl+F + shortcut to switch to search tab + + + + + Alt+3 + shortcut to switch to fourth tab + + + + + Recursive download confirmation + + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + + + + + + Yes + + + + + + No + 아니오 + + + + Never + 전혀 사용안함 + + + + Url download error + Url 다운로드 오류 + + + + Couldn't download file at url: %1, reason: %2. + 다음 주소(Url)에서 파일을 다운로드할수 없습니다: %1, 이유:%2. + + + + Global Upload Speed Limit + 전체 업로드 속도 제한 + + + + Global Download Speed Limit + 전체 다운 속도 제한 + + + + + Invalid password + + + + + The password is invalid + + + + + Exiting qBittorrent + + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + 현재 몇몇 파일은 아직 전송 중에 있습니다. 큐비토렌트를 종료하시겠습니까? + + + + Always + + + + + Open Torrent Files + 토런트 파일 열기 + + + + Torrent Files + 토런트 파일 + + + + Options were saved successfully. + 설정이 성공적으로 저장되었습니다. + + + + qBittorrent + + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + 다운로딩 속도: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + 업로딩 속도: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + 큐비토렌트 %1 (다운:%2/초, 업:%3/초) + + + + A newer version is available + + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + + + + + Impossible to update qBittorrent + + + + + qBittorrent failed to update, reason: %1 + + + + + PeerAdditionDlg + + + Invalid IP + 유효하지 않은 IP + + + + The IP you provided is invalid. + 유효하지 않은 IP 입니다. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /초 + + + + PeerListWidget + + + IP + + + + + Connection + 연결 + + + + Client + i.e.: Client application + 사용자 + + + + Progress + i.e: % downloaded + 진행상황 + + + + Down Speed + i.e: Download speed + 다운로드 속도 + + + + Up Speed + i.e: Upload speed + 업로드 속도 + + + + Downloaded + i.e: total data downloaded + 전송 완료 + + + + Uploaded + i.e: total data uploaded + 업로드 완료 + + + + Add a new peer... + + + + + Copy IP + + + + + Limit download rate... + + + + + Limit upload rate... + + + + + Ban peer permanently + 공유자(Peer) 영구 제한 + + + + + Peer addition + 공유자(Peer) 추가 + + + + The peer was added to this torrent. + 이 공유자(Peer)는 이 토렌트에 추가 되었습니다. + + + + The peer could not be added to this torrent. + 이 공유자(Peer)는 이 토렌트에 추가 될수 없습니다. + + + + Are you sure? -- qBittorrent + 재확인 해주십시요? -- 큐비토런트 + + + + Are you sure you want to ban permanently the selected peers? + 선택된 공유자(Peer)를 영구적으로 제한하시겠습니까? + + + + &Yes + &예 + + + + &No + &아니요 + + + + Manually banning peer %1... + 공유자(Peer)인 %1를 직접적으로 제한하기... + + + + Upload rate limiting + 업로드 비율 제한 + + + + Download rate limiting + 다운로드 비율 제한 + + + + Preferences + + UI + User Interface + 사용자 인터페이스(UI) + + + + Downloads + 다운로드 + + + + Connection + 연결 + + + + Speed + 속도 + + + Bittorrent + 비트토렌트 + + + Proxy + 프럭시 (Proxy) + + + + Web UI + 웹 유저 인터페이스 + + + + Advanced + 고급 + + + Language: + 언어: + + + + (Requires restart) + (재시작해야함) + + + Visual style: + 시각 효과: + + + Transfer list + 전송 목록 + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + 각 행마다 구별하기 쉽게 색입히기 + + + + + Start / Stop Torrent + + + + + + No action + + + + File system + 파일 시스템 + + + + Copy .torrent files to: + 토렌트을 여기로 복사하기: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + + + + Torrent queueing + 토렌트 나열하기 + + + + Maximum active downloads: + 최대 활성 다운로드: + + + + Maximum active uploads: + 최대 활성 업로드: + + + + Maximum active torrents: + 최대 활성 토렌트: + + + + When adding a torrent + 토렌트 추가시 + + + + + Options + 환경설정 + + + + Action on double-click + + + + + Downloading torrents: + + + + + + Open destination folder + 저장 폴더 열기 + + + + Completed torrents: + + + + + Desktop + + + + + Show splash screen on start up + + + + + Start qBittorrent minimized + + + + + Minimize qBittorrent to notification area + + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + + + + + Tray icon style: + + + + + Normal + 보통 + + + + Monochrome (Dark theme) + + + + + Monochrome (Light theme) + + + + + Ask for program exit confirmation + + + + + User Interface Language: + + + + + Transfer List + + + + + Show qBittorrent in notification area + + + + + Power Management + + + + + Inhibit system sleep when torrents are active + + + + + Display torrent content and some options + 토렌트 내용과 선택사항을 보이기 + + + + Do not start the download automatically + The torrent will be added to download list in pause state + + + + + Hard Disk + + + + + Save files to location: + + + + + Append the label of the torrent to the save path + + + + + Pre-allocate disk space for all files + + + + + Keep incomplete torrents in: + + + + + Automatically add torrents from: + + + + + Add folder... + + + + + Email notification upon download completion + + + + + Destination email: + + + + + SMTP server: + + + + + This server requires a secure connection (SSL) + + + + + Run an external program on torrent completion + + + + + Listening Port + + + + + Use UPnP / NAT-PMP port forwarding from my router + + + + + Otherwise, the proxy server is only used for tracker connections + + + + + Use proxy for peer connections + + + + + Reload the filter + + + + + Enable bandwidth management (uTP) + + + + + Privacy + + + + + Enable DHT (decentralized network) to find more peers + + + + + Use a different port for DHT and BitTorrent + + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + + + + + Enable Peer Exchange (PeX) to find more peers + + + + + Enable Local Peer Discovery to find more peers + + + + + Encryption mode: + + + + + Prefer encryption + + + + + Require encryption + + + + + Disable encryption + + + + + Seed torrents until their ratio reaches + + + + + then + + + + + Pause them + + + + + Remove them + + + + + Enable Web User Interface (Remote control) + + + + + Use UPnP / NAT-PMP to forward the port from my router + + + + + Use HTTPS instead of HTTP + + + + + Import SSL Certificate + + + + + Import SSL Key + + + + + Certificate: + + + + + Key: + + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + Bypass authentication for localhost + + + + + Update my dynamic domain name + + + + + Service: + + + + + Register + + + + + Domain name: + + + + Listening port + 포토듣기 + + + + Port used for incoming connections: + 송신 연결 포트: + + + + Random + 무작위 + + + Enable UPnP port mapping + UPnP 포트 맵핑 사용하기 + + + Enable NAT-PMP port mapping + NAT-PMP 포트 맵핑 사용하기 + + + Connections limit + 연결 제한 + + + + Global maximum number of connections: + 최대 전체 연결수: + + + + Maximum number of connections per torrent: + 토렌트당 최대 연결수: + + + + Maximum number of upload slots per torrent: + 토렌트당 최대 업로드수: + + + + + Upload: + 업로드: + + + + + Download: + 다운로드: + + + + + + + KiB/s + + + + + + Behavior + + + + + BitTorrent + + + + + Language + 언어 + + + Global speed limits + 전체 속도 제한 + + + Alternative global speed limits + 설정된 전체 전송 속도 제한 + + + + to + time1 to time2 + ~ + + + + Every day + 매일 + + + + Week days + 주중 + + + + Week ends + 주말 + + + Bittorrent features + 비토렌트 기능 + + + Enable DHT network (decentralized) + DHT 네트웍크 사용하기 (Decentralized) + + + Use a different port for DHT and Bittorrent + 비토렌트와 DHT에 다른 포트 사용하기 + + + + DHT port: + DHT 포트: + + + Enable Peer Exchange / PeX (requires restart) + 피어 익스체인지(Pex) 사용하기(재시작해야함) + + + Enable Local Peer Discovery + 로컬 네트웍크내 공유자 찾기 (Local Peer Discovery) 사용하기 + + + Enabled + 사용하기 + + + Forced + 강제 + + + Disabled + 사용하지 않기 + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP 통신(트렉커, 웹 시드, 검색엔진) + + + + Host: + 호스트: + + + Peer Communications + 사용자간 대화 + + + + SOCKS4 + 소켓4 + + + + Type: + 종류: + + + + Remove folder + 퐅더 제거 + + + + Connections Limits + + + + + Proxy Server + + + + + IP Filtering + + + + + from + from (time1 to time2) + + + + + When: + + + + + Look for peers on your local network + + + + + (None) + (없음) + + + + HTTP + + + + + + Port: + 포트: + + + + + + Authentication + 인증 + + + + Append .!qB extension to incomplete files + + + + + + + + Username: + 아이디: + + + + + + + Password: + 비밀번호: + + + + SOCKS5 + + + + + Filter path (.dat, .p2p, .p2b): + 필터 경로(.dat, .p2p, .p2b): + + + + Global Rate Limits + + + + + Apply rate limit to uTP connections + + + + + Apply rate limit to transport overhead + + + + + Alternative Global Rate Limits + + + + + Schedule the use of alternative rate limits + + + + + Torrent Queueing + + + + + Share Ratio Limiting + + + + HTTP Server + HTTP 서버 + + + + PreviewSelect + + + Name + + + + + Size + 크기 + + + + Progress + 진행상황 + + + + + + Preview impossible + 미리보기 불가 + + + + + + Sorry, we can't preview this file + 죄송합니다. 이 파일은 미리보기를 할수 없습니다 + + + + PropListDelegate + + + Not downloaded + 다운되지 않았음 + + + + + Normal + Normal (priority) + 보통 + + + + + High + High (priority) + 높음 + + + + Mixed + Mixed (priorities + + + + + + Maximum + Maximum (priority) + 최고 + + + + PropTabBar + + + General + 일반 + + + + Trackers + 트렉커(Trackers) + + + + Peers + + + + + HTTP Sources + + + + + Content + + + + Files + 파일 + + + + PropertiesWidget + + + Save path: + 저장 경로: + + + + Torrent hash: + 토렌트 헤쉬(Hash): + + + + Comment: + 설명: + + + + Share ratio: + 공유비율: + + + + + Downloaded: + 전송 받음: + + + + Availability: + 유효성: + + + + Transfer + 전송 + + + + Uploaded: + 보냄: + + + + Wasted: + 낭비됨: + + + + Time active: + Time (duration) the torrent is active (not paused) + + + + + Pieces size: + + + + + Torrent content: + 토렌트 내용: + + + + Select All + + + + + Select None + + + + + + Do not download + + + + + UP limit: + 업로드 제한: + + + + DL limit: + 다운로드 제한: + + + Time elapsed: + 지나간 시간: + + + + Connections: + 연결: + + + + Reannounce in: + + + + + Information + 정보 + + + + Created on: + 만든 날: + + + General + 일반 + + + Trackers + 트렉커(Trackers) + + + Peers + 공유자(Peers) + + + URL seeds + 웹 완전체(Url Seeds) + + + Files + 파일 + + + + Priority + 우선순위 + + + + Normal + 보통 + + + + Maximum + 최고 + + + + High + 높음 + + + + + this session + 이 세션 + + + + + /s + /second (i.e. per second) + /초 + + + + Seeded for %1 + e.g. Seeded for 3m10s + 완전체 공유한지: %1 + + + + %1 max + e.g. 10 max + 최고 %1 + + + + + I/O Error + I/O 에러 + + + + This file does not exist yet. + 이 파일은 아직 생성되지 않았습니다. + + + + This folder does not exist yet. + 이 폴더는 아직 생성되지 않았습니다. + + + + Rename... + 이름 바꾸기... + + + + Rename the file + 파일 이름바꾸기 + + + + New name: + 새 이름: + + + + + The file could not be renamed + 이 파일의 이름을 변경할수 없음 + + + + This file name contains forbidden characters, please choose a different one. + 파일 이름에 특수문자가 들어가 있습니다, 다른 이름을 입력해주십시오. + + + + + This name is already in use in this folder. Please use a different name. + 이 이름은 이 폴더에서 이미 사용중에 있습니다. 다른 이름을 입력해 주십시오. + + + + The folder could not be renamed + 이 폴더의 이름을 변경할수 없습니다 + + + + New url seed + New HTTP source + 새 웹 완전체(Url seed) + + + + New url seed: + 새 웹 완전체(Url seed): + + + + qBittorrent + 큐비토렌트 + + + + This url seed is already in the list. + 이 웹완전체(Url seed)는 이미 목록에 포함되어 있습니다. + + + + + Choose save path + 저장 경로 선택 + + + Save path creation error + 저장 경로에 설정 오류 + + + Could not create the save path + 저장 경로를 생성할수가 없습니다 + + + + QBtSession + + + + %1 reached the maximum ratio you set. + '%1' 는 설정된 최대 공유 비율에 도달했습니다. + + + + Removing torrent %1... + + + + + Pausing torrent %1... + + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + 큐비토런트는 다음 포트을 사용하고 있습니다: TCP/%1 + + + UPnP support [ON] + UPnp 지원 [사용] + + + UPnP support [OFF] + UPnP 지원 [사용안함] + + + NAT-PMP support [ON] + NAT-PMP 지원 [사용] + + + NAT-PMP support [OFF] + NAT-PMP 지원 [사용안함] + + + + HTTP user agent is %1 + HTTP 사용자 에이전트: %1 + + + Using a disk cache size of %1 MiB + 사용중인 디스크 케쉬 용량: %1 MiB + + + + DHT support [ON], port: UDP/%1 + DHT 지원 [사용], 포트:'UDP/%1 + + + + + DHT support [OFF] + DHT 지원 [사용안함] + + + + PeX support [ON] + PeX 지원 [사용] + + + + PeX support [OFF] + PeX 지원 [사용안함] + + + + Restart is required to toggle PeX support + Pex 기능을 재설정하기 위해서 프로그램을 다시 시작해야 합니다 + + + Local Peer Discovery [ON] + Local Peer Discovery (로컬 공유자 찾기) [사용] + + + + Local Peer Discovery support [OFF] + Local Peer Discovery (로컬 공유자 찾기) [사용안함] + + + + Encryption support [ON] + 암호화 지원 [사용] + + + + Encryption support [FORCED] + 암호화 지원 [강제사용] + + + + Encryption support [OFF] + 암호화 지원 [사용안함] + + + + Embedded Tracker [ON] + + + + + Failed to start the embedded tracker! + + + + + Embedded Tracker [OFF] + + + + + The Web UI is listening on port %1 + 웹 사용자 인터페이스는 포트 %1 를 사용하고 있습니다 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + 웹 유저 인터페이스 에러 - 웹 유저 인터페이스를 다음 포트에 연결 할수 없습니다:%1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + 전송목록과 디스크에서 '%1' 를 삭제하였습니다. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + 전송목록에서 '%1'를 삭제하였습니다. + + + + '%1' is not a valid magnet URI. + '%1'는 유효한 마그넷 URI (magnet URI)가 아닙니다. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1'는/은 이미 전송목록에 포함되어 있습니다. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1'가 다시 시작되었습니다. (빠른 재개) + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1'가 전송목록에 추가되었습니다. + + + + UPnP / NAT-PMP support [ON] + + + + + UPnP / NAT-PMP support [OFF] + + + + + Reporting IP address %1 to trackers... + + + + + Local Peer Discovery support [ON] + + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + 토렌트 파일을 해독할수 없음: '%1' + + + + This file is either corrupted or this isn't a torrent. + 파일에 오류가 있거나 토런트 파일이 아닙니다. + + + + Error: The torrent %1 does not contain any file. + + + + + Note: new trackers were added to the existing torrent. + 참고: 새 트렉커가 토렌트에 추가 되었습니다. + + + + Note: new URL seeds were added to the existing torrent. + 참고: 새 URL 완전체 공유자가 토렌트에 추가 되었습니다. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>은/는 IP 필터에 의해 접속이 금지되었습니다</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>은/는 유효하지 않은 파일 공유에 의해 접속이 금지되었습니다</i> + + + + The network interface defined is invalid: %1 + + + + + Trying any other network interface available instead. + + + + + Listening on IP address %1 on network interface %2... + + + + + Failed to listen on network interface %1 + + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + 토렌트 %2 에는 또 다른 토렌트 파일 %1이 포함되어 있습니다 + + + + + Unable to decode %1 torrent file. + %1 토렌트를 해독할수 없습니다. + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + + + + + Error: Failed to parse the provided IP filter. + + + + + Torrent name: %1 + + + + + Torrent size: %1 + + + + + Save path: %1 + + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + + + + + Thank you for using qBittorrent. + + + + + [qBittorrent] %1 has finished downloading + + + + + An I/O error occured, '%1' paused. + I/O 에러가 있습니다, '%1' 정지. + + + + + Reason: %1 + 이유: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: 포트 설정(Port Mapping) 실패, 메세지: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: 포트 설정(Port mapping) 성공, 메세지: %1 + + + + File sizes mismatch for torrent %1, pausing it. + + + + + Fast resume data was rejected for torrent %1, checking again... + %1 의 빨리 이어받기가 실퍠하였습니다, 재확인중... + + + + Url seed lookup failed for url: %1, message: %2 + Url 완전체(Url seed)를 찾을 수 없습니다: %1, 관련내용: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + '%1'을 다운 중입니다, 기다려 주세요... + + + + RSS + + + Search + 검색 + + + + New subscription + 새 구독 + + + + + + Mark items read + 읽은 것으로 표시 + + + + Update all + 다 업데이트하기 + + + + RSS Downloader... + + + + + Settings... + + + + Feed URL + 피드 주소(url) + + + + Rename... + 이름 바꾸기... + + + + + Update + 업데이트하기 + + + + New folder... + + + + + Manage cookies... + + + + RSS feeds + RSS 피드 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">토렌트:</span> <span style=" font-style:italic;">(다운로드하려면 더블 클릭하세요)</span></p></body></html> + + + Article title + 글 제목 + + + + New subscription... + + + + + + Update all feeds + 모든 피드 업데이트하기 + + + + + Delete + 삭제 + + + + Rename + 이름 바꾸기 + + + + Download torrent + 토렌트 다운로드하기 + + + + Open news URL + 새 주소(url) 열기 + + + + Copy feed URL + 피드 주소(url) 복사 + + + + Refresh RSS streams + RSS 스트림 새로고침 + + + + RSSImp + + + Please type a rss stream url + RSS 스트림 주소(url)를 입력하세요 + + + + Stream URL: + 스트림 URL: + + + + + Are you sure? -- qBittorrent + 재확인 해주십시요? -- 큐비토런트 + + + + + &Yes + &예 + + + + + &No + &아니요 + + + + Please choose a folder name + 폴더 이름을 고르세요 + + + + Folder name: + 폴도 이름: + + + + New folder + 새 폴더 + + + + Overwrite attempt + 덮어쓰기 시도 + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + %1 아이템은 덮어쓸수 없습니다. + + + + qBittorrent + 큐비토런트 + + + + This rss feed is already in the list. + 이 RSS 피드는 이미 리스트에 포함되어 있습니다. + + + + Are you sure you want to delete these elements from the list? + 이 목록에서 이 자료들을 지우싶으십니까? + + + + Are you sure you want to delete this element from the list? + 이 목록에서 이 자료를 지우싶으십니까? + + + + Please choose a new name for this RSS feed + RSS 피드에 쓸 새 이름을 고르세요 + + + + New feed name: + 새 피드 이름: + + + + Name already in use + 이 이름은 이미 사용중에 있음 + + + + This name is already used by another item, please choose another one. + 이 이름은 이미 다른 아이템이 사용하고 있습니다. 다른 이름을 사용하십시오. + + + + Date: + 날짜: + + + + Author: + 작성자: + + + + Unread + 안 읽음 + + + + RssArticle + + No description available + 관련 자료가 없습니다 + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + RSS 피드(%2)에서 자동으로 자료(%1) 다운하기... + + + + RssItem + + No description available + 관련 자료가 없습니다 + + + + RssSettings + + minutes + + + + + RssSettingsDlg + + + RSS Reader Settings + + + + + RSS feeds refresh interval: + + + + + minutes + + + + + Maximum number of articles per feed: + + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + RSS 피드(%2)에서 자동으로 자료(%1) 다운하기... + + + + ScanFoldersModel + + + Watched Folder + 주시할 폴더 + + + + Download here + 여기에 다운로드하기 + + + + SearchCategories + + + All categories + 모든 카테고리 + + + + Movies + 영화 + + + + TV shows + 텔레비젼 쇼 + + + + Music + 음악 + + + + Games + 게임 + + + + Anime + 애니 + + + + Software + 유틸 + + + + Pictures + 사진 + + + + Books + + + + + SearchEngine + + + Empty search pattern + 검색 양식 지우기 + + + + Please type a search pattern first + 검색 양식을 작성해주십시오 + + + + + Results + 결과 + + + + Searching... + 검색중... + + + + Cut + 잘라내기 + + + + Copy + 복사하기 + + + + Paste + 붙이기 + + + + Clear field + 내용 지우기 + + + + Clear completion history + 완료 내역 지우기 + + + + Confirmation + + + + + Are you sure you want to clear the history? + + + + + + + Search + 검색 + + + + Missing Python Interpreter + + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + + + + + Search Engine + 검색 엔진 + + + + + Search has finished + 검색 완료 + + + + An error occured during search... + 검색 중 오류 발생... + + + + + Search aborted + 검색이 중단됨 + + + + Download error + 다운로드 오류 + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + + + + + Search returned no results + 검색 결과가 없음 + + + + Results + i.e: Search results + 결과 + + + + + Unknown + 알려지지 않음 + + + + SearchTab + + + Name + i.e: file name + 파일이름 + + + + Size + i.e: file size + 크기 + + + + Seeders + i.e: Number of full sources + + + + + Leechers + i.e: Number of partial sources + + + + + Search engine + 검색 엔진 + + + + ShutdownConfirmDlg + + + Shutdown confirmation + + + + + SpeedLimitDialog + + + KiB/s + + + + + StatusBar + + + + Connection status: + 연결 상태: + + + + + No direct connections. This may indicate network configuration problems. + 직접적으로 연결되지 않음. 네트워크 설정에 오류가 있어 보입니다. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + 다운: '%1' B/s - 전송: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + 업: %1 B/s - 전송: %2 + + + + + DHT: %1 nodes + DHT: %1 노드 + + + + qBittorrent needs to be restarted + + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + + + + + + Connection Status: + 연결 상태: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + 오프라인(Offline)은 선택된 포트의 수신용 연결 오류로 발생할수 있습니다. + + + + Online + 온라인 + + + + + %1/s + Per second + %1/초 + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + 다운: '%1'/s - 전송: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + 업: %1/s - 전송: %2 + + + + Click to switch to alternative speed limits + + + + + Click to switch to regular speed limits + + + + Click to disable alternative speed limits + 설정한 속도 제한을 사용하지 않기 + + + Click to enable alternative speed limits + 설정한 속도 제한을 사용하기 + + + + Global Download Speed Limit + 전체 다운 속도 제한 + + + + Global Upload Speed Limit + 전체 업로드 속도 제한 + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + 토텐트를 추가할 폴더를 지정해 주십시오 + + + + Select a file to add to the torrent + 토렌트에 추가할 파일을 선택하십시오 + + + Please type an announce URL + 발표되는 주소(announce URL)를 입력해 주십시오 + + + Announce URL: + Tracker URL + 발표 되는 url(Tracker 주소): + + + Please type a web seed url + 웹에 있는 완전체의 주소(web seed url)를 입력해 주십시오 + + + Web seed URL: + 웹 시드 주소 (Web Seed URL): + + + + No input path set + 변환할 파일 경로가 설정되지 않았습니다 + + + + Please type an input path first + 파일 경로를 설정해 주십시오 + + + + Select destination torrent file + 토렌트 파일을 저장할 위치 지정 + + + + Torrent Files + 토런트 파일 + + + + + + Torrent creation + 토렌트 생성 + + + + Torrent creation was unsuccessful, reason: %1 + 토렌트 생성이 실패하였습니다, 이유: %1 + + + + Created torrent file is invalid. It won't be added to download list. + 토렌트 파일 목록 생성하기(다운로드 목록에 추가하지 않음). + + + + Torrent was created successfully: + 토렌트가 성공적으로 생성되었습니다: + + + + TorrentFilesModel + + + Name + 이름 + + + + Size + 크기 + + + + Progress + 진행상황 + + + + Priority + 우선순위 + + + + TorrentImportDlg + + + Torrent Import + + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + + + + + Torrent file to import: + + + + + + ... + ... + + + + Content location: + + + + + Skip the data checking stage and start seeding immediately + + + + + Import + + + + + Torrent file to import + + + + + Torrent files (*.torrent) + + + + + %1 Files + %1 is a file extension (e.g. PDF) + + + + + Please provide the location of %1 + %1 is a file name + + + + + Please point to the location of the torrent: %1 + + + + + Invalid torrent file + + + + + This is not a valid torrent file. + + + + + TorrentModel + + + Name + i.e: torrent name + + + + + Size + i.e: torrent size + 크기 + + + + Done + % Done + 완료 + + + + Status + Torrent status (e.g. downloading, seeding, paused) + 상태 + + + + Seeds + i.e. full sources (often untranslated) + 완전체 + + + + Peers + i.e. partial sources (often untranslated) + + + + + Down Speed + i.e: Download speed + 다운로드 속도 + + + + Up Speed + i.e: Upload speed + 업로드 속도 + + + + Ratio + Share ratio + 비율 + + + + ETA + i.e: Estimated Time of Arrival / Time left + 남은시간 + + + + Label + 라벨 + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + 추가됨 + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + 완료됨 + + + + Tracker + + + + + Down Limit + i.e: Download limit + 다운 제한 + + + + Up Limit + i.e: Upload limit + 업 제한 + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + + + + + Amount left + Amount of data left to download (e.g. in MB) + + + + + Time Active + Time (duration) the torrent is active (not paused) + + + + + TrackerList + + + URL + URL + + + + Status + 상태 + + + + Peers + 공유자 + + + + Message + 메세지 + + + + [DHT] + + + + + [PeX] + + + + + [LSD] + + + + + + + + + Working + 작동중 + + + + + + Disabled + 사용하지 않기 + + + + This torrent is private + 이 토렌트 파일은 개인용입니다 + + + + Updating... + 업데이트중... + + + + + Not working + 작동안됨 + + + + + Not contacted yet + 아직 접속되지 않음 + + + + Add a new tracker... + + + + + Remove tracker + + + + + Force reannounce + + + + + TrackersAdditionDlg + + + Trackers addition dialog + Tracker 입력창 + + + + List of trackers to add (one per line): + Tracker 입력 (한줄에 하나씩): + + + + µTorrent compatible list URL: + µTorrent에서 사용될수 있는 웹주소 목록: + + + + I/O Error + I/O 에러 + + + + Error while trying to open the downloaded file. + 다운 된 파일 실행 중 오류 발생. + + + + No change + 변동 없음 + + + + No additional trackers were found. + 추가 트렉커가 검색되지 않았습니다. + + + + Download error + 다운로드 오류 + + + + The trackers list could not be downloaded, reason: %1 + 트렉커 목록이 다운되지 않았습니다. 이유:%1 + + + + TransferListDelegate + + + Downloading + 다운로딩 + + + + Paused + 정지됨 + + + + Queued + i.e. torrent is queued + 대기중 + + + + Seeding + Torrent is complete and in upload-only mode + 공유중 + + + + Stalled + Torrent is waiting for download to begin + 다운로드 대기 + + + + Checking + Torrent local data is being checked + 확인중 + + + + /s + /second (.i.e per second) + /초 + + + + KiB/s + KiB/second (.i.e per second) + + + + + Seeded for %1 + e.g. Seeded for 3m10s + + + + + TransferListFiltersWidget + + + + All + 모두 + + + + + Downloading + 다운로딩 중 + + + + + Completed + 전송 완료 + + + + + Paused + 정지됨 + + + + + Active + 활성 + + + + + Inactive + 비활성 + + + + + All labels + 모든 라벨 + + + + + Unlabeled + 라벨 없음 + + + + Remove label + 라벨 지우기 + + + + Add label... + + + + + Resume torrents + + + + + Pause torrents + + + + + Delete torrents + + + + + New Label + 새 라벨 + + + + Label: + 라벨: + + + + Invalid label name + 부적절한 라벨 + + + + Please don't use any special characters in the label name. + 라벨 설정시 특수문자를 사용하지 마십시오. + + + + TransferListWidget + + Down Speed + i.e: Download speed + 다운로드 속도 + + + Up Speed + i.e: Upload speed + 업로드 속도 + + + ETA + i.e: Estimated Time of Arrival / Time left + 남은시간 + + + + Column visibility + 세로행 숨기기 + + + Name + i.e: torrent name + 토렌트 이름 + + + Size + i.e: torrent size + 크기 + + + Done + % Done + 완료 + + + Status + Torrent status (e.g. downloading, seeding, paused) + 상태 + + + Seeds + i.e. full sources (often untranslated) + 완전체 + + + Peers + i.e. partial sources (often untranslated) + 공유자(Peers) + + + Ratio + Share ratio + 비율 + + + + Label + 라벨 + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + 추가됨 + + + Completed On + Torrent was completed on 01/01/2010 08:00 + 완료됨 + + + Down Limit + i.e: Download limit + 다운 제한 + + + Up Limit + i.e: Upload limit + 업 제한 + + + + Choose save path + 저장 경로 선택 + + + Could not create the save path + 저장 경로를 생성할수가 없습니다 + + + + Torrent Download Speed Limiting + 토렌트 다운로드 속도 제한 + + + + Torrent Upload Speed Limiting + 토렌트 업로드 속도 제한 + + + + New Label + 새 라벨 + + + + Label: + 라벨: + + + + Invalid label name + 잘못된 라벨 이름 + + + + Please don't use any special characters in the label name. + 라벨 이름에 특수 문자를 사용하지 마십시오. + + + + Rename + 이름 바꾸기 + + + + New name: + 새 이름: + + + + Resume + Resume/start the torrent + + + + + Pause + Pause the torrent + 정지 + + + + Delete + Delete the torrent + 삭제 + + + + Preview file... + + + + + Limit share ratio... + + + + + Limit upload rate... + + + + + Limit download rate... + + + + + Priority + 우선순위 + + + + Open destination folder + 저장 폴더 열기 + + + + Move up + i.e. move up in the queue + + + + + Move down + i.e. Move down in the queue + + + + + Move to top + i.e. Move to top of the queue + + + + + Move to bottom + i.e. Move to bottom of the queue + + + + + Set location... + + + + + Force recheck + 강제로 재확인하기 + + + + Copy magnet link + 마그넷 링크 (Copy magnet link) 복사하기 + + + + Super seeding mode + 수퍼 공유 모드 (Super seeding mode) + + + + Rename... + 이름 바꾸기... + + + + Download in sequential order + 차레대로 다운받기 + + + + Download first and last piece first + 첫번째 조각과 마지막 조각을 먼저 다운받기 + + + + New... + New label... + 새라벨... + + + + Reset + Reset label + 재설정 + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + + + + + Use global ratio limit + + + + + + + buttonGroup + + + + + Set no ratio limit + + + + + Set ratio limit to + + + + + UsageDisplay + + + Usage: + 사용정보: + + + + displays program version + 프로그램 버전 보기 + + + + disable splash screen + 시작 광고 안보기 + + + + displays this help message + 도움말 안보기 + + + + changes the webui port (current: %1) + 웹인터페이스 포트 바꾸기 (현재: %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [파일 및 웹주소]:다른 사용자에게서 받은 토렌트 다운받기(옵션) + + + + about + + + qBittorrent + 큐비토런트 + + + + I would like to thank the following people who volunteered to translate qBittorrent: + 큐비토런트를 번역하는데 도움을 주신 다음 분들에게 다시 한번 감사드립니다: + + + + Please contact me if you would like to translate qBittorrent into your own language. + 큐비토런트를 자신이 사용하는 언어로 번역하는데 관심이 있으시가면 제게 연락을 주십시오. + + + + addPeerDialog + + + Peer addition + 피어 추가 + + + + IP + + + + + Port + 포트 + + + + addTorrentDialog + + + Torrent addition dialog + 토렌트 추가 다이얼로그 + + + + Save path: + 저장 경로: + + + + ... + ... + + + + Torrent size: + 토렌트 사이즈: + + + + + Unknown + 알수 없음 + + + + Free disk space: + 남은 디스크 공간: + + + + Label: + 라벨: + + + + Torrent content: + 토렌트 내용: + + + + Select All + + + + + Select None + + + + + Download in sequential order (slower but good for previewing) + 순차적으로 다운받기(느리지만 미리보기에 좋음) + + + + Skip file checking and start seeding immediately + 파일 검사 없이 바로 파일 공유시작하기 + + + + + Do not download + + + + + Add to download list in paused state + 정지 상태로 다운로드 목록에 추가하기 + + + + Add + 추가 + + + + Cancel + 취소 + + + + Normal + 보통 + + + + High + 높음 + + + + Maximum + 최고 + + + + authentication + + + + Tracker authentication + 트렉커 인증 + + + + Tracker: + 트렉커: + + + + Login + 로그인 + + + + Username: + 사용자: + + + + Password: + 비밀번호: + + + + Log in + 로그인 + + + + Cancel + 취소 + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + 삭제 완료- 큐비토렌트 + + + + Are you sure you want to delete the selected torrents from the transfer list? + 선택하신 토렌트를 전송목록에서 삭제하시겠습니까? + + + + Remember choice + + + + + Also delete the files on the hard disk + + + + + createTorrentDialog + + + Cancel + 취소 + + + + Torrent Creation Tool + 토렌트 파일 생성도구 + + + + Torrent file creation + 토렌트 파일 만들기 + + + Announce urls (trackers): + 발표 되는 url(Tracker 주소): + + + Comment (optional): + 의견(옵션): + + + Web seeds urls (optional): + 웹시드(Web seeds) url (옵션사항): + + + + File or folder to add to the torrent: + 토렌트를 추가할 파일 또는 폴더: + + + + Add file + 파일 추가 + + + + Add folder + 폴더 추가 + + + + Tracker URLs: + + + + + Web seeds urls: + + + + + Comment: + 설명: + + + + Piece size: + 조각 크기: + + + + 32 KiB + + + + + 64 KiB + + + + + 128 KiB + + + + + 256 KiB + + + + + 512 KiB + + + + + 1 MiB + + + + + 2 MiB + + + + + 4 MiB + + + + + Auto + + + + + Private (won't be distributed on DHT network if enabled) + 개인적으로 사용하기 (이 기능을 사용하시면 귀하의 파일은 DHT 네트웍크에 배포되지 않을 것입니다) + + + + Start seeding after creation + 생성후 바로 배포 시작하기 + + + + Create and save... + 생성 후 저장하기... + + + + Progress: + 진행: + + + + createtorrent + + Select destination torrent file + 토렌트 파일을 저장할 위치 지정 + + + Torrent Files + 토런트 파일 + + + No input path set + 변환할 파일 경로가 설정되지 않았습니다 + + + Please type an input path first + 파일 경로를 설정해 주십시오 + + + Torrent creation + 토렌트 생성 + + + Torrent was created successfully: + 토렌트가 성공적으로 생성되었습니다: + + + Select a folder to add to the torrent + 토텐트를 추가할 폴더를 지정해 주십시오 + + + Please type an announce URL + 발표되는 주소(announce URL)를 입력해 주십시오 + + + Torrent creation was unsuccessful, reason: %1 + 토렌트 생성이 실패하였습니다, 이유: %1 + + + Announce URL: + Tracker URL + 발표 되는 url(Tracker 주소): + + + Please type a web seed url + 웹에 있는 완전체의 주소(web seed url)를 입력해 주십시오 + + + Web seed URL: + 웹 시드 주소 (Web Seed URL): + + + Select a file to add to the torrent + 토렌트에 추가할 파일을 선택하십시오 + + + Created torrent file is invalid. It won't be added to download list. + 토렌트 파일 목록 생성하기(다운로드 목록에 추가하지 않음). + + + + downloadFromURL + + Download Torrents from URLs + URL에서 토렌트를 다운받기 + + + Only one URL per line + 한줄 당 하나의 URL을 쓰십시오 + + + + Add torrent links + + + + + Both HTTP and Magnet links are supported + + + + + Download + 다운로드 + + + + Cancel + 취소 + + + + Download from urls + URL로 부터 다운로드 받기 + + + + No URL entered + 주소(URL)가 포함되지 않았습니다 + + + + Please type at least one URL. + 적어도 하나의 주소(URL)를 적어주십시오. + + + + downloadThread + + I/O Error + I/O 에러 + + + The remote host name was not found (invalid hostname) + 리모트 호스트(remote host)를 찾을 수 없습니다(잘못된 호스트 이름) + + + The operation was canceled + 작업 취소됨 + + + The remote server closed the connection prematurely, before the entire reply was received and processed + 리모트 서버(Remote server)으로 부터 회신을 다 받기 전에 연결이 닫혔습니다 + + + The connection to the remote server timed out + 리모트 서버(Remote Server) 연결 타임아웃 + + + SSL/TLS handshake failed + I don't know how to translate handshake in korean. + SSL/TLS 핸드쉐이크 (handshake) 실패 + + + The remote server refused the connection + 리모트 서버(Remote Server) 연결 거부 + + + The connection to the proxy server was refused + 프락시 서버가 연결을 거부하였음 + + + The proxy server closed the connection prematurely + 프락시 서버 연결을 영구적으로 제한하였음 + + + The proxy host name was not found + 프락시 서버 이름을 찾을 수 없음 + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + 프락시 서버에 요청하신 작업에 대한 회신을 받기 전에 연결이 타임아웃(Timeout) 되었습니다 + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + 요청하신 작업을 하기 위해선 프락시 서버의 인증과정을 거쳐합니다. 하지만 입력하신 인증은 인정되지 않았습니다 + + + The access to the remote content was denied (401) + 리모트 자료(Remote content) 접속이 거부됨(401) + + + The operation requested on the remote content is not permitted + 리모트 자료(Remote content)에 요청하신 작업은 허용되지 않습니다 + + + The remote content was not found at the server (404) + 리모트 자료(Remote content)가 서버에 없습니다(404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + 자료에 접근하기 위해선 리모트 서버읜 인증과정을 거쳐합니다. 하지만 입력하신 인증은 인정되지 않았습니다 + + + The Network Access API cannot honor the request because the protocol is not known + 알려지지 않은 프로토콜 사용으로 인해 네트워크 접촉 API( Network Access API)가 사용하실수 없습니다 + + + The requested operation is invalid for this protocol + 요청하신 작업은 현재 사용중에 프로토콜에 적당하지 않습니다 + + + An unknown network-related error was detected + 네트웍크 관련 오류가 감지 되었습니다 + + + An unknown proxy-related error was detected + 프락시 관련 오류가 감지되었습니다 + + + An unknown error related to the remote content was detected + I am not sure what 'remote content' means. I translated it as file located in other side. + 리모트 자료(Remote content)관련된 오류가 감지되었습니다 + + + A breakdown in protocol was detected + 프로토콜 파손이 감지 되었습니다 + + + Unknown error + 알수 없는 오류 + + + + engineSelect + + + Search plugins + 검색 엔진 플러그인 + + + + Installed search engines: + 설치된 검색엔진: + + + + Name + 이름 + + + + Url + + + + + + Enabled + 사용하기 + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + 새 검색엔진 플러그인은 다음 링크에서 제공 받으실수 있습니다: <a href="http:plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + 새것 설치하기 + + + + Check for updates + 업데이트 확인 + + + + Close + 닫기 + + + Enable + 사용하기 + + + Disable + 사용하지 않기 + + + + Uninstall + 제거하기 + + + + engineSelectDlg + + + Uninstall warning + 언인스톨 경고 + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + 개중 몇의 검색엔진 플러그인은 큐비토런트에 포함이 되있기 때문에 제거 될수 없습니다. + 사용자가 직접 설치한 플러그인만이 제거 할수 있습니다. +하지만 큐비토런트에 포함된 검색플러그인들을 사용하지 않으시려면 "사용하지 않기"를 선택하시면 됩니다. + + + + + Uninstall success + 제거 완료 + + + + Select search plugins + 검색 플러그인을 선택하십시오 + + + + qBittorrent search plugins + 큐비토런트 검색엔진 + + + + + + + + Search plugin install + 검색 엔진 설치 + + + + + + Yes + + + + + + + + No + 아니오 + + + + + + + + + + + + qBittorrent + 큐비토런트 + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + 최신 버젼의 %1이 이미 설치되어있습니다. + + + + + + + Search plugin update + 검색 엔진 플러그인 업데이트 + + + + + Sorry, update server is temporarily unavailable. + 죄송합니다. 현재 임시적으로 업데이트 서버가 접속이 불가능합니다. + + + + All your plugins are already up to date. + 모든 검색엔진이 최신버젼입니다. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + 검색엔진 %1은 업데이트 될수 없습니다. 기존버젼을 유지하겠습니다. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + 검색엔진 %1은/는 설치될수 없습니다. + + + + All selected plugins were uninstalled successfully + 선택된 모든 플러그인들이 성공적으로 제거 되었습니다 + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + 검색엔진 %1이 성공적으로 업데이트 되었습니다. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + 검색엔진 %1이 성공적으로 설치 되었습니다. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + 죄송하지만, 검색엔진 플로그인, %1,의 설치가 실패하였습니다. + + + + New search engine plugin URL + 새 검색엔진 플러그인 주소(URL) + + + + URL: + + + + + misc + + + qBittorrent will shutdown the computer now because all downloads are complete. + + + + + B + bytes + 바이트 + + + + KiB + kibibytes (1024 bytes) + 킬로바이트 + + + + MiB + mebibytes (1024 kibibytes) + 메가바이트 + + + + GiB + gibibytes (1024 mibibytes) + 기가바이트 + + + + TiB + tebibytes (1024 gibibytes) + 테라바이트 + + + + %1h %2m + e.g: 3hours 5minutes + + + + + %1d %2h + e.g: 2days 10hours + + + + + + + + + + Unknown + 알수 없음 + + + + Unknown + Unknown (size) + 알수 없음 + + + + < 1m + < 1 minute + < 1분 + + + + %1m + e.g: 10minutes + %1분 + + + + options_imp + + + + + + Choose a save directory + 파일을 저장할 경로를 선택해주세요 + + + + Add directory to scan + 스켄 할 폴더 추가 + + + + Folder is already being watched. + 선택하신 폴더는 이미 스켄 목록에 포함되어 있습니다. + + + + Folder does not exist. + 선택하신 폴더는 존재하지 않습니다. + + + + Folder is not readable. + 선택하신 폴더를 읽을 수 없습니다. + + + + Failure + 실패 + + + + Failed to add Scan Folder '%1': %2 + 퐅도 추가 실패 '%1': %2 + + + + + Choose export directory + 내보낼 폴더 선택하기 + + + + + Choose an ip filter file + ip filter 파일 선택 + + + + + Filters + 필터 + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + + + + + Failed to parse the provided IP filter + + + + + Successfully refreshed + + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + + pluginSourceDlg + + + Plugin source + 플러그인 소스 + + + + Search plugin source: + 검색엔진 플러그인 소스: + + + + Local file + 로컬 파일 + + + + Web link + 웹 링크 + + + + preview + + + Preview selection + 미리보기 선택 + + + + File preview + 파일 미리보기 + + + + The following files support previewing, <br>please select one of them: + 다음 파일은 미리보기를 실행하실수 있습니다, +이 중 하나를 선택해 주십시오: + + + + Preview + 미리보기 + + + + Cancel + 취소 + + + + previewSelect + + Preview impossible + 미리보기 불가 + + + Sorry, we can't preview this file + 죄송합니다. 이 파일은 미리보기를 할수 없습니다 + + + Name + 파일 이름 + + + Size + 크기 + + + Progress + 진행상황 + + + + search_engine + + + + Search + 검색 + + + + Status: + 상태: + + + + Stopped + 정지됨 + + + + Download + 다운로드 + + + + Go to description page + + + + + Search engines... + 검색 엔진... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + 토런트 파일을 해독 할 수가 없습니다: + + + + + + Choose save path + 저장 경로 선택 + + + + Unable to decode magnet link: + 마그넷 링크를 읽을 수 없음: + + + + Magnet Link + 마그넷 링크 + + + + Rename... + 이름 바꾸기... + + + + Rename the file + 파일 이름 바꾸기 + + + + New name: + 새 이름: + + + + + The file could not be renamed + 이 파일의 이름을 바꿀수 없습니다 + + + + This file name contains forbidden characters, please choose a different one. + 파일 이름에 특수문자가 있습니다. 다른 이름을 입력해주십시오. + + + + + This name is already in use in this folder. Please use a different name. + 같은 이름의 파일이 있습니다. 다른 이름을 사용해 주세요. + + + + The folder could not be renamed + 이 폴더의 이름을 바꿀수 없습니다 + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (자료를 다운 후에는 %1 의 디스크 공간이 남습니다.) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (자료를 다운받기 위해서는 %1 의 디스크 공간이 필요합니다) + + + + Empty save path + 저장 경로 지우기 + + + + Please enter a save path + 저장 경로를 지정해주십시오 + + + + Save path creation error + 저장 경로 설정이 잘못되었습니다 + + + + Could not create the save path + 저장 경로를 생성할수가 없습니다 + + + + Invalid label name + 적절치 않은 라벨 이름입니다 + + + + Please don't use any special characters in the label name. + 라벨 이름에 특수 문자를 사용하지 마십시오. + + + + Seeding mode error + 공유 모트 오류 + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + 파일 검사를 옵션을 선택하셨지만 지정된 폴더에는 로컬 파일이 존재하지 않습니다. 파일 검사 옵션을 비활성화 하시거나 폴더를 재지정하십시오. + + + + Invalid file selection + 부적당한 파일 선택 + + + + You must select at least one file in the torrent + 토렌트에서 적어도 하나 이상의 파일을 선택해야 합니다 + + + + Priority + 우선순위 + + + diff --git a/src/lang/qbittorrent_lt.qm b/src/lang/qbittorrent_lt.qm new file mode 100644 index 0000000000000000000000000000000000000000..2a54f8029e514cb3cd0f45a67cbcc84fe96bf12a GIT binary patch literal 101195 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�*pNeEUCT|M}G2O5IshUi^d4!fwC3ymH|c&@0X5GXqVCFPvV! z@D;!_e42h*b<@i05PwmZTwT7b8teXQQa`N|o-9AGwG8SqRKD`>8{sEjRo?LE8}K)` zm#@DF`giSR<%b@-K&j8ZS>C$s0^sp+{j`<`fe&Shg zD)ruN<;m@M?}{7Bhw`vbv%g)wYkI9xw_Z_x%6*Wxe|oAzS8yCGVB z=9!NutL8`L=k%We`})N4i~4ScUv*gd#s9h(_Q%fhOAej}zvOxSv<`T>{Ic=Qu=~DI ze%V)Mg8$wxzZ|hZHSUe_&sAX^=QNam@zt&HzrSAo_3$d#@5%Bz`#+2IJX-$kQ>K8< zPAtFYviFo)`%?L%e}J8N@7Ky7eI0N&pH}|ZJNW(13(J2wyIHA!f4lrQXEXr5spZdv zpeJ9uxcvE3Vc%KLmA`#7_@wNhiu{|Q=Z~6PQ53*F-SW4JqRH5gDN8DX`B?8A?^TTd zJifpGofT7`coBZ#%8F@4_k%Bvub8p@o7ksC6?2Yy2KxBUin$lui@3pC`e~^vDyp9P z8~mB&6^rg$tkePHE0#a;9^y%>Dh?YzA2I6<6-V7NN5K%QIQq}|u#>h|9J}H{#Gmf1 z=pz35Z>;Fv{TA%YODlRW1)SllDt5eb82F^W;-v2%0YCP)6{lR1R95>{6=#%Ouhf6; zsyO$n*spH{E3Q27M@s#)sp6^^jzv6fZpBy2Q;a+#pBO*D0SfMipLp$I`GtrC+`4$ z3XZP$^@Pho|1}j)-TDmt&m#S_W<6B#>WRNpYW_hLe|Zr0L9n>uuTiY?{$EwRc`3%f zV@JjNH@pTrU}vy&{BI$TwgxAxdmeOsSa9E`e~GxsjlsG*A)h{aUvSY?wV>O^;F9~X zj)rT4%d6jm9ncqC`32aE%MJ)O>^=bT!VC1%3SJysbu7m1J1DsJ9neX|t-*E2;=R2; z5jJ2XVOP%& z9{*?T+ovxNMm`5Pme|j4Tpo;uKz~cR^wS!5d@#E4RM-i>4W3HBwe*(Y$DW1%(>XtQ z&LgQdMZ*Nu3yKyGy?4`>6 z`d?J)BfqHJ@7H(0E;^&Ke%;4G{~IdT-+C78=#`b5j?72=>ZQu&3xU6VrdPHd1US}T zQkk6ano?`(D$iT~DD=$3m7jX~R_x=0^1Si;`e{v>Re8Z6__6Z)l~+e!M?CSt%9~0~ z1)qMc@~aPD2mk5|mACx71pda<${)XneckW(l@HXN2)?ebd~g|lFB(_*&?^gJ49?--{bN;)AKCz8;IS6{|)y zfbk>l`vLv;>~DsgZ>o?#OzsHd^#~yYfb7x6VYESeO;P-mbl)y)98C4b6WOnX5UA?~ z0-`FZUmU=15dhPK*Zc9)Zg+@rYkCvWWGX(;8woWH_D6PS4_0m+ufnQN54OU6v3N~< zFqTRTugHF3vRaF;*J8c_6}G~FAPhLXSBuux^oOH;K5tG`Er2?VZR@mlsNIn3DuPWUZ6SLAMpXMTs2u!)DFTK^=HM zld5YqjrX`CPU_@Ft~#;9CFR<9q9=RoVrY^wkK z2dZ|AvO`ld**U5fVnl9SNDbp(j!znk;om{b5XDbGx8)&w+M3=-=Z;W!JP}I9yHi8q zL?kpg&=pQaMp#G{NHMOuu;ZlsI40@BGYLS*NL`p(|L$UOQd2a!BQ%tVrXr!va3|O) z8Qra^&VO0Uty%yb)?*IiC(e-4%i#=UU4Am4e~PG`_@<^)Z@#tt9g(iCNLMJ82zTy? zBtir6L@M{jEW&)CTOg+g^F&q1sx#-u2Bpn!)wwfGSsM#?^hH9Ej0tnkb*yT}8o>PS z>M$R0N9iS7*soU?w%6Bz-?(wuG<1oV_eMczd5`s+CSJIiVXs{iBP;d)En;W zu89vsVxi7>EEegcfJlapTC^er`rO|zk!Du3q4B@|2IFXv48;};g=m>`7un`-fBx;Y8NfOl% zMPZ;T32iYSzmJZx*;@uvJ#h#pP43B1HBdNztoUi(1F%SK9~`J?Y|KDyf}nAfgem1n z@-$<_h#@hCpa{rPJ(@IyDASnA3b-3Mvo!)41gU4+HJT|pHIi1{U0f~HG|0I^fJ=s}w~__G!{z&gc!x)Pt* zmP$lBQ=#PG02Z2zM7ltixtU^#e}^DVGE~G zXj9Y^#WV`}GptYjj9~pVEQy^#V1u923ZaT42a@9>`B|thCM>5nJs++SnLM z3___6MN_@N8k#N^=D6$Jid2(S0>>37=JA31CJi@U!P@K?T9d(^cv@K2L zHU&^|e{BoNR`n(h_Rhd#Wn)(tl;@C!aSS-6;^BBZU>3<-{qDECO}yg_qi)H zck#ia5$diFxT;K|cnNH#Nx>G3H*^D$caKGg&?2WRGYiG zQ(Y+%YHe!^d2(d5o#WCd)6=OfgRb0Z%9?;dcny>XqmA6)J94faPn(f@>&`jJp3~ht zPOjDDNNBCr_7fesK?p?KX4h0iOP+d(LeSJsm?sHguKnCl7p%ul*dxQEt+E>1H!7_{ ztaZuyzSB>JI$p@Eg~%Q?os15=*@s*oa~~ z<1V?(U59uLUCnr?6AB8%s^yxox83;rXxrN2x`i%0z%qHgPp^|2ijcwW)_NpM7~7U# zHhk3{e9?YlN5hv++@Z06I1#pNo!SCXK(mi%fYaCi2^`YJRR&GSKx3eZD!m6H5y`6BqQi1Y1JvJ1`NUmvaAOQsWV9<3 z)~@JiTU@I-SKL041=O{}TJ&n+s^bn~@dCTnLgATt+*`B##&_jB5Q1 za>X*pGzrJxfl1E@PMxVnHV?u`hOL?kM`NSf6^m>YB~~}bj{!}7b1;4oH|80y=YhF4 z=DBKZbDX9n6;+z-rmWMOB&Mk;VJn(#Gfi8CqwP;OX7O0eG+4=mQ4wz-1KLmaegU3Q zWpPf%+^qgS9rS zso?>UZ`vY9OolMi7*2zERQtQ$2i)8ic-jUVe*8XJK<&wPF9ZQIwm>w|e{~GsbmGdi z{)4R%y>!|HV-P6|vK%TgwCFr`kQ;S$E!}mjY^C$l73q$~qE0+wBzfADK8HHaIg#QK2V7YAf7tM<+&FUcK)eUX(&)Q?*(E zqa=Z4(vcg4baS8@lA`@i%9R&7N*k|4~1dvb|Wf-l;YU!-l=}`rs=O@d;C#V*CDD6LeWvQ zqEH5{Fr#OrLmj<{L9H;VgQaN!%D}ac_2~)7b_hbfsR&m@`Ug_O3n?4n_%eKf&;<22 z)*cZ9bu@Zjr4H4)h%5txS8HvsiGC8pG)+BUL-xR>L;&o0;Z@r;6hraBzAo*J_eFQ; zT}bNPu%RB+BmF0m0bvL$ax6F8ajQgH(pvJ2nWQ!knIzbu19`+FBW3cY&IhKZ6Mj8DIo(1{m91ntE8_+3LsX)i{K zm@6oF+%{Uf?nO9qS1cM&E8sj~P-suolG=?0T$k9-DBHquvNQAaWIzkrMcmjOZ@$P@#ETWedUTF;V~h$#lyMD_Du$tL>wAS)YV zp~2XW7$JzzwL#X!$UZ#hfN=W(u>hKz5)ueR4xa)X+N+o81qp8UrdjiC5#m zB~Xq94(3>0SCed!fg$Gc;%XPzz~A57&wv73vupSRz_2GCrQa^EVn_=04Rz4W%piDT zDXFbt5}9G+;O}IAiY|NQE^|+9Yui-UzNsyQf`zVRZx|x7Tf6nS2<%!+X>OEGdqO_Meiv;HCtJN|jiWeK^(_*eAENg%|&B=tZ zD7dtG*`meTpz$M~CR;iQiKhz$&P^Rab0&q=2+nEQrl+;NoMJ8Ef*i2Z(p2>}_I3>; zYm?Xs0Z+Dsj0a}Bav|^`l!#DG_Fz&@mSbWd$@?1-YjSJ)Qix_Rj4T@>(Hk9 !$* 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 + + + + AboutDlg + + + About qBittorrent + Apie qBittorrent + + + + About + Apie + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + + Author + Autorius + + + + Name: + Vardas: + + + + Country: + Šalis: + + + + E-mail: + El. paštas: + + + + Christophe Dumez + Christophe Dumez + + + + France + Prancūzija + + + + Translation + Vertimas + + + + License + Licenzija + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Bittorrent tinklo klientas, parašytas C++ kalba remiantis Qt4 įrankių rinkiniu </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">bei libtorrent-rasterbar. <br /><br />Autorinės teisės saugomos ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Namų puslapis:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forumas:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent Freenode tinkle</span></p></body></html> + + + + chris@qbittorrent.org + chris@qbittorrent.org + + + + Thanks to + Dėkoju + + + + AdvancedSettings + + Property + Savybė + + + Value + Reikšmė + + + + Disk write cache size + Podėlio diske dydis + + + + MiB + MiB + + + + Outgoing ports (Min) [0: Disabled] + Išeities prievadai (Min.) [0: Išjungta] + + + + Outgoing ports (Max) [0: Disabled] + Išeities prievadai (Maks.) [0: Išjungta] + + + + Recheck torrents on completion + Pertikrinti torentus baigus atsiuntimą + + + + Transfer list refresh interval + Siuntimų sąrašo atnaujinimo intervalas + + + + ms + milliseconds + ms + + + + Setting + + + + + Value + Value set for this setting + Reikšmė + + + + Resolve peer countries (GeoIP) + Gauti siuntėjų šalis (GeoIP) + + + + Resolve peer host names + Gauti siuntėjų stočių vardus + + + + Maximum number of half-open connections [0: Disabled] + Didžiausias pusiau atvirų prisijungimų kiekis[0: Išjungta] + + + + Strict super seeding + Griežtas super skleidimas + + + + Network Interface (requires restart) + Tinklo sąsaja (būtina perkrauti) + + + + Exchange trackers with other peers + + + + + Any interface + i.e. Any network interface + Bet kokia sąsaja + + + + IP Address to report to trackers (requires restart) + + + + + Display program on-screen notifications + + + + + Confirm torrent deletion + + + + Display program notification balloons + Rodyti programos pranešimus iš dėklo + + + + Enable embedded tracker + Įjungti įtaisytą trakerį + + + + Embedded tracker port + Įtaisyto trakerio prievadas + + + + Check for software updates + Tikrinti, ar yra atnaujinimų + + + + Use system icon theme + Naudoti sistemos piktogramas + + + + Ignore transfer limits on local network + Nepaisyti siuntimo apribojimų vietiniame tinkle + + + Include TCP/IP overhead in transfer limits + Siuntimo apribojimuose įtraukti ir TCP/IP viršutinę ribą + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Automatinis atsiuntimas iš RSS + + + + Enable the automated RSS downloader + Įjungti automatinį atsiuntimą iš RSS + + + + Download rules + Atsiuntimo taisyklės + + + + Rule definition + Taisyklės apibrėžimas + + + + Must contain: + Privalo turėti žodį: + + + + Must not contain: + Privalo neturėti žodžio: + + + + Use regular expressions + + + + + Import... + Įkelti... + + + + Export... + Eksportuoti... + + + + ... + ... + + + + Assign label: + Priskirti etiketę: + + + + Save to a different directory + Išsaugoti kitame aplanke + + + + Save to: + Išsaugoti į: + + + + Apply rule to feeds: + Taikyti taisyklę šiems srautams: + + + + Matching RSS articles + Atitinkantys RSS įrašai + + + + New rule name + Naujas taisyklės vardas + + + + Please type the name of the new download rule. + Įveskite vardą naujai atsiuntimo taisyklei. + + + + + Rule name conflict + Taisyklių vardų nesuderinamumas + + + + + A rule with this name already exists, please choose another name. + Taisyklė tokiu vardu jau egzistuoja, pasirinkite kitokį vardą. + + + + Are you sure you want to remove the download rule named %1? + Ar tikrai norite pašalinti atsiuntimo taisyklę vardu %1? + + + + Are you sure you want to remove the selected download rules? + Ar tikrai norite pašalinti pasirinktas atsiuntimo taisykles? + + + + Rule deletion confirmation + Taisyklių pašalinimo patvirtinimas + + + + Destination directory + Išsaugojimo aplankas + + + + Invalid action + Netinkamas veiksmas + + + + The list is empty, there is nothing to export. + Sąrašas tuščias, nėra ką eksportuoti. + + + + Where would you like to save the list? + Kur norėtumėte išsaugoti sąrašą? + + + + Rules list (*.rssrules) + Taisyklių sąrašas (*.rssrules) + + + + I/O Error + I/O klaida + + + + Failed to create the destination file + Nepavyko sukurti išvesties failo + + + + Please point to the RSS download rules file + Nurodykite kelią iki RSS atsiuntimo taisyklių failo + + + + Rules list (*.rssrules *.filters) + Taisyklių sąrašas (*.rssrules) + + + + Import Error + Įkėlimo klaida + + + + Failed to import the selected rules file + Nepavyko įkelti nurodyto taisyklių failo + + + + Add new rule... + Pridėti naują taisyklę... + + + + Delete rule + Pašalinti taisyklę + + + + Rename rule... + Pervadinti taisyklę... + + + + Delete selected rules + Pašalinti pasirinktas taisykles + + + + Rule renaming + Taisyklių pervadinimas + + + + Please type the new rule name + Įveskite naują taisyklės vardą + + + + Regex mode: use Perl-like regular expressions + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + + CookiesDlg + + + Cookies management + Slapukų valdymas + + + + Key + As in Key/Value pair + Raktas + + + + Value + As in Key/Value pair + Reikšmė + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Dažnai pasitaikantys slapukų raktai yra: '%1'. '%2'. +Šią informaciją turėtumėte gauti iš savo interneto naršyklės nustatymų. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + + + + + Dynamic DNS error: Invalid username/password. + + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + + + + + Dynamic DNS error: Your username was blocked due to abuse. + + + + + Dynamic DNS error: supplied domain name is invalid. + + + + + Dynamic DNS error: supplied username is too short. + + + + + Dynamic DNS error: supplied password is too short. + + + + + DownloadThread + + + + I/O Error + I/O klaida + + + + The remote host name was not found (invalid hostname) + Serverio vardas nerastas (negaliojantis serverio vardas) + + + + The operation was canceled + Veiksmas buvo atšauktas + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Serveris netinkamai nutraukė prisijungimą, nespėjus gauti bei apdoroti pilno atsakymo + + + + The connection to the remote server timed out + Baigėsi prisijungimui skirtas laikas + + + + SSL/TLS handshake failed + SSL/TLS pasisveikinimas nepavyko + + + + The remote server refused the connection + Serveris atmetė prisijungimą + + + + The connection to the proxy server was refused + Proxy serveris atmetė prisijungimą + + + + The proxy server closed the connection prematurely + Proxy serveris netinkamai nutraukė prisijungimą + + + + The proxy host name was not found + Proxy stoties vardas nerastas + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Baigėsi prisijungimui prie proxy serverio skirtas laikas arba proxy serveris laiku neatsakė į užklausą + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Proxy serveris reikalauja atpažinimo, norint įvykdyti užklausą, tačiau nepriėmė jokių siūlytų duomenų + + + + The access to the remote content was denied (401) + Priėjimas prie turinio buvo uždraustas (401) + + + + The operation requested on the remote content is not permitted + Užklaustas veiksmas yra neleistinas serveryje + + + + The remote content was not found at the server (404) + Turinys serveryje nerastas (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Serveris reikalauja atpažinimo, norint įvykdyti užklausą, tačiau nepriėmė jokių siūlytų duomenų + + + + The Network Access API cannot honor the request because the protocol is not known + Tinklo priėjimo API negali įvykdyti užklausos, nes užklausos protokolas nežinomas + + + + The requested operation is invalid for this protocol + Šis veiksmas yra negalimas šiam protokolui + + + + An unknown network-related error was detected + Įvyko nežinoma tinklo klaida + + + + An unknown proxy-related error was detected + Įvyko nežinoma proxy klaida + + + + An unknown error related to the remote content was detected + Įvyko nežinoma serverio klaida + + + + A breakdown in protocol was detected + Protokole aptiktas gedimas + + + + Unknown error + Nežinoma klaida + + + + EventManager + + + + Working + Veikia + + + + Updating... + Atnaujinama... + + + + + Not working + Neveikia + + + + + Not contacted yet + Dar nesusisiekta + + + + + this session + šioje sesijoje + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Skleidžiama jau %1 + + + + %1 max + e.g. 10 max + daugiausiai %1 + + + + + %1/s + e.g. 120 KiB/s + %1/s + + + + ExecutionLog + + + General + Bendra + + + + Blocked IPs + Užblokuoti IP + + + + FeedListWidget + + + RSS feeds + RSS srautai + + + + Unread + Neskaityta + + + + HeadlessLoader + + + Information + Informacija + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Kad valdyti qBittorrent, prisijunkite prie tinklo vartotojo sąsajos http://localhost:%1 + + + + The Web UI administrator user name is: %1 + Tinklo vartotojo sąsajos administratoriaus vartotojo vardas yra: %1 + + + + The Web UI administrator password is still the default one: %1 + Tinklo vartotojo sąsajos administratoriaus slaptažodis vis dar yra numatytasis: %1 + + + + This is a security risk, please consider changing your password from program preferences. + Yra saugumo spragos rizika, pasikeiskite savo slaptažodį programos nustatymuose. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + Jūsų IP adresas buvo užblokuotas po per didelio kiekio nepavykusių atpažinimo bandymų. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Ats.: %1/s - Viso: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Išs.: %1/s - Viso: %2 + + + + HttpServer + + + File + Failas + + + + Edit + Redaguoti + + + + Help + Žinynas + + + + Download Torrents from their URL or Magnet link + Atsiųsti torentus iš jų URL arba Magnet nuorodos + + + + Only one link per line + Po vieną nuorodą eilutėje + + + + Download local torrent + Atsiųsti vietinį torentą + + + + Torrent files were correctly added to download list. + Torentų failai tvarkingai pridėti į atsiuntimų sąrašą. + + + + Point to torrent file + Nurodykite torento failą + + + + Download + Atsiųsti + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Ar tikrai norite pašalinti pasirinktus torentus iš siuntimų sąrašo bei kietojo disko? + + + + Download rate limit must be greater than 0 or disabled. + Atsiuntimo greičio apribojimas privalo būti arba aukštesnis už 0, arba išjungtas. + + + + Upload rate limit must be greater than 0 or disabled. + Išsiuntimo greičio apribojimas privalo būti arba aukštesnis už 0, arba išjungtas. + + + + Maximum number of connections limit must be greater than 0 or disabled. + Didžiausias prisijungimų kiekis privalo būti arba aukštesnis už 0, arba išjungtas. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Didžiausias prisijungimų kiekis vienam torentui privalo būti arba aukštesnis už 0, arba išjungtas. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Didžiausias išsiuntimo prisijungimų kiekis vienam torentui privalo būti arba aukštesnis už 0, arba išjungtas. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Nepavyko išsaugoti programos nuostatų, qBittorrent tikriausiai yra nepasiekiamas. + + + + Language + Kalba + + + + Downloaded + Is the file downloaded or not? + Atsiųstas + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Įeinančių susijungimų prievadas privalo būti tarp 1024 ir 65535. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Tinklo vartotojo sąsajos prievadas privalo būti tarp 1024 ir 65535. + + + + The Web UI username must be at least 3 characters long. + Tinklo sąsajos vartotojo vardas privalo būti bent 3 simbolių ilgio. + + + + The Web UI password must be at least 3 characters long. + Tinklo sąsajos vartotojo slaptažodis privalo būti bent 3 simbolių ilgio. + + + + Save + Išsaugoti + + + + qBittorrent client is not reachable + qBittorrent klientas nepasiekiamas + + + + HTTP Server + HTTP serveris + + + + The following parameters are supported: + + + + + Torrent path + + + + + Torrent name + + + + + LegalNotice + + + Legal Notice + Teisinis pranešimas + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent yra failų dalinimosi programa. Vykdant torento siuntimą, jo duomenys bus prieinami kitiems išsiuntimo būdu. Visas turinys, kuriuo dalinsities, yra Jūsų atsakomybė. + +Daugiau nebus rodoma pranešimų apie tai. + + + + Press %1 key to accept and continue... + Spauskite mygtuką %1, jei sutinkate ir norite tęsti... + + + + Legal notice + Teisinis pranešimas + + + + Cancel + Atšaukti + + + + I Agree + Sutinku + + + + LineEdit + + + Clear the text + Išvalyti tekstą + + + + MainWindow + + + &Edit + R&edaguoti + + + + &Tools + Priem&onės + + + + &File + &Failas + + + + &Help + &Žinynas + + + + &View + Rod&ymas + + + + &Options... + &Pasirinktys... + + + + &Resume + &Tęsti + + + + R&esume All + T&ęsti visus + + + + Torrent &creator + Su&kurti torentą + + + + + Alternative speed limits + Alternatyvūs greičio apribojimai + + + + Top &tool bar + Viršutinė įrankių juos&ta + + + + Display top tool bar + Rodyti viršutinę įrankių juostą + + + + &Speed in title bar + &Greitis pavadinimo juostoje + + + + Show transfer speed in title bar + Rodyti siuntimų greitį pavadinimo juostoje + + + + &About + &Apie + + + + &Add torrent file... + Pri&dėti torentą... + + + + + Exit + Išeiti + + + + &Pause + &Pristabdyti + + + + &Delete + Pašalin&ti + + + + P&ause All + Prist&abdyti visus + + + + Visit &Website + Aplankyti tink&lalapį + + + + Auto-Shutdown on downloads completion + Išjungti baigus siuntimus + + + + Add &link to torrent... + Pridėti nuorodą torentui... + + + + Report a &bug + Pranešti apie problemą + + + + Set upload limit... + Nustatyti išsiuntimo greičio ribą... + + + + Set download limit... + Nustatyti atsiuntimo greičio ribą... + + + + &Documentation + &Žinynas + + + + Set global download limit... + Nustatyti globalią atsiuntimo greičio ribą... + + + + Set global upload limit... + Nustatyti globalią išsiuntimo greičio ribą... + + + + &RSS reader + &RSS skaitytuvas + + + + Search &engine + Pai&eškos variklis + + + + Exit qBittorrent + Uždaryti qBittorrent + + + + Suspend system + Pristabdyti sistemą + + + + Shutdown system + Išjungti kompiuterį + + + + Disabled + Išjungtas + + + + + Lock qBittorrent + Užrakinti qBittorrent + + + + Ctrl+L + Ctrl+L + + + + Import existing torrent... + Įkelti egzistuojantį torentą... + + + + Import torrent... + Įkelti torentą... + + + + Donate money + Paaukoti pinigų + + + + If you like qBittorrent, please donate! + Jei Jums patinka qBittorrent, paaukokite! + + + + Execution &Log + Vykdymo žurna&las + + + + + Execution Log + Vykdymo žurnalas + + + + Decrease priority + Sumažinti svarbą + + + + Increase priority + Padidinti svarbą + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + Nustatyti slaptažodį... + + + + Transfers + Siuntimai + + + + Torrent file association + .torrent failų susiejimas + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent nėra numatytoji programa atverti .torrent failams bei Magnet nuorodoms. +Ar norite susieti .torrent failus bei Magnet nuorodas su qBittorrent? + + + + + + UI lock password + Vartotojo sąsajos užrakinimo slaptažodis + + + + + + Please type the UI lock password: + Įveskite vartotojo sąsajos užrakinimo slaptažodį: + + + + The password should contain at least 3 characters + + + + + Password update + Slaptažodžio atnaujinimas + + + + The UI lock password has been successfully updated + Vartotojo sąsajos užrakinimo slaptažodis sėkmingai atnaujintas + + + + RSS + RSS + + + + Search + Paieška + + + + Transfers (%1) + Siuntimai (%1) + + + + Download completion + Užbaigiamas atsiuntimas + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 baigta siųsti. + + + + I/O Error + i.e: Input/Output Error + I/O klaida + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Įvyko įvesties/išvesties klaida torentui %1. Priežastis: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Rekursyvaus siuntimo patvirtinimas + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torente %1 yra torentų failų. Ar norite atsiųsti ir juos? + + + + + Yes + Taip + + + + + No + Ne + + + + Never + Niekada + + + + Url download error + URL atsiuntimo klaida + + + + Couldn't download file at url: %1, reason: %2. + Nepavyko atsiųsti failo iš URL: %1, priežastis: %2. + + + + Global Upload Speed Limit + Globalus išsiuntimo greičio apribojimas + + + + Global Download Speed Limit + Globalus atsiuntimo greičio apribojimas + + + + + Invalid password + Neteisingas slaptažodis + + + + The password is invalid + Slaptažodis yra neteisingas + + + + Exiting qBittorrent + Uždaroma qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Šiuo metu vyksta kelių failų siuntimas. +Ar tikrai norite uždaryti qBittorrent? + + + + Always + Visada + + + + Open Torrent Files + Atverti torentų failus + + + + Torrent Files + Torentų failai + + + + Options were saved successfully. + Pasirinktys sėkmingai išsaugotos. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Ats. greitis: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Išs. greitis: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Ats.: %2/s, Išs.: %3/s) + + + + A newer version is available + Nauja versija yra prieinama + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Nauja qBittorrent versija yra prieinama Sourceforge tinklalapyje. +Ar norėtumėte atnaujinti qBittorrent į versiją: %1? + + + + Impossible to update qBittorrent + Neįmanoma atnaujinti qBittorrent + + + + qBittorrent failed to update, reason: %1 + qBittorrent nepavyko atsinaujinti, priežastis: %1 + + + + PeerAdditionDlg + + + Invalid IP + Neteisingas IP + + + + The IP you provided is invalid. + Jūsų nurodytas IP adresas yra neteisingas. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + IP + + + + Connection + Jungiamumas + + + + Client + i.e.: Client application + Klientas + + + + Progress + i.e: % downloaded + Baigta + + + + Down Speed + i.e: Download speed + Atsiuntimo greitis + + + + Up Speed + i.e: Upload speed + Išsiuntimo greitis + + + + Downloaded + i.e: total data downloaded + Atsiųsta + + + + Uploaded + i.e: total data uploaded + Išsiųsta + + + + Add a new peer... + Pridėti siuntėją... + + + + Copy IP + Kopijuoti IP adresą + + + + Limit download rate... + Apriboti atsiuntimo greitį... + + + + Limit upload rate... + Apriboti išsiuntimo greitį... + + + + Ban peer permanently + Uždrausti siuntėją visam laikui + + + + + Peer addition + Siuntėjo pridėjimas + + + + The peer was added to this torrent. + Šis siuntėjas buvo pridėtas prie torento. + + + + The peer could not be added to this torrent. + Siuntėjo pridėti prie torento nepavyko. + + + + Are you sure? -- qBittorrent + Ar tikrai? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Ar tikrai norite visam laikui uždrausti pasirinktus siuntėjus? + + + + &Yes + &Taip + + + + &No + &Ne + + + + Manually banning peer %1... + Rankiniu būdu uždraudžiamas siuntėjas %1... + + + + Upload rate limiting + Išsiuntimo greičio ribojimas + + + + Download rate limiting + Atsiuntimo greičio ribojimas + + + + Preferences + + UI + User Interface + Sąsajos nustatymai + + + + Downloads + Atsiuntimai + + + + Connection + Jungiamumas + + + + Speed + Greitis + + + + Web UI + Tinklo sąsaja + + + + Advanced + Sudėtingiau + + + Language: + Kalba: + + + + (Requires restart) + (būtina perkrauti) + + + Visual style: + Išvaizdos stilius: + + + Transfer list + Siuntimų sąrašas + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Naudoti skirtingas eilučių spalvas + + + + + Start / Stop Torrent + Pratęsti / pristabdyti torentą + + + + + No action + Jokio veiksmo + + + File system + Failų sistema + + + + Copy .torrent files to: + Kopijuoti .torrent failus į: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + + + + + Listening Port + + + + + Connections Limits + + + + + Proxy Server + + + + + Enable bandwidth management (uTP) + + + + + Enable Local Peer Discovery to find more peers + Įjungti vietinių siuntėjų aptikimą, kad rasti daugiau siuntėjų + + + + Encryption mode: + Šifravimo rėžimas: + + + + Prefer encryption + Teikti pirmenybę šifravimui + + + + Require encryption + Reikalauti šifravimo + + + + Disable encryption + Išjungti šifravimą + + + Torrent queueing + Siuntimų eilė + + + + Maximum active downloads: + Didžiausias aktyvių atsiuntimų kiekis: + + + + Maximum active uploads: + Didžiausias aktyvių išsiuntimų kiekis: + + + + Maximum active torrents: + Didžiausias aktyvių torentų kiekis: + + + + When adding a torrent + Kai pridedamas torentas + + + + + Behavior + + + + + Language + Kalba + + + + Display torrent content and some options + Rodyti torento turinį ir keletą nustatymų + + + Listening port + Klausymosi prievadas + + + + Port used for incoming connections: + Prievadas, naudojamas įeinantiems sujungimams: + + + + Random + Atsitiktinis + + + Connections limit + Prisijungimų limitas + + + + Global maximum number of connections: + Globalus didžiausias prisijungimų skaičius: + + + + Maximum number of connections per torrent: + Didžiausias prisijungimų kiekis vienam torentui: + + + + Maximum number of upload slots per torrent: + Didžiausias išsiuntimo prisijungimų kiekis vienam torentui: + + + + + Upload: + Išsiuntimo: + + + + + Download: + Atsiuntimo: + + + + + + + KiB/s + KiB/s + + + Global speed limits + Globalus greičio ribojimas + + + + Remove folder + Pašalinti aplanką + + + Alternative global speed limits + Alternatyvūs globalūs greičio apribojimai + + + + to + time1 to time2 + iki + + + + Every day + Kasdien + + + + Week days + Darbo dienomis + + + + Week ends + Savaitgaliais + + + + DHT port: + DHT prievadas: + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Keistis siuntėjais su suderinamais BitTorrent klientais (µTorrent, Vuze, ...) + + + + Host: + Stotis: + + + + SOCKS4 + SOCKS4 + + + + Type: + Tipas: + + + + + Options + Pasirinktys + + + User Interface + Vartotojo sąsaja + + + Visual Appearance + Išvaizda + + + + Action on double-click + Veiksmai dvigubam paspaudimui + + + + Downloading torrents: + Atsiunčiamiems torentams: + + + + + Open destination folder + Atverti atsiuntimo aplanką + + + + Completed torrents: + Užbaigtiems torentams: + + + + Desktop + Darbastalis + + + + Show splash screen on start up + Paleidus programą rodyti pradžios langą + + + + Start qBittorrent minimized + Paleisti qBittorrent sumažintą į sistemos dėklą + + + Show qBittorrent icon in notification area + Dėkle rodyti qBittorrent piktogramą + + + + Minimize qBittorrent to notification area + Sumažinti į dėklą + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Uždaryti qBittorrent į dėklą + + + + Tray icon style: + + + + + Normal + Normali + + + + Monochrome (Dark theme) + + + + + Monochrome (Light theme) + + + + + Ask for program exit confirmation + + + + + User Interface Language: + + + + + Transfer List + + + + + Show qBittorrent in notification area + + + + + Power Management + + + + + Inhibit system sleep when torrents are active + + + + + Do not start the download automatically + The torrent will be added to download list in pause state + Nepradėti atsiuntimų automatiškai + + + + Hard Disk + + + + + Save files to location: + Failus išsaugoti į: + + + + Append the label of the torrent to the save path + Saugojimo vietai pritaikyti torento etiketę + + + + Pre-allocate disk space for all files + Priskirti disko vietą visiems failams + + + + Keep incomplete torrents in: + Nebaigtus siuntimus laikyti čia: + + + Append .!qB extension to incomplete files' names + Pridėti .!qB plėtinį nebaigtiems siųsti failams + + + + Automatically add torrents from: + Automatiškai pridėti torentus iš: + + + + Add folder... + Pridėti aplanką... + + + + Email notification upon download completion + Pabaigus atsiuntimą, pranešti el. paštu + + + + Destination email: + Gavėjo el. pašto adresas: + + + + SMTP server: + SMTP serveris: + + + + This server requires a secure connection (SSL) + + + + + Run an external program on torrent completion + Užbaigus torento siuntimą paleisti išorinę programą + + + + Otherwise, the proxy server is only used for tracker connections + + + + + Use proxy for peer connections + + + + + Global Rate Limits + + + + + Apply rate limit to uTP connections + + + + + Apply rate limit to transport overhead + + + + + Alternative Global Rate Limits + + + + + Schedule the use of alternative rate limits + + + + + Use HTTPS instead of HTTP + + + + + Import SSL Certificate + + + + + Import SSL Key + + + + + Certificate: + + + + + Key: + + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + Update my dynamic domain name + + + + + Service: + + + + + Register + + + + + Domain name: + + + + Use %f to pass the torrent path in parameters + Naudokite %f, kad perduoti torento vietą parametruose + + + + Use UPnP / NAT-PMP port forwarding from my router + Naudoti UPnP / NAT-PMP prievadų nukreipimą mašrutizatoriuje + + + Proxy server + Proxy serveris + + + + IP Filtering + IP filtravimas + + + + Reload the filter + Įkelti filtrą iš naujo + + + Schedule the use of alternative speed limits + Planuoti alternatyvių greičio apribojimų taikymą + + + + from + from (time1 to time2) + nuo + + + + When: + Kada: + + + + Privacy + Privatumas + + + + Enable DHT (decentralized network) to find more peers + Įjungti DHT (išcentruotą tinklą), kad rasti daugiau siuntėjų + + + + Use a different port for DHT and BitTorrent + DHT ir BitTorrent tinklams naudoti skirtingus prievadus + + + + Enable Peer Exchange (PeX) to find more peers + Įjungti siuntėjų apsikeitimą (PeX), kad rasti daugiau siuntėjų + + + + Look for peers on your local network + Ieškoti siuntėjų vietiniame tinkle + + + Share ratio limiting + Dalinimosi santykio ribojimas + + + + Seed torrents until their ratio reaches + Skleisti torentus, kol jų dalinimosi santykis pasieks + + + + then + o tada + + + + Pause them + juos pristabdyti + + + + Remove them + juos pašalinti + + + + Use UPnP / NAT-PMP to forward the port from my router + + + + + Bypass authentication for localhost + + + + + (None) + (jokio) + + + + BitTorrent + BitTorrent + + + + HTTP + HTTP + + + + + Port: + Prievadas: + + + + + + Authentication + Atpažinimas + + + + Append .!qB extension to incomplete files + + + + + + + + Username: + Vartotojo vardas: + + + + + + + Password: + Slaptažodis: + + + + Torrent Queueing + + + + + Share Ratio Limiting + + + + + Enable Web User Interface (Remote control) + Įjungti Tinklo vartotojo sąsają (nuotolinis valdymas) + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + Kelias iki filtro (.dat, .p2p, .p2b): + + + HTTP Server + HTTP serveris + + + + PreviewSelect + + + Name + Vardas + + + + Size + Dydis + + + + Progress + Baigta + + + + + + Preview impossible + Peržiūra neįmanoma + + + + + + Sorry, we can't preview this file + Atsiprašome, tačiau negalime parodyti šio failo + + + + PropListDelegate + + + Not downloaded + Neatsiųstas + + + + + Normal + Normal (priority) + Normali + + + + + High + High (priority) + Aukšta + + + + Mixed + Mixed (priorities + Įvairi + + + + + Maximum + Maximum (priority) + Aukščiausia + + + + PropTabBar + + + General + Bendra + + + + Trackers + Trakeriai + + + + Peers + Siuntėjai + + + + HTTP Sources + HTTP šaltiniai + + + + Content + Failai + + + + PropertiesWidget + + + Save path: + Atsiuntimo vieta: + + + + Torrent hash: + Torento raktas: + + + + Share ratio: + Dalinimosi santykis: + + + + + Downloaded: + Atsisiųsta: + + + + Availability: + Pasiekiamumas: + + + + Transfer + Siuntimas + + + + Uploaded: + Išsiųsta: + + + + Wasted: + Iššvaistyta: + + + + UP limit: + Išsiuntimo riba: + + + + DL limit: + Atsiuntimo riba: + + + + Connections: + Prisijungimai: + + + + Time active: + Time (duration) the torrent is active (not paused) + Praėjo laiko: + + + + Reannounce in: + Atnaujinama už: + + + + Information + Informacija + + + + Created on: + Sukurtas: + + + + Pieces size: + Dalies dydis: + + + + Comment: + Komentaras: + + + + Torrent content: + Torento turinys: + + + + Select All + Pažymėti viską + + + + Select None + Nieko nežymėti + + + + Normal + Normali + + + + High + Aukšta + + + + Maximum + Aukščiausia + + + + + Do not download + Nesiųsti + + + + + this session + šioje sesijoje + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Skleidžiama jau %1 + + + + %1 max + e.g. 10 max + daugiausiai %1 + + + + + I/O Error + I/O klaida + + + + This file does not exist yet. + Šis failas dar neegzistuoja. + + + + This folder does not exist yet. + Šis aplankas dar neegzistuoja. + + + + Rename... + Pervadinti... + + + + Priority + Svarba + + + + Rename the file + Pervadinti failą + + + + New name: + Naujas vardas: + + + + + The file could not be renamed + Failo pervadinti nepavyko + + + + This file name contains forbidden characters, please choose a different one. + Šiame failo varde yra neleistinų simbolių, pasirinkite kitokį. + + + + + This name is already in use in this folder. Please use a different name. + Šis vardas šiame aplanke jau naudojamas. Pasirinkite kitokį vardą. + + + + The folder could not be renamed + Šio aplanko pervadinti nepavyko + + + + New url seed + New HTTP source + Naujo šaltinio adresas + + + + New url seed: + Naujo šaltinio adresas: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Šis adresas jau yra sąraše. + + + + + Choose save path + Pasirinkite išsaugojimo vietą + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 pasiekė didžiausią Jūsų nustatytą dalinimosi santykį. + + + + Removing torrent %1... + Šalinamas torentas %1... + + + + Pausing torrent %1... + Pristabdomas torentas %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent pririštas prie prievado: TCP/%1 + + + + HTTP user agent is %1 + HTTP vartotojo agentas yra %1 + + + + Reporting IP address %1 to trackers... + + + + + DHT support [ON], port: UDP/%1 + DHT palaikymas [ĮJUNGTAS], prievadas: UDP/%1 + + + + + DHT support [OFF] + DHT palaikymas [IŠJUNGTAS] + + + + PeX support [ON] + PeX palaikymas [ĮJUNGTAS] + + + + PeX support [OFF] + PeX palaikymas [IŠJUNGTAS] + + + + Restart is required to toggle PeX support + Būtina perkrauti programą norint pakeisti PeX palaikymą + + + + Local Peer Discovery support [OFF] + Vietinių siuntėjų aptikimo palaikymas [IŠJUNGTAS] + + + + Encryption support [ON] + Šifravimo palaikymas [ĮJUNGTAS] + + + + Encryption support [FORCED] + Šifravimo palaikymas [PRIVERSTINIS] + + + + Encryption support [OFF] + Šifravimo palaikymas [IŠJUNGTAS] + + + + Embedded Tracker [ON] + Įtaisytas trakeris [ĮJUNGTAS] + + + + Failed to start the embedded tracker! + Nepavyko paleisti įtaisyto trakerio! + + + + Embedded Tracker [OFF] + Įtaisytas trakeris [IŠJUNGTAS] + + + + The Web UI is listening on port %1 + Tinklo vartotojo sąsaja klausosi ties prievadu %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Tinklo vartotojo sąsajos klaida - Nepavyko pririšti tinklo vartotojo sąsajos prie prievado %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' buvo pašalintas iš siuntimų sąrašo bei kietojo disko. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' buvo pašalintas iš siuntimų sąrašo. + + + + '%1' is not a valid magnet URI. + '%1' yra negaliojanti Magnet URI. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' jau yra siuntimų sąraše. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' buvo pratęstas (spartusis pratęsimas) + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Sėkmingai įkeltas nurodytas IP filtras. %1 taisyklės pritaikytos. + + + + Error: Failed to parse the provided IP filter. + Klaida: Nepavyko įkelti nurodyto IP filtro. + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' buvo pridėtas į siuntimų sąrašą. + + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP palaikymas [ĮJUNGTAS] + + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP palaikymas [IŠJUNGTAS] + + + + Local Peer Discovery support [ON] + Vietinių siuntėjų aptikimo palaikymas [ĮJUNGTAS] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Nepavyko iššifruoti torento failo: '%1' + + + + This file is either corrupted or this isn't a torrent. + Šis failas yra arba sugadintas, arba tai ne torento failas. + + + + Error: The torrent %1 does not contain any file. + Klaida: Torente %1 nėra nė vieno failo. + + + + Note: new trackers were added to the existing torrent. + Pastaba: esamam torentui buvo pridėti nauji trakeriai. + + + + Note: new URL seeds were added to the existing torrent. + Pastaba: esamam torentui buvo pridėti tinklo siuntėjų šaltiniai. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>buvo užblokuotas atsižvelgiant į Jūsų IP filtrą</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>buvo užblokuotas dėl sugadintų dalių siuntimo</i> + + + + The network interface defined is invalid: %1 + Ši tinklo sąsaja yra netinkama: %1 + + + + Trying any other network interface available instead. + Bandoma kita prieinama tinklo sąsaja. + + + + Listening on IP address %1 on network interface %2... + Klausomasi IP adreso %1 tinklo sąsajoje %2... + + + + Failed to listen on network interface %1 + Nepavyko klausytis tinklo sąsajoje %1 + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekursyvus failo %1, įdėto į torentą %2, atsiuntimas + + + + + Unable to decode %1 torrent file. + Nepavyko iššifruoti %1 torento failo. + + + + Torrent name: %1 + Torento vardas: %1 + + + + Torrent size: %1 + Torento dydis: %1 + + + + Save path: %1 + Atsiuntimo vieta: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torentas atsiųstas per %1. + + + + Thank you for using qBittorrent. + Ačiū, kad naudojatės qBittorrent. + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 baigtas atsiųsti + + + + An I/O error occured, '%1' paused. + Įvyko I/O klaida, '%1' pristabdytas. + + + + + Reason: %1 + Priežastis: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Prievadų išdėstymas nesėkmingas, žinutė: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Prievadų išdėstymas sėkmingas, žinutė: %1 + + + + File sizes mismatch for torrent %1, pausing it. + Failų dydžio nesutapimas torente %1, jis pristabdomas. + + + + Fast resume data was rejected for torrent %1, checking again... + Greito pratęsimo duomenys atmesti torente %1, tikrinama iš naujo... + + + + Url seed lookup failed for url: %1, message: %2 + URL sklėidėjo patikrinimas nepavyko adresu: %1, pranešimas: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Atsiunčiamas '%1'. luktelkite... + + + + RSS + + + Search + Ieškoti + + + + New subscription + Nauja prenumerata + + + + + + Mark items read + Pažymėti visus kaip skaitytus + + + + Update all + Atnaujinti visus + + + + RSS Downloader... + RSS atsiuntimas... + + + + Settings... + Nuostatos... + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torentai:</span> <span style=" font-style:italic;">(spustelėkite dukart, kad parsisiųsti)</span></p></body></html> + + + + + Delete + Pašalinti + + + + Rename... + Pervadinti... + + + + Rename + Pervadinti + + + + + Update + Atnaujinti + + + + New subscription... + Nauja prenumerata... + + + + + Update all feeds + Atnaujinti visus srautus + + + + Download torrent + Atsisiųsti torentą + + + + Open news URL + Atverti naujienos URL + + + + Copy feed URL + Kopijuoti srauto URL + + + + New folder... + Naujas aplankas... + + + + Manage cookies... + Tvarkyti slapukus... + + + + Refresh RSS streams + Atnaujinti RSS srautus + + + + RSSImp + + + Please type a rss stream url + Įveskite RSS srauto URL adresą + + + + Stream URL: + Srauto URL: + + + + + Are you sure? -- qBittorrent + Ar tikrai? -- qBittorrent + + + + + &Yes + &Taip + + + + + &No + &Ne + + + + Please choose a folder name + Pasirinkite aplanko vardą + + + + Folder name: + Aplanko vardas: + + + + New folder + Naujas aplankas + + + + Overwrite attempt + Perrašymo bandymas + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Negalite perrašyti %1. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Šis RSS srautas jau yra sąraše. + + + + Are you sure you want to delete these elements from the list? + Ar tikrai norite pašalinti šiuos elementus iš sąrašo? + + + + Are you sure you want to delete this element from the list? + Ar tikrai norite pašalinti šį elementą iš sąrašo? + + + + Please choose a new name for this RSS feed + Pasirinkite naują vardą šiam RSS srautui + + + + New feed name: + Naujas srauto vardas: + + + + Name already in use + Šis vardas jau naudojamas + + + + This name is already used by another item, please choose another one. + Šis vardas jau naudojamas, pasirinkite kitokį vardą. + + + + Date: + Data: + + + + Author: + Autorius: + + + + Unread + Neskaityta + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Automatiškai atsiunčiamas torentas %1 iš %2 RSS srauto... + + + + RssSettingsDlg + + + RSS Reader Settings + RSS skaitytuvo nustatymai + + + + RSS feeds refresh interval: + RSS srautų atnaujinimo intervalas: + + + + minutes + minutės + + + + Maximum number of articles per feed: + Didžiausias įrašų sraute kiekis: + + + + ScanFoldersModel + + + Watched Folder + Stebimas aplankas + + + + Download here + Atsiųsti čia + + + + SearchCategories + + + All categories + Visos kategorijos + + + + Movies + Filmai + + + + TV shows + TV laidos + + + + Music + Muzika + + + + Games + Žaidimai + + + + Anime + Anime + + + + Software + Programinė įranga + + + + Pictures + Nuotraukos + + + + Books + Knygos + + + + SearchEngine + + + Cut + Iškirpti + + + + Copy + Kopijuoti + + + + Paste + Įdėti + + + + Clear field + Išvalyti + + + + Clear completion history + Išvalyti užbaigimų istoriją + + + + Confirmation + Patvirtinimas + + + + Are you sure you want to clear the history? + Ar tikrai norite išvalyti istoriją? + + + + + + Search + Paieška + + + + Missing Python Interpreter + Nerastas Python interpretuotojas + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Norint naudoti paieškos variklį būtinas Python 2.x, tačiau neatrodo, jog jis būtų įdiegtas. +Ar norite įdiegti jį dabar? + + + + Empty search pattern + Tuščias paieškos raktažodis + + + + Please type a search pattern first + Visų pirma nurodykite paieškos raktažodį + + + + + Results + Rezultatai + + + + Searching... + Ieškoma... + + + + Search Engine + Paieškos variklis + + + + + Search has finished + Paieška baigta + + + + An error occured during search... + Paieškos metu įvyko klaida... + + + + + Search aborted + Paieška nutraukta + + + + Download error + Atsiuntimo klaida + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Python įdiegties atsiųsti nepavyko, priežastis: %1. +Prašome padaryti tai rankiniu būdu. + + + + Search returned no results + Paieška negrąžino rezultatų + + + + Results + i.e: Search results + Rezultatai + + + + + Unknown + Nežinoma + + + + SearchTab + + + Name + i.e: file name + Vardas + + + + Size + i.e: file size + Dydis + + + + Seeders + i.e: Number of full sources + Skleidėjai + + + + Leechers + i.e: Number of partial sources + Siuntėjai + + + + Search engine + Paieškos variklis + + + + ShutdownConfirmDlg + + + Shutdown confirmation + + + + + SpeedLimitDialog + + + KiB/s + KiB/s + + + + StatusBar + + + + Connection status: + Prisijungimo būsena: + + + + + No direct connections. This may indicate network configuration problems. + Nėra tiesioginių susijungimų. Tai gali reikšti tinklo nustatymo problemas. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + Ats.: %1 B/s Viso: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + Išs.: %1 B/s Viso: %2 + + + + + DHT: %1 nodes + DHT: %1 mazgų + + + + qBittorrent needs to be restarted + qBittorrent turi būti perkrautas + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent kątik atsinaujino ir ją reikia perkrauti, norint, kad įsigaliotų nauji pakeitimai. + + + + + Connection Status: + Prisijungimo būsena: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Neprisijungta. Tai dažniausiai reiškia, jog qBittorrent nepavyko klausytis ties pasirinktu prievadu. + + + + Online + Prisijungta + + + + + %1/s + Per second + %1/s + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Ats.: %1/s Viso: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Išs.: %1/s Viso: %2 + + + + Click to switch to alternative speed limits + + + + + Click to switch to regular speed limits + + + + Click to disable alternative speed limits + Spauskite, jei norite išjungti alternatyvius greičio apribojimus + + + Click to enable alternative speed limits + Spauskite, jei norite įjungti alternatyvius greičio apribojimus + + + + Global Download Speed Limit + Globalus atsiuntimo greičio apribojimas + + + + Global Upload Speed Limit + Globalus išsiuntimo greičio apribojimas + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Pasirinkite aplanką, kurį norite įdėti į torentą + + + + Select a file to add to the torrent + Pasirinkite failą, kurį norite įdėti į torentą + + + + No input path set + Nenurodyta įvesties vieta + + + + Please type an input path first + Visų pirma nurodykite įvesties vietą + + + + Select destination torrent file + Pasirinkite, kur norite išsaugoti torentą + + + + Torrent Files + Torentų failai + + + + + + Torrent creation + Torento kūrimas + + + + Torrent creation was unsuccessful, reason: %1 + Torento sukurti nepavyko, priežasitis: %1 + + + + Created torrent file is invalid. It won't be added to download list. + Sukurtas torento failas yra sugadintas. Jis nebus pridėtas į siuntimų sąrašą. + + + + Torrent was created successfully: + Torentas sėkmingai sukurtas: + + + + TorrentFilesModel + + + Name + Vardas + + + + Size + Dydis + + + + Progress + Baigta + + + + Priority + Svarba + + + + TorrentImportDlg + + + Torrent Import + Torentų įkėlimas + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Šis vedlys padės Jums dalintis torentu, kurį jau atsisiuntėte, programoje qBittorrent. + + + + Torrent file to import: + Įkeliamo torento failas: + + + + + ... + ... + + + + Content location: + Turinio vieta: + + + + Skip the data checking stage and start seeding immediately + Praleisti failų tikrinimą ir iškart pradėti skleidimą + + + + Import + Įkelti + + + + Torrent file to import + Įkeliamo torento failas + + + + Torrent files (*.torrent) + Torentų failai (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 tipo failai + + + + Please provide the location of %1 + %1 is a file name + Nurodykite %1 saugojimo vietą + + + + Please point to the location of the torrent: %1 + Nurodykite torento %1 saugojimo vietą + + + + Invalid torrent file + + + + + This is not a valid torrent file. + + + + + TorrentModel + + + Name + i.e: torrent name + Vardas + + + + Size + i.e: torrent size + Dydis + + + + Done + % Done + Baigta + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Būsena + + + + Seeds + i.e. full sources (often untranslated) + Skleidėjai + + + + Peers + i.e. partial sources (often untranslated) + Siuntėjai + + + + Down Speed + i.e: Download speed + Ats. greitis + + + + Up Speed + i.e: Upload speed + Išs. greitis + + + + Ratio + Share ratio + Santykis + + + + ETA + i.e: Estimated Time of Arrival / Time left + Liko + + + + Label + Etiketė + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Pridėta + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Užbaigta + + + + Tracker + Trakeris + + + + Down Limit + i.e: Download limit + Ats. riba + + + + Up Limit + i.e: Upload limit + Išs. riba + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Atsiųsta + + + + Amount left + Amount of data left to download (e.g. in MB) + Liko siųsti + + + + Time Active + Time (duration) the torrent is active (not paused) + Aktyvus + + + + TrackerList + + + URL + URL + + + + Status + Būsena + + + + Peers + Siuntėjai + + + + Message + Žinutė + + + + [DHT] + [DHT] + + + + [PeX] + [PeX] + + + + [LSD] + [LSD] + + + + + + + + Working + Veikia + + + + + + Disabled + Išjungta + + + + This torrent is private + Šis torentas yra privatus + + + + Updating... + Atnaujinama... + + + + + Not working + Neveikia + + + + + Not contacted yet + Dar nesusisiekta + + + + Add a new tracker... + Pridėti trakerį... + + + + Remove tracker + Pašalinti trakerį + + + + Force reannounce + Priverstinai atnaujinti + + + + TrackersAdditionDlg + + + Trackers addition dialog + Trakerių pridėjimo vedlys + + + + List of trackers to add (one per line): + Norimų pridėti trakerių sąrašas (po vieną eilutėje): + + + + µTorrent compatible list URL: + Suderinamo su µTorrent sąrašo URL: + + + + I/O Error + I/O klaida + + + + Error while trying to open the downloaded file. + Klaida bandant atidaryti atsiųstą failą. + + + + No change + Jokių pokyčių + + + + No additional trackers were found. + Nerasta jokių papildomų trakerių. + + + + Download error + Atsiuntimo klaida + + + + The trackers list could not be downloaded, reason: %1 + Trakerių sąrašo atsiųsti nepavyko, priežastis: %1 + + + + TransferListDelegate + + + Downloading + Atsiunčiama + + + + Paused + Pristabdyta + + + + Queued + i.e. torrent is queued + Eilėje + + + + Seeding + Torrent is complete and in upload-only mode + Skleidžiama + + + + Stalled + Torrent is waiting for download to begin + Laukiama + + + + Checking + Torrent local data is being checked + Tikrinama + + + + /s + /second (.i.e per second) + /s + + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Skleidžiama jau %1 + + + + TransferListFiltersWidget + + + + All + Visi + + + + + Downloading + Atsiunčiama + + + + + Completed + Užbaigta + + + + + Paused + Pristabdyti + + + + + Active + Aktyvūs + + + + + Inactive + Neaktyvūs + + + + + All labels + Visos etiketės + + + + + Unlabeled + Be etiketės + + + + Remove label + Pašalinti etiketę + + + + Add label... + Pridėti etiketę... + + + + Resume torrents + Prastęsti torentus + + + + Pause torrents + Pristabdyti torentus + + + + Delete torrents + Pašalinti torentus + + + + New Label + Nauja etiketė + + + + Label: + Etiketė: + + + + Invalid label name + Neteisingas etiketės vardas + + + + Please don't use any special characters in the label name. + Etiketės varde nenaudokite jokių specialiųjų simbolių. + + + + TransferListWidget + + + Column visibility + Stulpelio matomumas + + + + Label + Etiketė + + + + Choose save path + Pasirinkite išsaugojimo vietą + + + + Torrent Download Speed Limiting + Torento atsiuntimo greičio ribojimas + + + + Torrent Upload Speed Limiting + Torento išsiuntimo greičio ribojimas + + + + New Label + Nauja etiketė + + + + Label: + Etiketė: + + + + Invalid label name + Neteisingas etiketės vardas + + + + Please don't use any special characters in the label name. + Etiketės varde nenaudokite jokių specialiųjų simbolių. + + + + Rename + Pervadinti + + + + New name: + Naujas vardas: + + + + Resume + Resume/start the torrent + Tęsti + + + + Pause + Pause the torrent + Pristabdyti + + + + Delete + Delete the torrent + Pašalinti + + + + Preview file... + Peržiūrėti failą... + + + + Limit share ratio... + + + + + Limit upload rate... + Apriboti išsiuntimo greitį... + + + + Limit download rate... + Apriboti atsiuntimo greitį... + + + + Open destination folder + Atverti atsiuntimo aplanką + + + + Move up + i.e. move up in the queue + Aukštyn + + + + Move down + i.e. Move down in the queue + Žemyn + + + + Move to top + i.e. Move to top of the queue + Į viršų + + + + Move to bottom + i.e. Move to bottom of the queue + Į apačią + + + + Set location... + Nustatyti saugojimo vietą... + + + + Priority + Svarba + + + + Force recheck + Priverstinai pertikrinti + + + + Copy magnet link + Kopijuoti Magnet nuorodą + + + + Super seeding mode + Super skleidimo rėžimas + + + + Rename... + Pervadinti... + + + + Download in sequential order + Siųsti dalis iš eilės + + + + Download first and last piece first + Visų pirma siųsti pirmą ir paskutinę dalį + + + + New... + New label... + Nauja... + + + + Reset + Reset label + Nustatyti iš naujo + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + + + + + Use global ratio limit + + + + + + + buttonGroup + + + + + Set no ratio limit + + + + + Set ratio limit to + + + + + UsageDisplay + + + Usage: + Naudojimas: + + + + displays program version + rodo programos versiją + + + + disable splash screen + išjungti pradžios langą + + + + displays this help message + rodo šį pagalbos pranešimą + + + + changes the webui port (current: %1) + pakeičia tinklo sąsajos prievadą (dabartinis: %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [failai arba URL adresai]: atsiunčia torentus, perduotus vartotojo (neprivalomas) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Norėčiau padėkoti šiems žmonėms, kurie savanoriškai išvertė qBittorrent: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Susisiekite su manimi, jei norite išversti qBittorrent į savo kalbą. + + + + addPeerDialog + + + Peer addition + Siuntėjo pridėjimas + + + + IP + IP + + + + Port + Prievadas + + + + addTorrentDialog + + + Torrent addition dialog + Torento pridėjimo vedlys + + + + Save path: + Atsiuntimo vieta: + + + + ... + ... + + + + Torrent size: + Torento dydis: + + + + + Unknown + Nežinoma + + + + Free disk space: + Laisva vieta diske: + + + + Label: + Etiketė: + + + + Torrent content: + Torento turinys: + + + + Select All + Pasirinkti viską + + + + Select None + Nieko nesirinkti + + + + Download in sequential order (slower but good for previewing) + Siųsti dalis iš eilės (lėčiau, tačiau tinka peržiūrai) + + + + Skip file checking and start seeding immediately + Praleisti failų tikrinimą ir iškart pradėti skleidimą + + + + Add to download list in paused state + Pridėti į siuntimų sąrašą pristabdytoje būsenoje + + + + Add + Pridėti + + + + Cancel + Atšaukti + + + + Normal + Normali + + + + High + Aukšta + + + + Maximum + Aukščiausia + + + + + Do not download + Nesiųsti + + + + authentication + + + + Tracker authentication + Trakerio atpažinimas + + + + Tracker: + Trakeris: + + + + Login + Prisijungimas + + + + Username: + Vartotojo vardas: + + + + Password: + Slaptažodis: + + + + Log in + Prisijungti + + + + Cancel + Atšaukti + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Ištrinimo patvirtinimas - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Ar tikrai norite pašalinti pasirinktus torentus iš siuntimų sąrašo? + + + + Remember choice + Atsiminti pasirinkimą + + + + Also delete the files on the hard disk + Taipogi pašalinti failus iš kietojo disko + + + + createTorrentDialog + + + Cancel + Atšaukti + + + + Torrent Creation Tool + Torento kūrimo vedlys + + + + Torrent file creation + Torento failo kūrimas + + + + Add file + Pridėti failą + + + + Add folder + Pridėti aplanką + + + + File or folder to add to the torrent: + Failas arba aplankas, įdedamas į torentą: + + + + Tracker URLs: + Trakerių URL: + + + + Web seeds urls: + Skleidimo tinkle URL: + + + + Comment: + Komentaras: + + + + Piece size: + Dalies dydis: + + + + 32 KiB + 32 KiB + + + + 64 KiB + 64 KiB + + + + 128 KiB + 128 KiB + + + + 256 KiB + 256 KiB + + + + 512 KiB + 512 KiB + + + + 1 MiB + 1 MiB + + + + 2 MiB + 2 MiB + + + + 4 MiB + 4 MiB + + + + Auto + nustatyti automatiškai + + + + Private (won't be distributed on DHT network if enabled) + Privatus (nebus prieinamas DHT tinkle, jei šis įjungtas) + + + + Start seeding after creation + Pradėti skleisti po sukūrimo + + + + Create and save... + Kurti ir išsaugoti... + + + + Progress: + Baigta: + + + + downloadFromURL + + + Add torrent links + Pridėti torentų nuorodas + + + + Both HTTP and Magnet links are supported + Palaikomos ir HTTP, ir Magnet nuorodos + + + + Download + Atsiųsti + + + + Cancel + Atšaukti + + + + Download from urls + Atsiųsti iš URL adreso + + + + No URL entered + Neįvestas URL + + + + Please type at least one URL. + Įveskite bent vieną URL adresą. + + + + downloadThread + + I/O Error + I/O klaida + + + The remote host name was not found (invalid hostname) + Serverio vardas nerastas (negaliojantis serverio vardas) + + + The operation was canceled + Veiksmas buvo atšauktas + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Serveris netinkamai nutraukė prisijungimą, nespėjus gauti bei apdoroti pilno atsakymo + + + The connection to the remote server timed out + Baigėsi prisijungimui skirtas laikas + + + SSL/TLS handshake failed + SSL/TLS pasisveikinimas nepavyko + + + The remote server refused the connection + Serveris atmetė prisijungimą + + + The connection to the proxy server was refused + Proxy serveris atmetė prisijungimą + + + The proxy server closed the connection prematurely + Proxy serveris netinkamai nutraukė prisijungimą + + + The proxy host name was not found + Proxy stoties vardas nerastas + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Baigėsi prisijungimui prie proxy serverio skirtas laikas arba proxy serveris laiku neatsakė į užklausą + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Proxy serveris reikalauja atpažinimo, norint įvykdyti užklausą, tačiau nepriėmė jokių siūlytų duomenų + + + The access to the remote content was denied (401) + Priėjimas prie turinio buvo uždraustas (401) + + + The operation requested on the remote content is not permitted + Užklaustas veiksmas yra neleistinas serveryje + + + The remote content was not found at the server (404) + Turinys serveryje nerastas (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Serveris reikalauja atpažinimo, norint įvykdyti užklausą, tačiau nepriėmė jokių siūlytų duomenų + + + The Network Access API cannot honor the request because the protocol is not known + Tinklo priėjimo API negali įvykdyti užklausos, nes užklausos protokolas nežinomas + + + The requested operation is invalid for this protocol + Šis veiksmas yra negalimas šiam protokolui + + + An unknown network-related error was detected + Įvyko nežinoma tinklo klaida + + + An unknown proxy-related error was detected + Įvyko nežinoma proxy klaida + + + An unknown error related to the remote content was detected + Įvyko nežinoma serverio klaida + + + A breakdown in protocol was detected + Protokole aptiktas gedimas + + + Unknown error + Nežinoma klaida + + + + engineSelect + + + Search plugins + Ieškyklės + + + + Installed search engines: + Įdiegti paieškos varikliai: + + + + Name + Vardas + + + + Url + URL + + + + + Enabled + Įjungtas + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Naujų paieškos variklių galite gauti čia: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Įdiegti naują + + + + Check for updates + Tikrinti, ar yra atnaujinimų + + + + Close + Uždaryti + + + + Uninstall + Pašalinti + + + + engineSelectDlg + + + Uninstall warning + Pašalinimo įspėjimas + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Kai kurių priedų nepavyko pašalinti, nes jie integruoti į qBittorrent. +Pašalinti galima tik tuos priedus, kuriuos pridėjote Jūs. +Nepaisant to, tie priedai buvo išjungti. + + + + Uninstall success + Sėkmingai pašalinta + + + + Select search plugins + Pasirinkite paieškos priedus + + + + qBittorrent search plugins + qBittorrent paieškos priedai + + + + + + + + Search plugin install + Paieškos priedo įdiegimas + + + + + + Yes + Taip + + + + + + + No + Ne + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Naujesnė priedo %1 versija jau įdiegta. + + + + + + + Search plugin update + Paieškos priedo atnaujinimas + + + + + Sorry, update server is temporarily unavailable. + Atsiprašome, atnaujinimų serveris kolkas nepasiekiamas. + + + + All your plugins are already up to date. + Visi priedai yra naujausios laidos. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 paieškos priedo nepavyko atnaujinti, paliekama senoji versija. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 paieškos priedo nepavyko įdiegti. + + + + All selected plugins were uninstalled successfully + Visi pasirinkti priedai buvo sėkmingai pašalinti + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 paieškos priedas buvo sėkmingai atnaujintas. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1 paieškos priedas buvo sėkmingai įdiegtas. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Atsiprašome, %1 paieškos priedo įdiegti nepavyko. + + + + New search engine plugin URL + Naujo paieškos priedo URL + + + + URL: + URL: + + + + misc + + + B + bytes + B + + + + KiB + kibibytes (1024 bytes) + KiB + + + + MiB + mebibytes (1024 kibibytes) + MiB + + + + GiB + gibibytes (1024 mibibytes) + GiB + + + + TiB + tebibytes (1024 gibibytes) + TiB + + + + %1h %2m + e.g: 3hours 5minutes + %1 val. %2 min. + + + + %1d %2h + e.g: 2days 10hours + %1 diena %2 val. + + + + Unknown + Unknown (size) + Nežinoma + + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent dabar išjungs kompiuterį, kadangi visi siuntimai baigti. + + + + + + + + + Unknown + Nežinoma + + + + < 1m + < 1 minute + < 1 min. + + + + %1m + e.g: 10minutes + %1 min. + + + + options_imp + + + + Choose export directory + Pasirinkite eksportavimo aplanką + + + + + + + Choose a save directory + Pasirinkite išsaugojimo aplanką + + + + + Choose an ip filter file + Pasirinkite IP filtrų failą + + + + Add directory to scan + Pridėkite norimą skenuoti aplanką + + + + Folder is already being watched. + Šis aplankas jau stebimas. + + + + Folder does not exist. + Aplankas neegzistuoja. + + + + Folder is not readable. + Aplanko skaityti nepavyko. + + + + Failure + Nepavyko + + + + Failed to add Scan Folder '%1': %2 + Nepavyko pridėti skenuojamo aplanko '%1': %2 + + + + + Filters + Filtrai + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + + Parsing error + Įkėlimo klaida + + + + Failed to parse the provided IP filter + Nepavyko įkelti nurodyto IP filtro + + + + Successfully refreshed + + + + + Invalid key + + + + + This is not a valid SSL key. + + + + + Invalid certificate + + + + + This is not a valid SSL certificate. + + + + Succesfully refreshed + Sėkmingai atnaujinta + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Nurodytas IP filtras sėkmingai įkeltas. %1 taisyklės pritaikytos. + + + + pluginSourceDlg + + + Plugin source + Priedo šaltinis + + + + Search plugin source: + Ieškoti priedo šaltinio: + + + + Local file + Vietiniame faile + + + + Web link + Tinklo nuorodoje + + + + preview + + + Preview selection + Peržiūrėti pasirinktą dalį + + + + File preview + Failo peržiūra + + + + The following files support previewing, <br>please select one of them: + Šių failų peržiūra yra palaikoma,<br>pasirinkite vieną iš jų: + + + + Preview + Peržiūrėti + + + + Cancel + Atšaukti + + + + search_engine + + + + Search + Ieškoti + + + + Status: + Būsena: + + + + Stopped + Sustabdyta + + + + Download + Parsisiųsti + + + + Go to description page + Eiti į aprašymo puslapį + + + + Search engines... + Paieškos varikliai... + + + + torrentAdditionDialog + + + Unable to decode magnet link: + Nepavyko iššifruoti Magnet nuorodos: + + + + Magnet Link + Magnet nuoroda + + + + + Unable to decode torrent file: + Nepavyko iššifruoti torento failo: + + + + Rename... + Pervadinti... + + + + Priority + Svarba + + + + Rename the file + Pervadinti failą + + + + New name: + Naujas vardas: + + + + + The file could not be renamed + Failo pervadinti nepavyko + + + + This file name contains forbidden characters, please choose a different one. + Šiame failo varde yra neleistinų simbolių, pasirinkite kitokį. + + + + + This name is already in use in this folder. Please use a different name. + + + + + The folder could not be renamed + Šio aplanko pervadinti nepavyko + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 liks po torento atsiuntimo) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (atsiuntimui papildomai reikia %1) + + + + + + Choose save path + Pasirinkite išsaugojimo vietą + + + + Empty save path + Tuščia išsaugojimo vieta + + + + Please enter a save path + Įveskite išsaugojimo vietą + + + + Save path creation error + Išsaugojimo vietos kūrimo klaida + + + + Could not create the save path + Nepavyko sukurti išsaugojimo vietos aplanko + + + + Invalid label name + Neteisingas etiketės vardas + + + + Please don't use any special characters in the label name. + Etiketės varde nenaudokite jokių specialiųjų simbolių. + + + + Seeding mode error + Skleidimo rėžimo klaida + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Pasirinkote praleisti falių patikrinimą. Vis dėlto, neatrodo, jog nurodytame išsaugojimo aplanke egzistuotų vietiniai failai. Išjunkite šią savybę arba pataisykite išsaugojimo vietą. + + + + Invalid file selection + Neteisingai pasirinkti failai + + + + You must select at least one file in the torrent + Privalote pasirinkti bent vieną torente esantį failą + + + diff --git a/src/lang/qbittorrent_nb.qm b/src/lang/qbittorrent_nb.qm new file mode 100644 index 0000000000000000000000000000000000000000..f6fbf618edc9d243f0ff42ff87d3d378c6494edb GIT binary patch literal 120769 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 Mb4d)%0bju={@{l^eDNgb>+ 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 Qt&z3=EyVCwUwP&K0(LQLc>n+a literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_nb.ts b/src/lang/qbittorrent_nb.ts new file mode 100644 index 000000000..14ef70533 --- /dev/null +++ b/src/lang/qbittorrent_nb.ts @@ -0,0 +1,5701 @@ + + + + + AboutDlg + + + About qBittorrent + Om qBittorrent + + + + About + Om + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">En Bittorrent klient programert i C++, basert på Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">og libtorrent-rasterbar. <br /><br />Opphavsrett ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Hjemmeside:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + Author + Opphavsperson + + + + Name: + Navn: + + + + Country: + Land: + + + + E-mail: + E-post: + + + + Christophe Dumez + Christophe Dumez + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">En avansert Bittorrent klient programert i C++, basert på Qt4 toolkit og libtorrent-rasterbar. <br /><br />Opphavsrett ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Hjemmeside:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Feilsporer:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + France + Frankrike + + + + Translation + Oversettelse + + + + License + Lisens + + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + + chris@qbittorrent.org + chris@qbittorrent.org + + + + Thanks to + Takk til + + + + AdvancedSettings + + Property + Egenskap + + + Value + Verdi + + + + Disk write cache size + Disk-skrivnings hurtiglagerstørrelse + + + + MiB + MiB + + + + Outgoing ports (Min) [0: Disabled] + Utgående porter (Min) [0: Deaktivert] + + + + Outgoing ports (Max) [0: Disabled] + Utgående porter (Maks) [0: Deaktivert] + + + + Recheck torrents on completion + Sjekk torrenter på nytt ved fullførelse + + + + Transfer list refresh interval + Overføringsliste oppdateringsintervall + + + + ms + milliseconds + ms + + + + Setting + Innstilling + + + + Value + Value set for this setting + Verdi + + + + Resolve peer countries (GeoIP) + Løs deltakerland (GeoIP) + + + + Resolve peer host names + Løs deltaker-vertsnavn + + + + Maximum number of half-open connections [0: Disabled] + Maksimalt antall halvåpne tilkoblinger [0: Deaktivert] + + + + Strict super seeding + Streng supergivning + + + + Network Interface (requires restart) + Nettverksgrensesnitt (krever omstart) + + + + Exchange trackers with other peers + Utveksle sporere med andre deltakere + + + + Any interface + i.e. Any network interface + Hvilket som helst grensesnitt + + + + IP Address to report to trackers (requires restart) + IP Adresse som skal rapporteres til sporere (krever omstart) + + + + Display program on-screen notifications + Vis programvarslinger på skjermen + + + + Confirm torrent deletion + Bekreft sletting av torrenter + + + Display program notification balloons + Vis programvarslingsballonger + + + + Enable embedded tracker + Aktiver innebygd sporer + + + + Embedded tracker port + Innebygd sporerport + + + + Check for software updates + Søk etter programvareoppdateringer + + + + Use system icon theme + Bruk systemikon tema + + + + Ignore transfer limits on local network + Ignorer overføringsgrenser på lokale nettverk + + + Include TCP/IP overhead in transfer limits + Inkluder TCP/IP tilleggsdata i overføringsgrenser + + + + AutomatedRssDownloader + + + Automated RSS Downloader + Automatisert nyhetsmatingsnedlaster + + + + Enable the automated RSS downloader + Aktiver den automatiserte nyhetsmatingsnedlasteren + + + + Download rules + Nedlastingsregler + + + + Rule definition + Regeldefinisjon + + + + Must contain: + Må inneholde: + + + + Must not contain: + Må ikke inneholde: + + + + Use regular expressions + Bruk regulære uttrykk + + + + Import... + Importer... + + + + Export... + Eksporter... + + + + ... + ... + + + + Assign label: + Tildel etikett: + + + + Save to a different directory + Lagre til en annen katalog + + + + Save to: + Lagre til: + + + + Apply rule to feeds: + Bruk regel til matinger: + + + + Matching RSS articles + Matchende nyhetsmatingsartikler + + + + New rule name + Navn på ny regel + + + + Please type the name of the new download rule. + Vennligst skriv navnet på den nye nedlastingsregelen. + + + + + Rule name conflict + Regelnavn konflikt + + + + + A rule with this name already exists, please choose another name. + En regel med dette navnet eksisterer allerede, vennligst velg et annet navn. + + + + Are you sure you want to remove the download rule named %1? + Er du sikker på at du vil fjerne nedlastingsregelen som heter %1? + + + + Are you sure you want to remove the selected download rules? + Er du sikker på at du vil fjerne de valgte nedlastingsreglene? + + + + Rule deletion confirmation + Regelslettingsbekreftelse + + + + Destination directory + Destinasjonskatalog + + + + Invalid action + Ugyldig handling + + + + The list is empty, there is nothing to export. + Listen er tom, det er ingenting å eksportere. + + + + Where would you like to save the list? + Hvor vil du lagre listen? + + + + Rules list (*.rssrules) + Regelliste (*.rssrules) + + + + I/O Error + Inn/ut-operasjonsfeil + + + + Failed to create the destination file + Oppretting av destinasjonsfil mislyktes + + + + Please point to the RSS download rules file + Vennligst pek på filen med nyhetsmating-nedlastingsreglene + + + + Rules list (*.rssrules *.filters) + Regelliste (*.rssrules *.filters) + + + + Import Error + Importeringsfeil + + + + Failed to import the selected rules file + Importering av den valgte regelfilen mislyktes + + + + Add new rule... + Legg til ny regel... + + + + Delete rule + Slett regel + + + + Rename rule... + Omdøp regel... + + + + Delete selected rules + Slett valgte regler + + + + Rule renaming + Regel omdøping + + + + Please type the new rule name + Vennligst skriv nytt regelnavn + + + + Regex mode: use Perl-like regular expressions + Regex modus: bruk Perl-lignende regulære uttrykk + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Jokertegnmodus: du kan bruke<ul><li>? til å matche hvilke som helst enkle tegn</li><li>* for å matche null eller mer av hvilke som helst tegn</li><li>Blanktegn teller som OG-operatører</li></ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Jokertegnmodus: du kan bruke<ul><li>? til å matche hvilke som helst enkle tegn</li><li>* for å matche null eller mer av hvilke som helst tegn</li><li>| er brukt som ELLER-operatør</li></ul> + + + + Bittorrent + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' finnes allerede i nedlastingslisten. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' ble gjenopptatt (hurtig gjenopptaging) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' ble lagt til i nedlastingslisten. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Klarte ikke å dekode torrentfilen: '%1' + + + This file is either corrupted or this isn't a torrent. + Denne filen er enten ødelagt, eller det er ikke en torrent. + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Laster ned '%1'... + + + + CookiesDlg + + + Cookies management + Behandling av cookies + + + + Key + As in Key/Value pair + Nøkkel + + + + Value + As in Key/Value pair + Verdi + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Vanlige nøkler for cookies er : '%1', '%2'. +Du bør hente denne informasjonen fra nettleseren din sine innstillinger. + + + + DNSUpdater + + + Your dynamic DNS was successfuly updated. + Din dynamiske DNS ble vellykket oppdatert. + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Dynamisk DNS feil: Tjenesten er midlertidig utilgjengelig, det vil bli prøvd på nytt om 30 minutter. + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Dynamisk DNS feil: Oppgitt vertsnavn eksisterer ikke under spesifisert konto. + + + + Dynamic DNS error: Invalid username/password. + Dynamisk DNS feil: Ugyldig brukernavn/passord. + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Dynamisk DNS feil: qBittorrent ble svartelistet av tjenesten, vennligst rapporter en feil hos http://bugs.qbittorrent.org. + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Dynamisk DNS feil: %1 ble gitt av tjenesten, vennligst rapporter en feil hos http://bugs.qbittorrent.org. + + + + Dynamic DNS error: Your username was blocked due to abuse. + Dynamisk DNS feil: Ditt brukernavn ble blokkert pga. misbruk. + + + + Dynamic DNS error: supplied domain name is invalid. + Dynamisk DNS feil: oppgitt domenenavn er ugyldig. + + + + Dynamic DNS error: supplied username is too short. + Dynamisk DNS feil: oppgitt brukernavn er for kort. + + + + Dynamic DNS error: supplied password is too short. + Dynamisk DNS feil: oppgitt passord er for kort. + + + + DownloadThread + + + + I/O Error + Inn/ut-operasjonsfeil + + + + The remote host name was not found (invalid hostname) + Det eksterne vertsnavnet ble ikke funnet (ugyldig vertsnavn) + + + + The operation was canceled + Operasjonen ble avbrutt + + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Den eksterne tjeneren stengte tilkoblingen for tidlig, før hele svaret ble mottatt og bearbeidet + + + + The connection to the remote server timed out + Tilkoblingen til den eksterne tjeneren endte i tidsavbrudd + + + + SSL/TLS handshake failed + SSL/TLS håndtrykk mislyktes + + + + The remote server refused the connection + Den eksterne tjeneren nektet tilkoblingen + + + + The connection to the proxy server was refused + Tilkoblingen til mellomtjeneren ble nektet + + + + The proxy server closed the connection prematurely + Mellomtjeneren stengte tilkoblingen for tidlig + + + + The proxy host name was not found + Mellomtjenerens vertsnavn ble ikke funnet + + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Tilkoblingen til mellomtjeneren endte i tidsavbrudd, eller mellomtjeneren svarte ikke i tide på forespørselen som ble sendt + + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Mellomtjeneren krever autentisering for å kunne hedre forespørselen, men godtok ikke noen av attestene som ble tilbudt + + + + The access to the remote content was denied (401) + Tilgangen til det eksterne innholdet ble nektet (401) + + + + The operation requested on the remote content is not permitted + Operasjonen som blir forespurt på det eksterne innholdet er ikke tillatt + + + + The remote content was not found at the server (404) + Det eksterne innholdet ble ikke funnet på tjeneren (404) + + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Den eksterne tjeneren krever autentisering for å kunne servere innholdet, men attestene som ble oppgitt ble ikke akseptert + + + + The Network Access API cannot honor the request because the protocol is not known + Nettverktilgangens applikasjon-programeringsgrensesnitt kan ikke hedre forespørselen fordi protokollen ikke er kjent + + + + The requested operation is invalid for this protocol + Den forespurte operasjonen er ugyldig for denne protokollen + + + + An unknown network-related error was detected + En ukjent nettverksrelatert feil ble oppdaget + + + + An unknown proxy-related error was detected + En ukjent mellomtjenerrelatert feil ble oppdaget + + + + An unknown error related to the remote content was detected + En ukjent feil relatert til det eksterne innholdet ble oppdaget + + + + A breakdown in protocol was detected + En driftstans i protokollen ble oppdaget + + + + Unknown error + Ukjent feil + + + + EventManager + + + + Working + Virker + + + + Updating... + Oppdaterer... + + + + + Not working + Virker ikke + + + + + Not contacted yet + Ikke kontaktet ennå + + + + + this session + denne sesjonen + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Gitt ut i %1 + + + + %1 max + e.g. 10 max + %1 maks + + + + + %1/s + e.g. 120 KiB/s + %1/s + + + + ExecutionLog + + + General + Generelt + + + + Blocked IPs + Blokerte IPer + + + + FeedDownloader + + ... + ... + + + + FeedDownloaderDlg + + Choose save path + Velg filsti for nedlasting + + + + FeedListWidget + + + RSS feeds + Nyhetsmatinger + + + + Unread + Ulest + + + + GUI + + Open Torrent Files + Åpne torrentfiler + + + Torrent Files + Torrentfiler + + + Transfers + Overføringer + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Nedlastingshastighet: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Opplastingshastighet: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 er ferdig nedlastet. + + + I/O Error + i.e: Input/Output Error + Lese/Skrive feil + + + Search + Søk + + + Options were saved successfully. + Innstillingene ble lagret. + + + + GeoIP + + France + Frankrike + + + + HeadlessLoader + + + Information + Informasjon + + + + To control qBittorrent, access the Web UI at http://localhost:%1 + For å kontrollere qBittorrent, få tilgang til nettbrukergrensesnittet hos http://localhost:%1 + + + + The Web UI administrator user name is: %1 + Nettbrukergrensesnittets administrator-brukernavn er: %1 + + + + The Web UI administrator password is still the default one: %1 + Nettbrukergrensesnittets administrator-passord er fremdeles standardpassordet: %1 + + + + This is a security risk, please consider changing your password from program preferences. + Dette er en sikkerhetsrisiko, vennligst vurder å forandre passordet ditt fra programinnstillingene. + + + + HttpConnection + + + Your IP address has been banned after too many failed authentication attempts. + IP adressen din har blitt bannet etter for mange mislykkede autentiseringsforøk. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + N: %1/s - Ov: %2 + + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + O: %1/s - Ov: %2 + + + + HttpServer + + + File + Fil + + + + Edit + Rediger + + + + Help + Hjelp + + + + Download Torrents from their URL or Magnet link + Last ned Torrenter fra deres nettadresse eller Magnetlenke + + + + Only one link per line + Kun en lenke per linje + + + + Download local torrent + Last ned lokal torrent + + + + Torrent files were correctly added to download list. + Torrentfilene ble korrekt lagt til nedlastingslisten. + + + + Point to torrent file + Pek på torrentfilen + + + + Download + Last ned + + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Er du sikker på at du vil slette de valgte torrentene fra overføringslisten og harddisken? + + + + Download rate limit must be greater than 0 or disabled. + Nedlastingsforholdsgrense må være større enn 0 eller deaktivert. + + + + Upload rate limit must be greater than 0 or disabled. + Opplastingsforholdsgrense må være større enn 0 eller deaktivert. + + + + Maximum number of connections limit must be greater than 0 or disabled. + Grensen for maksimalt antall tilkoblinger må være større enn 0 eller deaktivert. + + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Grensen for maksimalt antall tilkoblinger per torrent må være større enn 0 eller deaktivert. + + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Grensen for maksimalt antall opplastingsåpninger per torrent må være større enn 0 eller deaktivert. + + + + Unable to save program preferences, qBittorrent is probably unreachable. + Ikke i stand til å lagre programinnstillinger, qBittorrent er sannsynligvis uoppnåelig. + + + + Language + Språk + + + + Downloaded + Is the file downloaded or not? + Nedlastet + + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Porten som brukes for innkommende tilkoblinger må være større enn 1024 og mindre enn 65535. + + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Porten som brukes for nettbrukergrensesnittet må være større enn 1024 og mindre enn 65535. + + + + The Web UI username must be at least 3 characters long. + Nettbrukergrensesnittets brukernavn må være minst 3 tegn langt. + + + + The Web UI password must be at least 3 characters long. + Nettbrukergrensesnittets passord må være minst 3 tegn langt. + + + + Save + Lagre + + + + qBittorrent client is not reachable + qBittorrent er ikke oppnåelig + + + + HTTP Server + HTTP Tjener + + + + The following parameters are supported: + Følgende parametre er støttet: + + + + Torrent path + Torrentsti + + + + Torrent name + Torrentnavn + + + + LegalNotice + + + Legal Notice + Juridisk Notat + + + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent er et fildelingsprogram. Når du kjører en torrent, vil dens data bli gjordt tilgjengelig for andre gjennom opplasting. Innhold som du deler er ene og alene ditt ansvar. + +Ingen flere notiser vil bli gitt. + + + + Press %1 key to accept and continue... + Trykk %1 tasten for å akseptere og fortsette... + + + + Legal notice + Juridisk notat + + + + Cancel + Avbryt + + + + I Agree + Jeg er enig + + + + LineEdit + + + Clear the text + Fjern teksten + + + + MainWindow + + + &Edit + &Rediger + + + + &Tools + Verk&tøy + + + + &File + &Fil + + + + &Help + &Hjelp + + + + &View + &Vis + + + + &Options... + &Alternativer... + + + + Torrent &creator + Torrent&oppretter + + + + Set upload limit... + Sett opplastingsgrense... + + + + Set download limit... + Sett nedlastingsgrense... + + + + &About + &Om + + + + &Pause + Sett på &pause + + + + &Delete + &Slett + + + + P&ause All + Sett &Alle på Pause + + + + &Resume + &Gjenoppta + + + + &Add torrent file... + Legg til &torrentfil... + + + + + Exit + Avslutt + + + + R&esume All + Gjenoppta &Alle + + + + Visit &Website + Besøk &Nettside + + + + Auto-Shutdown on downloads completion + Slå av automatisk ved nedlastingsfullførelse + + + + Add &link to torrent... + Legg til &lenke til torrent... + + + + Report a &bug + Rapporter en &feil + + + + &Documentation + &Dokumentasjon + + + + Set global download limit... + Sett global nedlastingsgrense... + + + + Set global upload limit... + Sett global opplastingsgrense... + + + + + Alternative speed limits + Alternative hastighetsgrenser + + + + &RSS reader + &Nyhetsmatingsleser (RSS) + + + + Search &engine + &Søkemotor + + + + Exit qBittorrent + Avslutt qBittorrent + + + + Suspend system + Sett system i hvilemodus + + + + Shutdown system + Slå av system + + + + Disabled + Deaktivert + + + + + Lock qBittorrent + Lås qBittorrent + + + + Ctrl+L + Ctrl+L + + + + Import existing torrent... + Importer eksisterende torrent... + + + + Import torrent... + Importer torrent... + + + + Donate money + Doner penger + + + + If you like qBittorrent, please donate! + Hvis du liker qBittorrent, vennligst doner! + + + + Execution &Log + &Utførelseslogg + + + + + Execution Log + Utførelseslogg + + + + Top &tool bar + &Topp-verktøylinje + + + + Display top tool bar + Vis topp-verktøylinje + + + + &Speed in title bar + &Hastighet i tittellinje + + + + Show transfer speed in title bar + Vis overføringshastighet i tittellinje + + + Preview file + Forhåndsvis filen + + + Clear log + Nullstill loggen + + + + Decrease priority + Formink prioritet + + + + Increase priority + Øk prioritet + + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + + Set the password... + Sett passordet... + + + + Transfers + Overføringer + + + + Torrent file association + Torrent-filassosiasjon + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent er ikke satt som standardapplikasjon for åpning av torrentfiler eller Magnetlenker. +Vil du assosiere qBittorrent til torrentfiler og Magnetlenker? + + + + + + UI lock password + Brukergrensesnitt låsingspassord + + + + + + Please type the UI lock password: + Vennligst skriv brukergrensesnitt låsingspassordet: + + + + The password should contain at least 3 characters + Passordet bør inneholde minst 3 tegn + + + + Password update + Passord oppdatering + + + + The UI lock password has been successfully updated + Brukergrensesnitt-låsingspassordet har blitt vellykket oppdatert + + + + RSS + Nyhetsmating (RSS) + + + + Search + Søk + + + + Transfers (%1) + Overføringer (%1) + + + + Download completion + Nedlastingsfullførelse + + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 er ferdig nedlastet. + + + + I/O Error + i.e: Input/Output Error + Inn/ut-operasjonsfeil + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + En Inn/ut-operasjonsfeil oppstod for torrent %1. + Grunn: %2 + + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + + Recursive download confirmation + Rekursiv nedlastingsbekreftelse + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrenten %1 inneholder torrentfiler, vil du fortsette med deres nedlasting? + + + + + Yes + Ja + + + + + No + Nei + + + + Never + Aldri + + + + Url download error + Nettadresse nedlastingsfeil + + + + Couldn't download file at url: %1, reason: %2. + Kunne ikke laste ned filen hos nettadresse: %1, grunn: %2. + + + + Global Upload Speed Limit + Global Opplastingshastighetsgrense + + + + Global Download Speed Limit + Global Nedlastingshastighetsgrense + + + + + Invalid password + Ugyldig passord + + + + The password is invalid + Passordet er ugyldig + + + + Exiting qBittorrent + Avslutter qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Noen filer overføres for øyeblikket. +Er du sikker på at du vil avslutte qBittorrent? + + + + Always + Alltid + + + + Open Torrent Files + Åpne Torrentfiler + + + + Torrent Files + Torrentfiler + + + + Options were saved successfully. + Alternativene ble vellykket lagret. + + + + qBittorrent + qBittorrent + + + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + NL-hastighet: %1 KiB/s + + + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + OL-hastighet: %1 KiB/s + + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Ned: %2/s, Opp: %3/s) + + + + A newer version is available + En nyere versjon er tilgjengelig + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + En nyere verjon av qBittorrent er tilgjengelig hos Sourceforge. +Vil du oppdatere qBittorrent til versjon %1? + + + + Impossible to update qBittorrent + Umulig å oppdatere qBittorrent + + + + qBittorrent failed to update, reason: %1 + qBittorrent mislyktes i å oppdateres, grunn: %1 + + + + PeerAdditionDlg + + + Invalid IP + Ugyldig IP + + + + The IP you provided is invalid. + IPen som du oppgav er ugyldig. + + + + PeerListDelegate + + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + + IP + IP + + + + Connection + Tilkobling + + + + Client + i.e.: Client application + Klient + + + + Progress + i.e: % downloaded + Fremdrift + + + + Down Speed + i.e: Download speed + Ned-hastighet + + + + Up Speed + i.e: Upload speed + Opp-hastighet + + + + Downloaded + i.e: total data downloaded + Nedlastet + + + + Uploaded + i.e: total data uploaded + Opplastet + + + + Add a new peer... + Legg til ny deltaker... + + + + Copy IP + Kopier IP + + + + Limit download rate... + Begrens nedlastingsforholdet... + + + + Limit upload rate... + Begrens opplastingsforholdet... + + + + Ban peer permanently + Bann deltaker permanent + + + + + Peer addition + Deltaker tillegging + + + + The peer was added to this torrent. + Deltakeren ble lagt til denne torrenten. + + + + The peer could not be added to this torrent. + Deltakeren kunne ikke bli lagt til denne torrenten. + + + + Are you sure? -- qBittorrent + Er du sikker? -- qBittorrent + + + + Are you sure you want to ban permanently the selected peers? + Er du sikker på at du vil banne de valgte deltakerne permanent? + + + + &Yes + &Ja + + + + &No + &Nei + + + + Manually banning peer %1... + Banner manuelt deltaker %1... + + + + Upload rate limiting + Opplastingsforholdsbegrensning + + + + Download rate limiting + Nedlastingsforholdsbegrensning + + + + Preferences + + UI + User Interface + Brukergrensesnitt + + + + Downloads + Nedlastinger + + + + Connection + Tilkobling + + + + Speed + Hastighet + + + Proxy + Mellomtjener + + + + Web UI + Web UI + + + + Advanced + Avansert + + + Language: + Språk: + + + + (Requires restart) + (Krever omstart) + + + Visual style: + Visuell stil: + + + Transfer list + Overføringsliste + + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Bruk alternerende rekkefarger + + + + + Start / Stop Torrent + Start / Stopp Torrent + + + + + No action + Ingen handling + + + File system + Filsystem + + + + Copy .torrent files to: + Kopier torrentfiler til: + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Følgende parametre er støttet: +<ul> +<li>%f: Torrentsti</li> +<li>%n: Torrentnavn</li> +</ul> + + + + Listening Port + Lytteport + + + + Connections Limits + Tilkoblingsgrenser + + + + Proxy Server + Mellomtjener + + + + Enable bandwidth management (uTP) + Aktiver båndbreddebehandling (uTP) + + + + Enable Local Peer Discovery to find more peers + Aktiver lokal deltakeroppdagelse for å finne flere deltakere + + + + Encryption mode: + Krypteringsmodus: + + + + Prefer encryption + Foretrekk kryptering + + + + Require encryption + Krev kryptering + + + + Disable encryption + Deaktiver kryptering + + + Torrent queueing + Torrentkø-danning + + + + Maximum active downloads: + Maksimalt aktive nedlastinger: + + + + Maximum active uploads: + Maksimalt aktive opplastinger: + + + + Maximum active torrents: + Maksimalt aktive torrenter: + + + + When adding a torrent + Når en torrent legges til + + + + + Behavior + Oppførsel + + + + Language + Språk + + + + Display torrent content and some options + Vis torrentinnhold og noen alternativer + + + Listening port + Lytteport + + + + Port used for incoming connections: + Port brukt for innkommende tilkoblinger: + + + + Random + Tilfeldig + + + Connections limit + Tilkoblingsgrense + + + + Global maximum number of connections: + Globalt maksimalt antall tilkoblinger: + + + + Maximum number of connections per torrent: + Maksimalt antall tilkoblinger per torrent: + + + + Maximum number of upload slots per torrent: + Maksimalt antall opplastingsåpninger per torrent: + + + + + Upload: + Opplasting: + + + + + Download: + Nedlasting: + + + + + + + KiB/s + KiB/s + + + Global speed limits + Globale hastighetsgrenser + + + + Remove folder + Fjern mappe + + + Alternative global speed limits + Alternative globale hastighetsgrenser + + + + to + time1 to time2 + til + + + + Every day + Hver dag + + + + Week days + Ukedager + + + + Week ends + Helger + + + + DHT port: + DHT port: + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Utveksle deltakere med kompatible Bittorrent klienter (µTorrent, Vuze, ...) + + + + Host: + Vert: + + + + SOCKS4 + SOCKS4 + + + + Type: + Type: + + + + + Options + Alternativer + + + User Interface + Brukergrensesnitt + + + Visual Appearance + Visuelt utseende + + + + Action on double-click + Handling ved dobbelklikk + + + + Downloading torrents: + Nedlastende torrenter: + + + + + Open destination folder + Åpne destinasjonsmappe + + + + Completed torrents: + Fullførte torrenter: + + + + Desktop + Skrivebord + + + + Show splash screen on start up + Vis velkomstskjerm ved oppstart + + + + Start qBittorrent minimized + Start qBittorrent minimert + + + Show qBittorrent icon in notification area + Vis qBittorrent ikon i varslingsområdet + + + Use monochrome system tray icon (requires restart) + Bruk monokromt systemkurvikon (krever omstart) + + + + Minimize qBittorrent to notification area + Minimer qBittorrent til varslingsområdet + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Steng qBittorrent til varslingsområdet + + + + Ask for program exit confirmation + Spør etter programavsluttningsbekreftelse + + + + User Interface Language: + Brukergrensesnittsspråk: + + + + Transfer List + Overføringsliste + + + + Show qBittorrent in notification area + Vis qBittorrent i varslingsområdet + + + + Tray icon style: + Systemkurvikon-stil: + + + + Normal + Normal + + + + Monochrome (Dark theme) + Monokromt (Mørkt tema) + + + + Monochrome (Light theme) + Monokromt (Lyst tema) + + + + Power Management + Strømstyring + + + + Inhibit system sleep when torrents are active + Hindre systemhvile når torrenter er aktive + + + + Do not start the download automatically + The torrent will be added to download list in pause state + Ikke start nedlastingen automatisk + + + + Hard Disk + Harddisk + + + + Save files to location: + Lagre filer til plassering: + + + + Append the label of the torrent to the save path + Tilføy torrentens etikett til lagringsstien + + + + Pre-allocate disk space for all files + Forhåndstildel diskplass for alle filer + + + + Keep incomplete torrents in: + Oppbevar ikke-fullførte torrenter i: + + + Append .!qB extension to incomplete files' names + Tilføy .!qB benevnelse til navn på ikke-fullførte filer + + + + Automatically add torrents from: + Legg automatisk til torrenter fra: + + + + Add folder... + Legg til mappe... + + + + Email notification upon download completion + Epost-varsling ved nedlastingsfullførelse + + + + Destination email: + Destinasjons-epost: + + + + SMTP server: + SMTP tjener: + + + + This server requires a secure connection (SSL) + Denne tjeneren krever en sikker tilkobling (SSL) + + + + Run an external program on torrent completion + Kjør et eksternt program ved torrentfullførelse + + + + Otherwise, the proxy server is only used for tracker connections + Ellers så er mellomtjeneren kun brukt for sporertilkoblinger + + + + Use proxy for peer connections + Bruk mellomtjener for deltakertilkoblinger + + + + Global Rate Limits + Globale Forholdsgrenser + + + + Apply rate limit to uTP connections + Bruk forholdsgrense for uTP tilkoblinger + + + + Apply rate limit to transport overhead + Bruk forholdsgrense for transportering av tilleggsdata + + + + Alternative Global Rate Limits + Alternative Globale Forholdsgrenser + + + + Schedule the use of alternative rate limits + Planlegg bruken av alternative forholdsgrenser + + + + Use HTTPS instead of HTTP + Bruk HTTPS istedenfor HTTP + + + + Import SSL Certificate + Importer SSL Sertifikat + + + + Import SSL Key + Importer SSL Nøkkel + + + + Certificate: + Sertifikat: + + + + Key: + Nøkkel: + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Informasjon om sertifikater</a> + + + + Update my dynamic domain name + Oppdater mitt dynamiske domenenavn + + + + Service: + Tjeneste: + + + + Register + Registrer + + + + Domain name: + Domenenavn: + + + Use %f to pass the torrent path in parameters + Bruk %f for å overføre torrentstien i parametre + + + + Use UPnP / NAT-PMP port forwarding from my router + Bruk UPnP / NAT-PMP port-videresending fra min ruter + + + Proxy server + Mellomtjener + + + + IP Filtering + IP Filtrering + + + + Reload the filter + Last inn filteret på nytt + + + Schedule the use of alternative speed limits + Planlegg bruken av alternative hastighetsgrenser + + + + from + from (time1 to time2) + fra + + + + When: + Når: + + + + Privacy + Personvern + + + + Enable DHT (decentralized network) to find more peers + Aktiver DHT (desentralisert nettverk) for å finne flere deltakere + + + + Use a different port for DHT and BitTorrent + Bruk en annen port for DHT og BitTorrent + + + + Enable Peer Exchange (PeX) to find more peers + Aktiver utveksling av deltakere (PeX) for å finne flere deltakere + + + + Look for peers on your local network + Se etter deltakere i ditt lokale nettverk + + + Share ratio limiting + Delingsforholdsbegrensning + + + + Seed torrents until their ratio reaches + Vær giver for torrenter til forholdet deres når + + + + then + deretter + + + + Pause them + Sett dem på pause + + + + Remove them + Fjern dem + + + + Use UPnP / NAT-PMP to forward the port from my router + Bruk UPnP / NAT-PMP for å videresende porten fra min ruter + + + + Bypass authentication for localhost + Omgå autentisering for lokalvert + + + + (None) + (Ingen) + + + + BitTorrent + BitTorrent + + + + HTTP + HTTP + + + + + Port: + Port: + + + + + + Authentication + Autentisering + + + + Append .!qB extension to incomplete files + Tilføy .!qB benevnelse til ikke-fullførte filer + + + + + + + Username: + Brukernavn: + + + + + + + Password: + Passord: + + + + Torrent Queueing + Torrentkø-danning + + + + Share Ratio Limiting + Delingsforholdsbegrensning + + + + Enable Web User Interface (Remote control) + Aktiver Nettbrukergrenesnitt (Web UI) *Fjernkontroll* + + + + SOCKS5 + SOCKS5 + + + + Filter path (.dat, .p2p, .p2b): + Filtersti (.dat, .p2p, .p2b): + + + HTTP Server + HTTP Tjener + + + + PreviewSelect + + + Name + Navn + + + + Size + Størrelse + + + + Progress + Fremdrift + + + + + + Preview impossible + Forhåndsvisning er ikke mulig + + + + + + Sorry, we can't preview this file + Beklager, vi kan ikke forhåndsvise denne filen + + + + PropListDelegate + + + Not downloaded + Ikke nedlastet + + + + + Normal + Normal (priority) + Normal + + + + + High + High (priority) + Høy + + + + Mixed + Mixed (priorities + Blandet + + + + + Maximum + Maximum (priority) + Maksimal + + + + PropTabBar + + + General + Generelt + + + + Trackers + Sporere + + + + Peers + Deltakere + + + + HTTP Sources + HTTP Kilder + + + + Content + Innhold + + + + PropertiesWidget + + + Save path: + Lagringssti: + + + + Torrent hash: + Torrent-verifiseringsnøkkel: + + + + Comment: + Kommentar: + + + + Share ratio: + Delingsforhold: + + + + + Downloaded: + Nedlastet: + + + + Availability: + Tilgjengelighet: + + + + Transfer + Overføring + + + + Uploaded: + Opplastet: + + + + Wasted: + Ødslet: + + + + UP limit: + Opp grense: + + + + DL limit: + Ned grense: + + + + Connections: + Tilkoblinger: + + + + Time active: + Time (duration) the torrent is active (not paused) + Aktivitetstid: + + + + Reannounce in: + Annonser på nytt om: + + + + Information + Informasjon + + + + Created on: + Opprettet: + + + + Pieces size: + Delstørrelser: + + + + Torrent content: + Torrentinnhold: + + + + Select All + Velg Alle + + + + Select None + Velg Ingen + + + + Normal + Normal + + + + High + Høy + + + + Maximum + Maksimal + + + + + Do not download + Ikke last ned + + + + + this session + Denne sesjonen + + + + %1 max + e.g. 10 max + %1 maks + + + + + /s + /second (i.e. per second) + /s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Gitt ut i %1 + + + + + I/O Error + Inn/ut-operasjonsfeil + + + + This file does not exist yet. + Denne filen eksisterer ikke ennå. + + + + This folder does not exist yet. + Denne mappen eksisterer ikke ennå. + + + + Rename... + Omdøp... + + + + Priority + Prioritet + + + + Rename the file + Omdøp filen + + + + New name: + Nytt navn: + + + + + The file could not be renamed + Filen kunne ikke omdøpes + + + + This file name contains forbidden characters, please choose a different one. + Dette filnavnet inneholder forbudte tegn, vennligst velg et annet et. + + + + + This name is already in use in this folder. Please use a different name. + Dette navnet er allerede i bruk i denne mappen. Vennligst velg et annet navn. + + + + The folder could not be renamed + Mappen kunne ikke omdøpes + + + + New url seed + New HTTP source + Ny nettadressegivning + + + + New url seed: + Ny nettadressegivning: + + + + qBittorrent + qBittorrent + + + + This url seed is already in the list. + Denne nettadressegivningen er allerede i listen. + + + + + Choose save path + Velg en lagringssti + + + Save path creation error + Feil ved oprettelsen av filsti + + + Could not create the save path + Kunne ikke opprette nedlastingsfilstien + + + + QBtSession + + + + %1 reached the maximum ratio you set. + %1 nådde det maksimale forholdet du satte. + + + + Removing torrent %1... + Fjerner torrent %1... + + + + Pausing torrent %1... + Setter torrenten på pause %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent er bundet til port: TCP/%1 + + + + HTTP user agent is %1 + HTTP brukeragent er %1 + + + + Reporting IP address %1 to trackers... + Rapporterer IP adresse %1 til sporere... + + + + DHT support [ON], port: UDP/%1 + DHT støtte [PÅ], port: UDP/%1 + + + + + DHT support [OFF] + DHT støtte [AV] + + + + PeX support [ON] + PeX støtte [PÅ] + + + + PeX support [OFF] + PeX støtte [AV] + + + + Restart is required to toggle PeX support + Omstart kreves for å omkoble PeX støtte + + + + Local Peer Discovery support [OFF] + Lokal deltaker-oppdagelsesstøtte [AV] + + + + Encryption support [ON] + Krypteringsstøtte [PÅ] + + + + Encryption support [FORCED] + Krypteringsstøtte [TVUNGET] + + + + Encryption support [OFF] + Krypteringsstøtte [AV] + + + + Embedded Tracker [ON] + Innebygd Sporer [PÅ] + + + + Failed to start the embedded tracker! + Start av den innebygde sporeren mislyktes! + + + + Embedded Tracker [OFF] + Innebygd Sporer [AV] + + + + The Web UI is listening on port %1 + Nettbrukergrensesnittet lytter på port %1 + + + + Web User Interface Error - Unable to bind Web UI to port %1 + Nettbrukergrenesnitt feil. Ikke i stand til å binde nettbrukergrensesnitt til port %1 + + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' ble fjernet fra overføringslisten og harddisk. + + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' ble fjernet fra overføringslisten. + + + + '%1' is not a valid magnet URI. + '%1' er ikke en gyldig magnet URI. + + + + + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' finnes allerede i nedlastingslisten. + + + + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' ble gjenopptatt (hurtig gjenopptaking) + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Maskinen vil nå gå i hvilemodus dersom du ikke avbryter innen de neste 15 sekundene... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Maskinen vil nå bli slått av dersom du ikke avbryter innen de neste 15 sekundene... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent vil nå avsluttes dersom du ikke avbryter innen de neste 15 sekundene... + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Det oppgitte IP filteret ble vellykket analysert: %1 regler ble lagt til. + + + + Error: Failed to parse the provided IP filter. + Feil: Mislyktes i å analysere det oppgitte IP filteret. + + + + + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' lagt til i nedlastingslisten. + + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP støtte [PÅ] + + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP støtte [AV] + + + + Local Peer Discovery support [ON] + Lokal deltaker-oppdagelsesstøtte [PÅ] + + + + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Ikke i stand til å dekode torrentfilen: '%1' + + + + This file is either corrupted or this isn't a torrent. + Denne filen er enten ødelagt, eller så er ikke dette en torrent. + + + + Error: The torrent %1 does not contain any file. + Feil: Torrenten %1 inneholder ingen filer. + + + + Note: new trackers were added to the existing torrent. + Notat: nye sporere ble lagt til den eksisterende torrenten. + + + + Note: new URL seeds were added to the existing torrent. + Notat: nye nettadressegivninger ble lagt til den eksisterende torrenten. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>ble blokkert pga. IP filteret ditt</i> + + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>ble bannet pga. ødelagte deler</i> + + + + The network interface defined is invalid: %1 + Det definerte nettverksgrensesnittet er ugyldig: %1 + + + + Trying any other network interface available instead. + Prøver hvilket som helst annet nettverksgrensesnitt som er tilgjengelig isteden. + + + + Listening on IP address %1 on network interface %2... + Lytter på IP adresse %1 på nettverksgrensesnitt %2... + + + + Failed to listen on network interface %1 + Mislyktes i å lytte på nettverksgrensesnitt %1 + + + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekursiv nedlasting av fil %1 innebygd i torrent %2 + + + + + Unable to decode %1 torrent file. + Ikke i stand til å dekode %1 torrentfil. + + + + Torrent name: %1 + Torrentnavn: %1 + + + + Torrent size: %1 + Torrentstørrelse: %1 + + + + Save path: %1 + Lagringssti: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrenten ble lastet ned på %1. + + + + Thank you for using qBittorrent. + Takk for at du bruker qBittorrent. + + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 har gjordt seg ferdig med å laste ned + + + + An I/O error occured, '%1' paused. + En inn/ut-operasjonsfeil oppstod, '%1' satt på pause. + + + + + Reason: %1 + Grunn: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port-viderekoblingssvikt, melding: %1 + + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port-viderekobling vellykket, melding: %1 + + + + File sizes mismatch for torrent %1, pausing it. + Filstørrelser feilmatching for torrent %1, setter den på pause. + + + + Fast resume data was rejected for torrent %1, checking again... + Hurtig gjennopptakingsdata ble avslått for torrent %1, sjekker igjen... + + + + Url seed lookup failed for url: %1, message: %2 + Nettadressegivningsoppsøking mislyktes for nettadresse: %1, melding: %2 + + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Laster ned '%1', vennligst vent... + + + + RSS + + + Search + Søk + + + + New subscription + Nytt abonnement + + + + + + Mark items read + Marker ting som er lest + + + + Update all + Oppdater alle + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrenter:</span> <span style=" font-style:italic;">(dobbelklikk for å laste ned)</span></p></body></html> + + + Article title + Artikkeltittel + + + + + Update all feeds + Oppdater alle matinger + + + + + Delete + Slett + + + + RSS Downloader... + Nyhetsmatingsnedlaster... + + + + Settings... + Innstillinger... + + + Feed URL + Matingsnettadresse + + + + Rename... + Omdøp... + + + + Rename + Omdøp + + + + + Update + Oppdater + + + + New subscription... + Nytt abonnement... + + + + Download torrent + Last ned torrent + + + + Open news URL + Åpne nyhetsnettadresse + + + + Copy feed URL + Kopier matingsnettadresse + + + + New folder... + Ny mappe... + + + + Manage cookies... + Behandle cookies... + + + + Refresh RSS streams + Oppdater nyhetsmatingsdataflyt + + + + RSSImp + + + Please type a rss stream url + Vennligst skriv en nyhetsmating-dataflytsnettadresse + + + + Stream URL: + Dataflytsnettadresse: + + + + + Are you sure? -- qBittorrent + Er du sikker? -- qBittorrent + + + + + &Yes + &Ja + + + + + &No + &Nei + + + + Please choose a folder name + Vennligst velg et mappenavn + + + + Folder name: + Mappenavn: + + + + New folder + Ny mappe + + + + Overwrite attempt + Overskrivingsforsøk + + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Du kan ikke overskrive %1 gjenstanden. + + + + qBittorrent + qBittorrent + + + + This rss feed is already in the list. + Denne nyhetsmatingen er allerede på listen. + + + + Are you sure you want to delete these elements from the list? + Er du sikker på at du vil slette disse elementene fra listen? + + + + Are you sure you want to delete this element from the list? + Er du sikker på at du vil slette dette elementet fra listen? + + + + Please choose a new name for this RSS feed + Vennligst velg et nytt navn for denne nyhetsmatingen + + + + New feed name: + Nytt matingsnavn: + + + + Name already in use + Navn allerede i bruk + + + + This name is already used by another item, please choose another one. + Dette navnet brukes allerede av en annen gjenstand, vennligst velg et annet et. + + + + Date: + Dato: + + + + Author: + Opphavsperson: + + + + Unread + Ulest + + + + RssArticle + + No description available + Ingen beskrivelse tilgjengelig + + + + RssFeed + + + Automatically downloading %1 torrent from %2 RSS feed... + Laster automatisk ned %1 torrent fra %2 nyhetsmating... + + + + RssSettingsDlg + + + RSS Reader Settings + Innstillinger for Nyhetsmatingsleser + + + + RSS feeds refresh interval: + Oppdateringsintervall for nyhetsmating: + + + + minutes + minutter + + + + Maximum number of articles per feed: + Maksimalt antall artikler per mating: + + + + ScanFoldersModel + + + Watched Folder + Overvåket Mappe + + + + Download here + Last ned her + + + + SearchCategories + + + All categories + Alle kategorier + + + + Movies + Filmer + + + + TV shows + TV-forestillinger + + + + Music + Musikk + + + + Games + Spill + + + + Anime + Anime + + + + Software + Programvare + + + + Pictures + Bilder + + + + Books + Bøker + + + + SearchEngine + + + Empty search pattern + Tom søkestreng + + + + Please type a search pattern first + Vennligst skriv en søkestreng først + + + + + Results + Resultater + + + + Searching... + Søker... + + + + Cut + Klipp ut + + + + Copy + Kopier + + + + Paste + Lim inn + + + + Clear field + Tøm felt + + + + Clear completion history + Fjern fullførelseshistorie + + + + Confirmation + Bekreftelse + + + + Are you sure you want to clear the history? + Er du sikker på at du vil fjerne historien? + + + + + + Search + Søk + + + + Missing Python Interpreter + Manglende Python tolk + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x er påkrevd for å bruke søkemotoren, men det ser ikke ut til å være installert. +Vil du installere det nå? + + + + Search Engine + Søkemotor + + + + + Search has finished + Søket er ferdig + + + + An error occured during search... + Det oppstod en feil under søket... + + + + + Search aborted + Søk avbrutt + + + + Download error + Nedlastingsfeil + + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Python oppsettet kunne ikke lastes ned, grunn: %1. +Vennligst installer det manuelt. + + + + Search returned no results + Søket ga ingen resultater + + + + Results + i.e: Search results + Resultater + + + + + Unknown + Ukjent + + + + SearchTab + + + Name + i.e: file name + Navn + + + + Size + i.e: file size + Størrelse + + + + Seeders + i.e: Number of full sources + Givere + + + + Leechers + i.e: Number of partial sources + Sankere + + + + Search engine + Søkemotor + + + + ShutdownConfirmDlg + + + Shutdown confirmation + Avslåingsbekreftelse + + + + SpeedLimitDialog + + + KiB/s + KiB/s + + + + StatusBar + + + + Connection status: + Tilkoblingsstatus: + + + + + No direct connections. This may indicate network configuration problems. + Ingen direkte tilkoblinger. Dette kan indikere problemer med nettverkskonfigurasjonen. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + N: %1 B/s - Ov: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + O: %1 B/s - Ov: %2 + + + + + DHT: %1 nodes + DHT: %1 noder + + + + qBittorrent needs to be restarted + qBittorrent trenger å bli omstartet + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent ble nettopp oppdatert og trenger å bli omstartet for at forandringene skal tre i kraft. + + + + + Connection Status: + Tilkoblingsstatus: + + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Frakoblet. Dette betyr vanligvis at qBittorrent mislyktes i å lytte på den valgte porten for innkommende tilkoblinger. + + + + Online + Tilkoblet + + + + + %1/s + Per second + %1/s + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + N: %1/s - Ov: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + O: %1/s - Ov: %2 + + + + Click to switch to alternative speed limits + Klikk for å bytte til alternative hastighetsgrenser + + + + Click to switch to regular speed limits + Klikk for å bytte til regulære hastighetsgrenser + + + Click to disable alternative speed limits + Klikk for å deaktivere alternative hastighetsgrenser + + + Click to enable alternative speed limits + Klikk for å aktivere alternative hastighetsgrenser + + + + Global Download Speed Limit + Global Nedlastingshastighetsgrense + + + + Global Upload Speed Limit + Global Opplastingshastighetsgrense + + + + TorrentCreatorDlg + + + Select a folder to add to the torrent + Velg en mappe som skal legges til torrenten + + + + Select a file to add to the torrent + Velg en fil som skal legges til torrenten + + + + No input path set + Ingen sti for inndata er satt + + + + Please type an input path first + Vennligst skriv en sti for inndata først + + + + Select destination torrent file + Velg torrent-destinasjonsfil + + + + Torrent Files + Torrentfiler + + + + + + Torrent creation + Torrentopprettelse + + + + Torrent creation was unsuccessful, reason: %1 + Torrentopprettelse mislyktes, grunn: %1 + + + + Created torrent file is invalid. It won't be added to download list. + Den opprettede torrentfilen er ugyldig. Den vil ikke bli lagt til nedlastingslisten. + + + + Torrent was created successfully: + Torrenten ble vellykket opprettet: + + + + TorrentFilesModel + + + Name + Navn + + + + Size + Størrelse + + + + Progress + Fremdrift + + + + Priority + Prioritet + + + + TorrentImportDlg + + + Torrent Import + Torrent Importering + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Denne assistenten vil hjelpe deg med å dele med qBittorrent en torrent som du allerede har lastet ned. + + + + Torrent file to import: + Torrentfil til å importere: + + + + + ... + ... + + + + Content location: + Innholdsplassering: + + + + Skip the data checking stage and start seeding immediately + Hopp over steget med datasjekking og start givning umiddelbart + + + + Import + Importer + + + + Torrent file to import + Torrentfil til å importere + + + + Torrent files (*.torrent) + Torrentfiler (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 Filer + + + + Please provide the location of %1 + %1 is a file name + Vennligst oppgi plasseringen til %1 + + + + Please point to the location of the torrent: %1 + Vennligst pek til plasseringen av torrenten: %1 + + + + Invalid torrent file + Ugyldig torrentfil + + + + This is not a valid torrent file. + Dette er ikke en gyldig torrentfil. + + + + TorrentModel + + + Name + i.e: torrent name + Navn + + + + Size + i.e: torrent size + Størrelse + + + + Done + % Done + Ferdig + + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + + Seeds + i.e. full sources (often untranslated) + Givninger + + + + Peers + i.e. partial sources (often untranslated) + Deltakere + + + + Down Speed + i.e: Download speed + Ned-hastighet + + + + Up Speed + i.e: Upload speed + Opp-hastighet + + + + Ratio + Share ratio + Forhold + + + + ETA + i.e: Estimated Time of Arrival / Time left + Gjenværende tid + + + + Label + Etikett + + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Lagt til + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Fullført + + + + Tracker + Sporer + + + + Down Limit + i.e: Download limit + Ned-grense + + + + Up Limit + i.e: Upload limit + Opp-grense + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Nedlastet mengde + + + + Amount left + Amount of data left to download (e.g. in MB) + Gjenstående mengde + + + + Time Active + Time (duration) the torrent is active (not paused) + Aktivitetstid + + + + TrackerList + + + URL + Nettadresse + + + + Status + Status + + + + Peers + Deltakere + + + + Message + Melding + + + + [DHT] + [DHT] + + + + [PeX] + [PeX] + + + + [LSD] + [LSD] + + + + + + + + Working + Virker + + + + + + Disabled + Deaktivert + + + + This torrent is private + Denne torrenten er privat + + + + Updating... + Oppdaterer... + + + + + Not working + Virker ikke + + + + + Not contacted yet + Ikke kontaktet ennå + + + + Add a new tracker... + Legg til en ny sporer... + + + + Remove tracker + Fjern sporer + + + + Force reannounce + Tving annonsering på nytt + + + + TrackersAdditionDlg + + + Trackers addition dialog + Sporere tilleggingsdialog + + + + List of trackers to add (one per line): + Liste over sporere som skal legges til (en per linje): + + + + µTorrent compatible list URL: + Nettadresse for µTorrent-kompatibel liste: + + + + I/O Error + Inn/ut-operasjonsfeil + + + + Error while trying to open the downloaded file. + Feil ved åpningsforsøk av den nedlastede filen. + + + + No change + Ingen forandring + + + + No additional trackers were found. + Ingen flere sporere ble funnet. + + + + Download error + Nedlastingsfeil + + + + The trackers list could not be downloaded, reason: %1 + Listen over sporere kunne ikke lastes ned, grunn: %1 + + + + TransferListDelegate + + + Downloading + Laster ned + + + + Paused + Satt på pause + + + + Queued + i.e. torrent is queued + Satt i kø + + + + Seeding + Torrent is complete and in upload-only mode + Gir ut + + + + Stalled + Torrent is waiting for download to begin + Laster ikke ned + + + + Checking + Torrent local data is being checked + Sjekker + + + + /s + /second (.i.e per second) + /s + + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + + Seeded for %1 + e.g. Seeded for 3m10s + Gitt ut i %1 + + + + TransferListFiltersWidget + + + + All + Alle + + + + + Downloading + Laster ned + + + + + Completed + Fullført + + + + + Paused + Satt på pause + + + + + Active + Aktiv + + + + + Inactive + Inaktiv + + + + + All labels + Alle etiketter + + + + + Unlabeled + Ingen etikett + + + + Remove label + Fjern etikett + + + + Add label... + Legg til etikett... + + + + Resume torrents + Gjenoppta torrenter + + + + Pause torrents + Sett torrenter på pause + + + + Delete torrents + Slett torrenter + + + + New Label + Ny Etikett + + + + Label: + Etikett: + + + + Invalid label name + Ugyldig etikettnavn + + + + Please don't use any special characters in the label name. + Vennligst ikke bruk noen spesielle tegn i etikettnavnet. + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + Gjenværende tid + + + + Column visibility + Kolonne synlighet + + + Name + i.e: torrent name + Navn + + + Size + i.e: torrent size + Størrelse + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + + Label + Etikett + + + + Choose save path + Velg lagringssti + + + Save path creation error + Feil ved oprettelsen av filsti + + + Could not create the save path + Kunne ikke opprette nedlastingsfilstien + + + + Torrent Download Speed Limiting + Torrent-nedlastingshastighetsbegrensning + + + + Torrent Upload Speed Limiting + Torrent-opplastingshastighetsbegrensning + + + + New Label + Ny Etikett + + + + Label: + Etikett: + + + + Invalid label name + Ugyldig etikettnavn + + + + Please don't use any special characters in the label name. + Vennligst ikke bruk noen spesielle tegn i etikettnavnet. + + + + Rename + Omdøp + + + + New name: + Nytt navn: + + + + Resume + Resume/start the torrent + Gjenoppta + + + + Pause + Pause the torrent + Sett på pause + + + + Delete + Delete the torrent + Slett + + + + Preview file... + Forhåndsvis fil... + + + + Limit share ratio... + Begrens delingsforholdet... + + + + Limit upload rate... + Begrens opplastingsforholdet... + + + + Limit download rate... + Begrens nedlastingsforholdet... + + + + Open destination folder + Åpne destinasjonsmappe + + + + Move up + i.e. move up in the queue + Flytt opp + + + + Move down + i.e. Move down in the queue + Flytt ned + + + + Move to top + i.e. Move to top of the queue + Flytt til topp + + + + Move to bottom + i.e. Move to bottom of the queue + Flytt til bunn + + + + Set location... + Sett plassering... + + + + Priority + Prioritet + + + + Force recheck + Tving sjekking på nytt + + + + Copy magnet link + Kopier magnetlenke + + + + Super seeding mode + Supergivningsmodus + + + + Rename... + Omdøp... + + + + Download in sequential order + Last ned i sekvensiell rekkefølge + + + + Download first and last piece first + Last ned første og siste del først + + + + New... + New label... + Ny... + + + + Reset + Reset label + Tilbakestill + + + + UpDownRatioDlg + + + Torrent Upload/Download Ratio Limiting + Torrent-Opplasting/Nedlasting Forholdsbegrensning + + + + Use global ratio limit + Bruk global forholdsgrense + + + + + + buttonGroup + knappeGruppe + + + + Set no ratio limit + Sett ingen forholdsgrense + + + + Set ratio limit to + Sett forholdsgrensen til + + + + UsageDisplay + + + Usage: + Bruk: + + + + displays program version + viser programversjon + + + + disable splash screen + deaktiver velkomstskjerm + + + + displays this help message + viser denne hjelpemeldingen + + + + changes the webui port (current: %1) + forandrer nettbrukergrensesnittporten (nåværende: %1) + + + + [files or urls]: downloads the torrents passed by the user (optional) + [filer eller nettadresser]: laster ned torrentene som er godkjent av brukeren (valgfritt) + + + + about + + + qBittorrent + qBittorrent + + + + I would like to thank the following people who volunteered to translate qBittorrent: + Jeg ønsker å takke følgende personer, som frivillig har oversatt qBittorrent: + + + + Please contact me if you would like to translate qBittorrent into your own language. + Vennligst kontakt meg dersom du ønsker å oversette qBittorrent til ditt eget språk. + + + + addPeerDialog + + + Peer addition + Deltaker tillegging + + + + IP + IP + + + + Port + Port + + + + addTorrentDialog + + + Torrent addition dialog + Torrent tilleggingsdialog + + + + Save path: + Lagringssti: + + + + ... + ... + + + + Torrent size: + Torrent størrelse: + + + + + Unknown + Ukjent + + + + Free disk space: + Ledig diskplass: + + + + Label: + Etikett: + + + + Torrent content: + Torrentinnhold: + + + + Select All + Velg Alle + + + + Select None + Velg Ingen + + + + Download in sequential order (slower but good for previewing) + Last ned i sekvensiell rekkefølge (tregere, men bra for forhåndsvisning) + + + + Skip file checking and start seeding immediately + Hopp over filsjekking og start givning umiddelbart + + + + Normal + Normal + + + + High + Høy + + + + Maximum + Maksimal + + + + + Do not download + Ikke last ned + + + + Add to download list in paused state + Legg til nedlastingslisten i pausetilstand + + + + Add + Legg til + + + + Cancel + Avbryt + + + + authentication + + + + Tracker authentication + Sporerautentisering + + + + Tracker: + Sporer: + + + + Login + Innlogging + + + + Username: + Brukernavn: + + + + Password: + Passord: + + + + Log in + Logg inn + + + + Cancel + Avbryt + + + + confirmDeletionDlg + + + Deletion confirmation - qBittorrent + Slettingsbekreftelse - qBittorrent + + + + Are you sure you want to delete the selected torrents from the transfer list? + Er du sikker på at du vil slette de valgte torrentene fra overføringslisten? + + + + Remember choice + Husk valg + + + + Also delete the files on the hard disk + Slett også filene på harddisken + + + + createTorrentDialog + + + Cancel + Avbryt + + + + Torrent Creation Tool + Torrentopprettelsesverktøy + + + + Torrent file creation + Torrentfilopprettelse + + + + Add file + Legg til fil + + + + Add folder + Legg til mappe + + + + File or folder to add to the torrent: + Fil eller mappe som skal legges til torrenten: + + + + Tracker URLs: + Sporer-nettadresser: + + + + Web seeds urls: + Nettgiver-nettadresser: + + + + Comment: + Kommentar: + + + + Piece size: + Delstørrelse: + + + + 32 KiB + 32 KiB + + + + 64 KiB + 64 KiB + + + + 128 KiB + 128 KiB + + + + 256 KiB + 256 KiB + + + + 512 KiB + 512 KiB + + + + 1 MiB + 1 MiB + + + + 2 MiB + 2 MiB + + + + 4 MiB + 4 MiB + + + + Auto + Auto + + + + Private (won't be distributed on DHT network if enabled) + Privat (vil ikke bli forstyrret på DHT nettverk hvis aktivert) + + + + Start seeding after creation + Start givning etter opprettelse + + + + Create and save... + Opprett og lagre... + + + + Progress: + Fremdrift: + + + + createtorrent + + Select destination torrent file + Velg torrent-målfil + + + Torrent Files + Torrentfiler + + + No input path set + Ingen filsti for inndata er valgt + + + Please type an input path first + Velg en filsti for inndata først + + + Torrent creation + Torrentfilen blir opprettet + + + Torrent was created successfully: + Vellykket opprettelse av torrentfil: + + + + downloadFromURL + + Download Torrents from URLs + Last ned torrenter fra nettadresser + + + Only one URL per line + Kun en nettadresse per linje + + + + Add torrent links + Legg til torrentlenker + + + + Both HTTP and Magnet links are supported + Både HTTP og Magnetlenker er støttet + + + + Download + Last ned + + + + Cancel + Avbryt + + + + Download from urls + Last ned fra nettadresser + + + + No URL entered + Ingen nettadresse oppgitt + + + + Please type at least one URL. + Vennligst skriv minst en nettadresse. + + + + downloadThread + + I/O Error + Inn/ut-operasjonsfeil + + + The remote host name was not found (invalid hostname) + Det eksterne vertsnavnet ble ikke funnet (ugyldig vertsnavn) + + + The operation was canceled + Operasjonen ble avbrutt + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Den eksterne tjeneren stengte tilkoblingen for tidlig, før hele svaret ble mottatt og bearbeidet + + + The connection to the remote server timed out + Tilkoblingen til den eksterne tjeneren endte i tidsavbrudd + + + SSL/TLS handshake failed + SSL/TLS håndtrykk mislyktes + + + The remote server refused the connection + Den eksterne tjeneren nektet tilkoblingen + + + The connection to the proxy server was refused + Tilkoblingen til mellomtjeneren ble nektet + + + The proxy server closed the connection prematurely + Mellomtjeneren stengte tilkoblingen for tidlig + + + The proxy host name was not found + Mellomtjenerens vertsnavn ble ikke funnet + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Tilkoblingen til mellomtjeneren endte i tidsavbrudd, eller mellomtjeneren svarte ikke i tide på forespørselen som ble sendt + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Mellomtjeneren krever autentisering for å kunne hedre forespørselen, men godtok ikke noen av attestene som ble tilbudt + + + The access to the remote content was denied (401) + Tilgangen til det eksterne innholdet ble nektet (401) + + + The operation requested on the remote content is not permitted + Operasjonen som blir forespurt på det eksterne innholdet er ikke tillatt + + + The remote content was not found at the server (404) + Det eksterne innholdet ble ikke funnet på tjeneren (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Den eksterne tjeneren krever autentisering for å kunne servere innholdet, men attestene som ble oppgitt ble ikke akseptert + + + The Network Access API cannot honor the request because the protocol is not known + Nettverktilgangens applikasjons-programeringsgrensesnitt kan ikke hedre forespørselen fordi protokollen er ukjent + + + The requested operation is invalid for this protocol + Den forespurte operasjonen er ugyldig for denne protokollen + + + An unknown network-related error was detected + En ukjent nettverksrelatert feil ble oppdaget + + + An unknown proxy-related error was detected + En ukjent mellomtjenerrelatert feil ble oppdaget + + + An unknown error related to the remote content was detected + En ukjent feil relatert til det eksterne innholdet ble oppdaget + + + A breakdown in protocol was detected + En driftstans i protokollen ble oppdaget + + + Unknown error + Ukjent feil + + + + engineSelect + + + Search plugins + Søk programtillegg + + + + Installed search engines: + Installerte søkemotorer: + + + + Name + Navn + + + + Url + Nettadresse + + + + + Enabled + Aktivert + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Du kan skaffe nye søkemotor-programtillegg her: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + Install a new one + Installer en ny + + + + Check for updates + Søk etter oppdateringer + + + + Close + Steng + + + Disable + Deaktiver + + + + Uninstall + Avinstaller + + + + engineSelectDlg + + + Uninstall warning + Avinstalleringsadvarsel + + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Noen programtillegg kunne ikke avinstalleres fordi de er inkludert i qBittorrent. +Kun de som du la til selv kan avinstalleres. +Disse programtilleggene ble derimot deaktivert. + + + + Uninstall success + Avinstallering vellykket + + + + Select search plugins + Velg søke-programtillegg + + + + qBittorrent search plugins + qBittorrent søke-programtillegg + + + + + + + + Search plugin install + Søk programtillegg installering + + + + + + Yes + Ja + + + + + + + No + Nei + + + + + + + + + + + + qBittorrent + qBittorrent + + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + En nyere versjon av %1 søkemotor-programtillegget er allerede installert. + + + + + + + Search plugin update + Søk programtillegg oppdatering + + + + + Sorry, update server is temporarily unavailable. + Beklager, oppdateringstjener er midlertidig utilgjengelig. + + + + All your plugins are already up to date. + Alle dine programtillegg er allerede oppdatert. + + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 søkemotor-programtillegg kunne ikke oppdateres, beholder gammel versjon. + + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 søkemotor-programtillegg kunne ikke installeres. + + + + All selected plugins were uninstalled successfully + Alle valgte programtillegg ble vellykket avinstallert + + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 søkemotor-programtillegg ble vellykket oppdatert. + + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1 søkemotor-programtillegg ble vellykket installert. + + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Beklager, %1 søke-programtilleggs installering var mislykket. + + + + New search engine plugin URL + Ny søkemotor-programtilleggs nettadresse + + + + URL: + Nettadresse: + + + + misc + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent vil nå slå av maskinen fordi alle nedlastinger er fullførte. + + + + B + bytes + B + + + + KiB + kibibytes (1024 bytes) + KiB + + + + MiB + mebibytes (1024 kibibytes) + MiB + + + + GiB + gibibytes (1024 mibibytes) + GiB + + + + TiB + tebibytes (1024 gibibytes) + TiB + + + + %1h %2m + e.g: 3hours 5minutes + %1t %2m + + + + %1d %2h + e.g: 2days 10hours + %1d %2t + + + + + + + + + Unknown + Ukjent + + + + Unknown + Unknown (size) + Ukjent + + + + < 1m + < 1 minute + < 1m + + + + %1m + e.g: 10minutes + %1m + + + + options_imp + + + + + + Choose a save directory + Velg en lagringskatalog + + + + Add directory to scan + Legg til katalog som skal gjennomsøkes + + + + Folder is already being watched. + Mappe er allerede overvåket. + + + + Folder does not exist. + Mappe eksisterer ikke. + + + + Folder is not readable. + Mappe er ikke lesbar. + + + + Failure + Svikt + + + + Failed to add Scan Folder '%1': %2 + Tillegging av gjennomsøkingsmappe mislyktes '%1': %2 + + + + + Choose export directory + Velg eksporteringskatalog + + + + + Choose an ip filter file + Velg en ip filter fil + + + + + Filters + Filter + + + + SSL Certificate (*.crt *.pem) + + + + + SSL Key (*.key *.pem) + + + + SSL Certificate (*.crt) + SSL Sertifikat (*.crt) + + + SSL Key (*.key) + SSL Nøkkel (*.key) + + + + Parsing error + Analyseringsfeil + + + + Failed to parse the provided IP filter + Analysering av det oppgitte IP filteret mislyktes + + + + Invalid key + Ugyldig nøkkel + + + + This is not a valid SSL key. + Dette er ikke en gyldig SSL nøkkel. + + + + Invalid certificate + Ugyldig sertifikat + + + + This is not a valid SSL certificate. + Dette er ikke et gyldig SSL sertifikat. + + + Succesfully refreshed + Oppdatert vellykket + + + + Successfully refreshed + Oppdatert vellykket + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Analysering av det oppgitte IP filteret var vellykket: %1 regler ble lagt til. + + + + pluginSourceDlg + + + Plugin source + Programtilleggskilde + + + + Search plugin source: + Søk programtilleggskilde: + + + + Local file + Lokal fil + + + + Web link + Nettlenke + + + + preview + + + Preview selection + Forhåndsvis utvalg + + + + File preview + Forhåndsvis fil + + + + The following files support previewing, <br>please select one of them: + Følgende filer støtter forhåndsvisning, <br>vennligst velg en av dem: + + + + Preview + Forhåndsvis + + + + Cancel + Avbryt + + + + previewSelect + + Preview impossible + Forhåndsvisning er ikke mulig + + + Sorry, we can't preview this file + Denne filen kan ikke forhåndsvises + + + Name + Navn + + + Size + Størrelse + + + + search_engine + + + + Search + Søk + + + + Status: + Status: + + + + Stopped + Stoppet + + + + Download + Last ned + + + + Go to description page + Gå til beskrivelsesside + + + + Search engines... + Søkemotorer... + + + + torrentAdditionDialog + + + + Unable to decode torrent file: + Ikke i stand til å dekode torrentfilen: + + + + + + Choose save path + Velg lagringssti + + + + Unable to decode magnet link: + Ikke i stand til å dekode magnetlenke: + + + + Magnet Link + Magnetlenke + + + + Rename... + Omdøp... + + + + Priority + Prioritet + + + + Rename the file + Omdøp filen + + + + New name: + Nytt navn: + + + + + The file could not be renamed + Filen kunne ikke omdøpes + + + + This file name contains forbidden characters, please choose a different one. + Dette filnavnet inneholder forbudte tegn, vennligst velg et annet et. + + + + + This name is already in use in this folder. Please use a different name. + Dette navnet er allerede i bruk i denne mappen. Vennligst bruk et annet navn. + + + + The folder could not be renamed + Mappen kunne ikke omdøpes + + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 igjen etter torrent nedlasting) + + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 mer kreves å laste ned) + + + + Empty save path + Tom lagringssti + + + + Please enter a save path + Vennligst skriv en lagringssti + + + + Save path creation error + Feil ved opprettelse av lagringssti + + + + Could not create the save path + Kunne ikke opprette lagringsstien + + + + Invalid label name + Ugyldig etikettnavn + + + + Please don't use any special characters in the label name. + Vennligst ikke bruk noen spesielle tegn i etikettnavnet. + + + + Seeding mode error + Givningsmodusfeil + + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Du valgte å hoppe over filsjekking. Lokale filer ser derimot ikke ut til å eksistere i den nåværende destinasjonsmappen. Vennligst deaktiver denne funksjonen eller oppdater lagringsstien. + + + + Invalid file selection + Ugyldig filvalg + + + + You must select at least one file in the torrent + Du må velge minst en fil i torrenten + + + diff --git a/src/lang/qbittorrent_nl.qm b/src/lang/qbittorrent_nl.qm new file mode 100644 index 0000000000000000000000000000000000000000..7dc9e067e79352ddb02b242a8c65f054c926cd04 GIT binary patch literal 119552 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 + + + + AboutDlg + + About qBittorrent + Over qBittorrent + + + About + Over + + + Author + Auteur + + + Name: + Naam: + + + Country: + Land: + + + E-mail: + E-mail: + + + Christophe Dumez + Christophe Dumez + + + France + Frankrijk + + + Translation + Vertaling + + + License + Licentie + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + chris@qbittorrent.org + + + + Thanks to + Met dank aan + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Een Bittorrent client geprogrammeerd in C++, gebaseerd op Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">en libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent op Freenode</span></p></body></html> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Een geavanceerde Bittorrent client geprogrammeerd in C++, gebaseerd op Qt4 toolkit en libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent op Freenode</span></p></body></html> + + + + AdvancedSettings + + Property + Eigenschap + + + Value + Waarde + + + Ignore transfer limits on local network + Negeer overdrachtlimieten op het locale netwerk + + + Include TCP/IP overhead in transfer limits + Includeer TCP/IP overheid in de overdrachtlimieten + + + Disk write cache size + Disk write cache grootte + + + MiB + MiB + + + Outgoing ports (Min) [0: Disabled] + Uitgaande poorten (Min) [0: Uitgeschakeld] + + + Outgoing ports (Max) [0: Disabled] + UItgaande poorten (Max) [0: Uitgeschakeld] + + + Recheck torrents on completion + Hercontroleer torrents bij voltooiing + + + Transfer list refresh interval + Overdrachtenlijst vernieuwinterval + + + ms + milliseconds + ms + + + Resolve peer countries (GeoIP) + Ontbind peer landen (GeoIP) + + + Resolve peer host names + Ontbind peer hostnamen + + + Maximum number of half-open connections [0: Disabled] + Maximum aantal van half-open verbindingen [0 Uitgeschakeld] + + + Strict super seeding + Stricte super seeding + + + Network Interface (requires restart) + Netwerkinterface (vereist herstart) + + + Any interface + i.e. Any network interface + Gelijk welke interface + + + Display program notification balloons + Toon programma notificatie ballonnen + + + Enable embedded tracker + Activeer embedded tracker + + + Embedded tracker port + Embedded trackerpoort + + + Check for software updates + Controleer op software updates + + + Use system icon theme + Gebruik systeem iconen thema + + + Confirm torrent deletion + Bevestig verwijder torrent + + + IP Address to report to trackers (requires restart) + IP-adres om te melden aan trackers (vereist herstart) + + + Display program on-screen notifications + Toon programma on-screen meldingen + + + Setting + Instelling + + + Value + Value set for this setting + Waarde + + + Exchange trackers with other peers + + + + + AutomatedRssDownloader + + Automated RSS Downloader + Automatische RSS Downloader + + + Enable the automated RSS downloader + Activeer de automatische RSS downloader + + + Download rules + Downloadregels + + + Rule definition + Regeldefinitie + + + Must contain: + Moet bevatten: + + + Must not contain: + Mag niet bevatten: + + + ... + ... + + + Assign label: + Ken label toe: + + + Apply rule to feeds: + Pas regel toe op feeds: + + + Matching RSS articles + Overeenkomstige RSS artikels + + + Save to a different directory + Opslaan in een andere map + + + Save to: + Opslaan in: + + + Import... + Importeer... + + + Export... + Exporteer... + + + New rule name + Nieuwe regel naam + + + Please type the name of the new download rule. + Type de naam van de nieuwe downloadregel. + + + Rule name conflict + Regelnaam conflict + + + A rule with this name already exists, please choose another name. + Een regel met deze naam bestaat reeds, kies een andere naam. + + + Are you sure you want to remove the download rule named %1? + Bent u zeker dat u de downloadregel met naam %1 wilt verwijderen? + + + Are you sure you want to remove the selected download rules? + Bent u zeker dat u de geselecteerde downloadregel wilt verwijderen? + + + Rule deletion confirmation + Regelverwijdering bevestiging + + + Destination directory + Bestemmingsmap + + + Invalid action + Ongeldige actie + + + The list is empty, there is nothing to export. + De lijst is leeg, er is niets om te importeren. + + + Where would you like to save the list? + Waar wilt u de lijst opslaan? + + + Rules list (*.rssrules) + Ruleslijst (*.rssrules) + + + I/O Error + I/O Fout + + + Failed to create the destination file + Mislukt om het bestemmingsbestand te maken + + + Please point to the RSS download rules file + Gelieve te verwijzen naar het RSS download regelsbestand + + + Rules list (*.rssrules *.filters) + Regelslijst (*.rssrules *.filters) + + + Import Error + Import Fout + + + Failed to import the selected rules file + Mislukt om de geselecteerd regelslijst te importeren + + + Add new rule... + Voeg een nieuwe regel toe... + + + Delete rule + Verwijder regel + + + Rename rule... + Hernoem regel... + + + Delete selected rules + Verwijder geselecteerd regels + + + Rule renaming + Regelhernoeming + + + Please type the new rule name + Gelieve de nieuwe regelnaam te geven + + + Use regular expressions + Gebruike reguliere expressies + + + Regex mode: use Perl-like regular expressions + Regex modues: gebruik reguliere expressies die gelijkaardig zijn aa Perl + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Wildcard modus: u kan gebruikem maken van <ul><li>? om één enkel teken voor te stellen</li><li>* om nul of meerdere tekens voor te stellen<li><li>Witruimtes tellen als AND operatoren<li><lu> + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Wildcard modus: u kan gebruikem maken van <ul><li>? om één enkel teken voor te stellen</li><li>* om nul of meerdere tekens voor te stellen<li><li>| wordt gebruikt als als OR operator<li><lu> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 heeft de maximum ingestelde verhouding bereikt. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent is verbonden met poort: TCP/%1 + + + UPnP support [ON] + UPnP ondersteuning [AAN] + + + UPnP support [OFF] + UPnP ondersteuning [UIT] + + + NAT-PMP support [ON] + NAT-PMP ondersteuning [AAN] + + + NAT-PMP support [OFF] + NAT-PMP ondersteuning [UIT] + + + DHT support [ON], port: UDP/%1 + DHT ondersteuning [AAN], poort: UDP/%1 + + + DHT support [OFF] + DHT ondersteuning [UIT] + + + PeX support [ON] + PeX ondersteuning [AAN] + + + Local Peer Discovery [ON] + Local Peer Discovery [AAN] + + + Local Peer Discovery support [OFF] + Local Peer Discovery ondersteuning [UIT] + + + Encryption support [ON] + Encryptie ondersteuning [AAN] + + + Encryption support [FORCED] + Encryptie ondersteuning [GEFORCEERD] + + + Encryption support [OFF] + Encryptie ondersteuning [UIT] + + + '%1' is not a valid magnet URI. + '%1' is geen juiste magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' staat al in de downloadlijst. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' hervat. (snelle hervatting) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' toegevoegd aan de downloadlijst. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Torrentbestand kan niet worden gedecodeerd: '%1' + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>is geblokkeerd door de IP filter</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>is verbannen door onjuiste stukjes</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Recursieve download van bestand %1 in torrent %2 + + + Unable to decode %1 torrent file. + Kon torrentbestand %1 niet decoderen. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port mapping fout, bericht: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port mapping succesvol, bericht: %1 + + + Url seed lookup failed for url: %1, message: %2 + Url seed raadpleging mislukt voor url: %1, bericht: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Bezig met downloaden van '%1', even geduld alstublieft... + + + PeX support [OFF] + PeX ondersteuning [UIT] + + + + ConsoleDlg + + General + Algemeen + + + Blocked IPs + Geblokkeerde IP's + + + qBittorrent log viewer + qBittorrent log viewer + + + + CookiesDlg + + Cookies management + Cookiesbeheer + + + Key + As in Key/Value pair + Sleutel + + + Value + As in Key/Value pair + Waarde + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Algemene sleutel voor cookies zijn : '%1', '%2'. +U zou informatie moeten krijgen van u Webbrowser voorkeuren. + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + U dynamisch DNS werd succesvol geüpdate. + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Dynamische DNS error: De service is tijdelijk onbeschikbaar, er wordt opnieuw geprobeerd binnen 30 minuten. + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Dynamische DNS error: opgegeven hostname bestaat niet bij de opgegeven account. + + + Dynamic DNS error: Invalid username/password. + Dynamische DNS error: Ongeldige gebruikersnaam/wachtwoord. + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Dynamische DNS error: qBittorrent werd geblacklist door deze service, gelieve de bug te rapporteren op http://bugs.qbittorent.org. + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Dynamische DNS error: %1 werd teruggegeven door de service, gelieve de bug te rapporteren op http://bugs.qbittorrent.org. + + + Dynamic DNS error: Your username was blocked due to abuse. + Dynamische DNS error: U gebruikersnaam werd geblokkeerd door misbruik. + + + Dynamic DNS error: supplied domain name is invalid. + Dynamische DNS error: opgegeven domeinnaam is ongeldig. + + + Dynamic DNS error: supplied username is too short. + Dynamische DNS error: opgegegeven gebruikersnaam is te kort. + + + Dynamic DNS error: supplied password is too short. + Dynamische DNS error: opgegegeven wachtwoord is te kort. + + + + DownloadThread + + I/O Error + I/O Fout + + + The remote host name was not found (invalid hostname) + De remote hostnaam werd niet gevonden (ongeldige hostnaam) + + + The operation was canceled + De operatie werd geannuleerd + + + The remote server closed the connection prematurely, before the entire reply was received and processed + De remote server sloot de verbinding permanent, voor de gehele reactie werd ontvangen en verwerkt + + + The connection to the remote server timed out + De verbinding naar de remote server timede out + + + SSL/TLS handshake failed + SSL/T|S handshake mislukt + + + The remote server refused the connection + De remote server weigerde de verbinding + + + The connection to the proxy server was refused + De verbinding naar de proxy server werd geweigerd + + + The proxy server closed the connection prematurely + De proxy server sloot de verbinding permanent + + + The proxy host name was not found + De proxy host name werd niet gevonden + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + De verbinding naar de proxy timede out of the proxy reageerde niet op tijd op het verzonden verzoek + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + De proxy vereist authenticatie om in te kunnen gaan op het verzoek maar accepteerde geen van de aangeboden credentials + + + The access to the remote content was denied (401) + De toegang tot de remote content werd genegeerd (401) + + + The operation requested on the remote content is not permitted + De gevraagde operatie op de remote content is niet toegestaan + + + The remote content was not found at the server (404) + De remote content werd niet gevonden op de server (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + De remote server vereist authenticatie om de inhoud te presenteren maar de gegeven credentials werden niet geaccepteerd + + + The Network Access API cannot honor the request because the protocol is not known + De Network Access API kon niet ingaan op het verzoek want het protocol is niet bekend + + + The requested operation is invalid for this protocol + De verzochte operatie is niet geldig voor dit protocol + + + An unknown network-related error was detected + Een onbekende netwerkgerelateerde fout werd gevonden + + + An unknown proxy-related error was detected + Een onbekende proxy-gerelateerde fout werd gevonden + + + An unknown error related to the remote content was detected + Een onbekende error gerelateerd tot de remote content werd gevonden + + + A breakdown in protocol was detected + Een storing in het protocol werd gedetecteerd + + + Unknown error + Onbekende fout + + + + EventManager + + %1/s + e.g. 120 KiB/s + %1/s + + + Working + Bezig + + + Updating... + Updating... + + + Not working + Niet bezig + + + Not contacted yet + Nog niet gecontacteerd + + + this session + Deze sessie + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Geseed voor %1 + + + %1 max + e.g. 10 max + %1 max + + + + ExecutionLog + + Form + Formulier + + + General + Algemeen + + + Blocked IPs + Geblokkeerde IP's + + + + FeedDownloader + + RSS Feed downloader + RSS Feed downloader + + + RSS feed: + RSS feed: + + + Feed name + Feed naam + + + Automatically download torrents from this feed + Automatisch torrents downloaden van deze feed + + + Download filters + Download filters + + + Filters: + Filters: + + + Filter settings + Filterinstellingen + + + Matches: + Resultaten: + + + Does not match: + Komt niet overeen: + + + Destination folder: + Doelmap: + + + ... + ... + + + Filter testing + Filter testen + + + Torrent title: + Torrent titel: + + + Result: + Resultaat: + + + Test + Test + + + Import... + Importeer... + + + Export... + Exporteer... + + + Rename filter + Hernoem filter + + + Remove filter + Verwijder filter + + + Add filter + Voeg filter toe + + + + FeedDownloaderDlg + + New filter + Nieuwe filter + + + Please choose a name for this filter + Kies alstublieft een naam voor de filter + + + Filter name: + Filternaam: + + + Invalid filter name + Onjuiste filternaam + + + The filter name cannot be left empty. + De filternaam kan niet leeg blijven. + + + This filter name is already in use. + Deze filternaam is al gebruikt. + + + Filter testing error + Filtertest fout + + + Please specify a test torrent name. + Specificeer een testtorrentnaam. + + + matches + resultaten + + + does not match + komt niet overeen + + + Select file to import + Selecteer bestand om te importeren + + + Filters Files + Filtert bestanden + + + Import successful + Importeren gelukt + + + Filters import was successful. + Filters importeren gelukt. + + + Import failure + Fout tijdens importeren + + + Filters could not be imported due to an I/O error. + Filters konden niet worden geïmporteerd door een I/O fout. + + + Select destination file + Selecteer doelbestand + + + Export successful + Exporteren gelukt + + + Filters export was successful. + Filters exporteren gelukt. + + + Export failure + Fout tijdens exporteren + + + Filters could not be exported due to an I/O error. + Filters konden niet worden geëxporteerd door een I/O fout. + + + Choose save path + Kies opslag pad + + + + FeedList + + Unread + Ongelezen + + + + FeedListWidget + + RSS feeds + RSS feeds + + + Unread + Ongelezen + + + + GUI + + qBittorrent + qBittorrent + + + Open Torrent Files + Open Torrent bestanden + + + Torrent Files + Torrent bestanden + + + Transfers + Overdrachten + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + DL snelheid: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + UP snelheid: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 is klaar met downloaden. + + + I/O Error + i.e: Input/Output Error + I/O Fout + + + Search + Zoeken + + + RSS + RSS + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Een I/O fout trad op voor torrent %1. Reden: %2 + + + Url download error + Url download fout + + + Couldn't download file at url: %1, reason: %2. + Kon bestand niet downloaden vanaf url: %1, reden: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Options were saved successfully. + Opties zijn succesvol opgeslagen. + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Yes + Ja + + + No + Nee + + + Never + Nooit + + + A newer version is available + Er is een nieuwere versie beschikbaar + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Er is een nieuwere versie van qBittorrent beschikbaar op Sourceforge. +Wil u qBittorrent updaten naar versie %1? + + + Impossible to update qBittorrent + Onmogelijk om qBittorrent up te daten + + + qBittorrent failed to update, reason: %1 + qBittorrent slaagde er niet in om up te daten, reason: %1 + + + + GeoIP + + Australia + Australië + + + Argentina + Argentinië + + + Austria + Oostenrijk + + + United Arab Emirates + Verenigde Arabische Emiraten + + + Brazil + Brazilië + + + Bulgaria + Bulgarije + + + Belarus + Wit-Rusland + + + Belgium + België + + + Bosnia + Bosnië + + + Canada + Canada + + + Czech Republic + Tsjechische Republiek + + + China + China + + + Costa Rica + Costa Rica + + + Switzerland + Zwitserland + + + Germany + Duitsland + + + Denmark + Denemarken + + + Algeria + Algerije + + + Spain + Spanje + + + Egypt + Egypte + + + Finland + Finland + + + France + Frankrijk + + + United Kingdom + Verenigd Koninkrijk + + + Greece + Griekenland + + + Georgia + Georgië + + + Hungary + Hongarije + + + Croatia + Kroatië + + + Italy + Italië + + + India + India + + + Israel + Israël + + + Ireland + Ierland + + + Iceland + Ijsland + + + Indonesia + Indonesië + + + Japan + Japan + + + South Korea + Zuid-Korea + + + Luxembourg + Luxemburg + + + Mexico + Mexico + + + Netherlands + Nederland + + + Norway + Noorwegen + + + New Zealand + Nieuw-Zeeland + + + Portugal + Portugal + + + Poland + Polen + + + Pakistan + Pakistan + + + Russia + Rusland + + + Sweden + Zweden + + + Slovakia + Slovakije + + + Singapore + Singapore + + + Slovenia + Slovenië + + + Taiwan + Taiwan + + + Turkey + Turkije + + + Thailand + Thailand + + + USA + VSA + + + Ukraine + Oekraine + + + South Africa + Zuid-Afrika + + + Saudi Arabia + Saudi-Arabië + + + + HeadlessLoader + + Information + Informatie + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Om qBittorrent te besturen, gebruik de Web UI op http://localhost:%1 + + + The Web UI administrator user name is: %1 + De Web UI administrator gebruikersnaam is: %1 + + + The Web UI administrator password is still the default one: %1 + Het Web UI administrator paswoord is still nog steeds het standaard: %1 + + + This is a security risk, please consider changing your password from program preferences. + Dit is een beveiligingsrisico, gelieve te overwegen om u paswoord aan te passen via programmavoorkeuren. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + U IP-adres is geband na te veel mislukte autorisatiepogingen. + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - O: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - O: %2 + + + + HttpServer + + File + Bestand + + + Edit + Bewerk + + + Help + Help + + + Delete from HD + Verwijder van HD + + + Download Torrents from their URL or Magnet link + Download Torrent van hun URL of Magnet link + + + Only one link per line + Slechts ééen link per lijn + + + Download + Download + + + Download local torrent + Download lokale torrent + + + Torrent files were correctly added to download list. + Torrentbestanden werden correct toegevoegd aan de downloadlijst. + + + Point to torrent file + Wijst naar torrentbestand + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Bent u zeker dat u de geselecteerde torrents wilt verwijderen van de overdrachtenlijst en harde schijf? + + + Download rate limit must be greater than 0 or disabled. + Downloadsnelheidslimiet moet groter zijn dan 0 of uitgeschakeld. + + + Upload rate limit must be greater than 0 or disabled. + Uploadsnelheidslimiet moet groter zijn dan 0 of uitgeschakeld. + + + Maximum number of connections limit must be greater than 0 or disabled. + Maximum aantal verbindingen limiet moet groter zijn dan 0 of uitgeschakeld. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Maximum aantal verbindingen per torrentlimiet moet groter zijn dan 0 of uitgeschakeld. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Maximum aantal uploadslots per torrent limiet moet groter zijn dan 0 of uigeschakeld. + + + Unable to save program preferences, qBittorrent is probably unreachable. + Onmogelijk om programmavoorkeuren op te slaan, qBittorrent is waarschijnlijk onbereikbaar. + + + Language + Taal + + + The port used for incoming connections must be greater than 1024 and less than 65535. + De poort gebruikt voor inkomende verbindingen moet groter zijn dan 1024 en kleiner dan 65535. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + De poort gebruikt voor de Web UI moet groter zijn dan 1024 en kleiner dan 65535. + + + The Web UI username must be at least 3 characters long. + De Web UI-gebruikersnaam moet minstens 3 characters lang zijn. + + + The Web UI password must be at least 3 characters long. + Het Web UI-paswoord moet minstens 3 characters lang zijn. + + + Downloaded + Is the file downloaded or not? + Gedownload + + + Save + Sla op + + + qBittorrent client is not reachable + qBittorrent client is niet bereikbaar + + + HTTP Server + HTTP Server + + + Torrent path + Torrent pad + + + Torrent name + Torrent naam + + + The following parameters are supported: + De volgende parameters worden ondersteund: + + + + LegalNotice + + Legal Notice + Juridische mededeling + + + Legal notice + Juridische mededeling + + + Cancel + Annuleren + + + I Agree + Ik ga akkoord + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent is een bestanddelingsprogramma. Als u een torrent gebruikt zal zijn data beschikbaar worden gesteld voor anderen door het te uploaden. Elke inhoud die je sharet is alleen jouw verantwoordelijkheid. + + + Press %1 key to accept and continue... + Druk op de %1 toets om te accepteren en verder te gaan... + + + + LineEdit + + Clear the text + Verwijder de tekst + + + + MainWindow + + &File + &Bestand + + + &Help + &Help + + + &Edit + &Bewerken + + + Preview file + Kijk vooruit op bestand + + + Clear log + Wist log + + + Decrease priority + Prioriteit verlagen + + + Increase priority + Prioriteit verhogen + + + &Tools + &Tools + + + &View + &Weergave + + + &Add File... + &Voeg Bestand toe... + + + &Options... + &Opties... + + + Add &URL... + Voeg &URL toe... + + + Torrent &creator + Torrent &creator + + + Set upload limit... + Stel uploadlimiet in... + + + Set download limit... + stel downloadlimiet in... + + + Set global download limit... + Stel globale downloadlimiet in... + + + Set global upload limit... + Stel globale uploadlimiet in... + + + &Log viewer... + &Log viewer... + + + Top &tool bar + Bovenste &werkbalk + + + Display top tool bar + Toon bovenste werkbalk + + + &Speed in title bar + &Snelheid in titelbalk + + + Show transfer speed in title bar + Toon overdrachtsnelheid in titelbar + + + Alternative speed limits + Alternative snelheidslimieten + + + &About + &Over + + + &Pause + &Pauzeer + + + &Delete + &Verwijder + + + P&ause All + P&auzeer alles + + + Visit &Website + Bezoek de &Website + + + Report a &bug + Rapporteer een &bug + + + &Documentation + &Documentatie + + + &RSS reader + &RSS reader + + + Search &engine + Zoek &machine + + + Log viewer + Log viewer + + + Lock qBittorrent + Vergrendel qBittorrent + + + Ctrl+L + Ctrl+L + + + Shutdown computer when downloads complete + Sluit de computer af wanneer de downloads voltooid zijn + + + &Resume + &Herneem + + + R&esume All + H&erneem alles + + + Shutdown qBittorrent when downloads complete + Sluit qBittorrent af wanneer de downloads voltooid zijn + + + Exit + Afsluiten + + + Import torrent... + Importeer torrent... + + + Donate money + Doneer geld + + + If you like qBittorrent, please donate! + Als u qBittorrent goed vindt, gelieve te doneren! + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + Stel paswoord in... + + + Transfers + Overdrachten + + + Torrent file association + Torrentbestand associatie + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent is niet het standaardprogramma om torrentbestanden of Magnetlinks te openen. +Wilt u qBittorrent associëren met torrentbestanden en Magnetlinks? + + + UI lock password + UI lock paswoord + + + Please type the UI lock password: + Gelieve het UI lock paswoord op te geven: + + + Password update + Paswoord update + + + The UI lock password has been successfully updated + Het UI lock paswoord is succesvol geupdated + + + RSS + RSS + + + Search + Zoeken + + + Transfers (%1) + Overdrachten (%1) + + + Download completion + Download voltooid + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 is klaar met downloaden. + + + I/O Error + i.e: Input/Output Error + I/O Fout + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Een I/O fout trad op voor torrent %1. Reden: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Recursieve donwloadbevestiging + + + The torrent %1 contains torrent files, do you want to proceed with their download? + De torrent %1 bevat torrentbestanden, wilt u verdergaan met hun download? + + + Yes + Ja + + + No + Nee + + + Never + Nooit + + + Url download error + Url download fout + + + Couldn't download file at url: %1, reason: %2. + Kon bestand niet downloaden vanaf url: %1, reden: %2. + + + Global Upload Speed Limit + Globale uploadsnelheidslimiet + + + Global Download Speed Limit + Globale downloadsnelheidslimiet + + + Invalid password + Ongeldig paswoord + + + The password is invalid + Het paswoord is ongeldig + + + Exiting qBittorrent + qBittorrent wordt afgesloten + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Sommige bestanden worden momenteel overgedragen. +Weet u zeker dat u qBittorrent wilt afsluiten? + + + Always + Altijd + + + Open Torrent Files + Open Torrent bestanden + + + Torrent Files + Torrent bestanden + + + Options were saved successfully. + Opties zijn succesvol opgeslagen. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + DL snelheid: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + UP snelheid: %1 KiB/s + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Down: %2/s, Up: %3/s) + + + A newer version is available + Er is een nieuwere versie beschikbaar + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Er is een nieuwere versie van qBittorrent beschikbaar op Sourceforge. +Wil u qBittorrent updaten naar versie %1? + + + Impossible to update qBittorrent + Onmogelijk om qBittorrent up te daten + + + qBittorrent failed to update, reason: %1 + qBittorrent slaagde er niet in om up te daten, reason: %1 + + + &Add torrent file... + &Voeg torrent bestand toe... + + + Add &link to torrent... + Voeg &link toe aan torrent... + + + Import existing torrent... + Importeer bestaande torrent... + + + Execution &Log + Uitvoerings&log + + + Execution Log + Uitvoeringslog + + + Auto-Shutdown on downloads completion + Autmatisch aflsuiten als de downloads volledig zijn + + + Exit qBittorrent + Sluit qBittorrent + + + Suspend system + Schors systeem + + + Shutdown system + Sluit het systeem af + + + Disabled + Uitgeschakeld + + + The password should contain at least 3 characters + Het wachtwoord moet minstens 3 tekens bevatten + + + + PeerAdditionDlg + + Invalid IP + Ongeldig IP + + + The IP you provided is invalid. + Het gegeven IP is ongeldig. + + + + PeerListDelegate + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + Client + + + Progress + i.e: % downloaded + Voortgang + + + Down Speed + i.e: Download speed + Down-snelheid + + + Up Speed + i.e: Upload speed + Up-snelheid + + + Downloaded + i.e: total data downloaded + Gedownload + + + Uploaded + i.e: total data uploaded + Geupload + + + Ban peer permanently + Peer permanent verbannen + + + Peer addition + Peer toevoeging + + + The peer was added to this torrent. + De peer werd toegevoegd aan de torrent. + + + The peer could not be added to this torrent. + De peer kon niet toegevoegd worden aan deze torrent. + + + Are you sure? -- qBittorrent + Weet u het zeker? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + Bent u zeker dat u de geselecteerd peer permanent wilt verbannen? + + + &Yes + &Ja + + + &No + &Nee + + + Manually banning peer %1... + Peer %1 wordt manueel verbannen... + + + Upload rate limiting + Uploadsnelheid limieteren + + + Download rate limiting + Downloadsnelheid limieteren + + + Add a new peer... + Voeg nieuwe peer toe... + + + Limit download rate... + Limieteer downloadsnelheid... + + + Limit upload rate... + Limieteer uploadsnelheid... + + + Copy IP + Kopiëer IP + + + Connection + Verbinding + + + + Preferences + + UI + User Interface + UI + + + Downloads + Downloads + + + Connection + Verbinding + + + Bittorrent + Bittorrent + + + Proxy + Proxy + + + Web UI + Web UI + + + Language: + Taal: + + + (Requires restart) + (herstart vereist) + + + Visual style: + Visuele stijl: + + + Transfer list + Overdrachtenlijst + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Gebruik alternatieve rijkleuren + + + File system + Bestandssysteem + + + Torrent queueing + Torrent wachtrij + + + Maximum active downloads: + Maximum actieve downloads: + + + Maximum active uploads: + Maximum actieve uploads: + + + Maximum active torrents: + Maximum actieve torrents: + + + When adding a torrent + Tijdens torrent toevoegen + + + Display torrent content and some options + Torrentinhoud en enkele opties weergeven + + + Listening port + Luisterpoort + + + Port used for incoming connections: + Poort voor inkomende verbindingen: + + + Random + Willekeurig + + + Enable UPnP port mapping + UPnP port mapping inschakelen + + + Enable NAT-PMP port mapping + NAT-PMP port mapping inschakelen + + + Connections limit + Verbindingslimiet + + + Global maximum number of connections: + Globale verbindingslimiet: + + + Maximum number of connections per torrent: + Verbindingslimiet per torrent: + + + Maximum number of upload slots per torrent: + Maximum aantal uploads per torrent: + + + Upload: + Upload: + + + Download: + Download: + + + KiB/s + KiB/s + + + Bittorrent features + Bittorrent features + + + Enable DHT network (decentralized) + DHT (gedecentraliseerd) netwerk inschakelen + + + Use a different port for DHT and Bittorrent + Gebruik een andere poort voor DHT en Bittorrent + + + DHT port: + DHT poort: + + + Enable Peer Exchange / PeX (requires restart) + Schakel Peer Exchange in / PeX (herstart vereist) + + + Enable Local Peer Discovery + Local Peer Discovery inschakelen + + + Enabled + Ingeschakeld + + + Forced + Geforceerd + + + Disabled + Uitgeschakeld + + + Type: + Type: + + + (None) + (Geen) + + + HTTP + HTTP + + + Port: + Poort: + + + Authentication + Authenticatie + + + Username: + Gebruikersnaam: + + + Password: + Paswoord: + + + SOCKS5 + SOCKS5 + + + HTTP Server + HTTP Server + + + Filter path (.dat, .p2p, .p2b): + Filter pad (.dat, p2p, p2b): + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP Communicaties (trackers, Web seeds, zoekmachine) + + + Host: + Host: + + + Peer Communications + Peer communicaties + + + SOCKS4 + SOCKS4 + + + Speed + Snelheid + + + Global speed limits + Globale snelheidslimieten + + + Alternative global speed limits + Alternatieve globale snelheidslimieten + + + to + time1 to time2 + tot + + + Every day + Elke dag + + + Week days + Weekdagen + + + Week ends + Weekenden + + + Advanced + Geavanceerd + + + Copy .torrent files to: + Kopieer .torrentbestanden naar: + + + Remove folder + Verwijder map + + + No action + Geen actie + + + Options + Instellingen + + + Visual Appearance + Visuele stijl + + + Action on double-click + Actie bij dubbel-klikken + + + Downloading torrents: + Download torrents: + + + Start / Stop + Start / Stop + + + Open destination folder + Open doel map + + + Completed torrents: + Voltooide torrents: + + + Desktop + Bureaublad + + + Show splash screen on start up + Toon splash screen bij het opstarten + + + Start qBittorrent minimized + Start qBittorrent geminimaliseerd + + + Show qBittorrent icon in notification area + Toon qBittorrenpictogram in notificatie ruimte + + + Minimize qBittorrent to notification area + Miminalizeer qBittorrent naar de notificatie ruimte + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Sluit qBittorrent naar de notificatie ruimte + + + Do not start the download automatically + The torrent will be added to download list in pause state + Start the download niet automatisch + + + Save files to location: + Sla bestanden op op locatie: + + + Append the label of the torrent to the save path + Voeg het label toe aan het opslag pad van de torrent + + + Pre-allocate disk space for all files + Pre-allocate schijfruimte voor alle bestanden + + + Keep incomplete torrents in: + Bewaar onvoltooide torrent in: + + + Append .!qB extension to incomplete files' names + Voeg de .!qB-extensie toe aan onvoltooide bestanden hun namen + + + Automatically add torrents from: + Voeg automatisch torrents toe van: + + + Add folder... + Voeg map toe... + + + IP Filtering + IP Filtering + + + Schedule the use of alternative speed limits + Plan het gebruik van alternatieve snelheidslimieten + + + from + from (time1 to time2) + van + + + When: + Wanneer: + + + Look for peers on your local network + Zoek naar peers in u lokaal netwerk + + + Protocol encryption: + Protocol encryptie: + + + Enable Web User Interface (Remote control) + Schakel Webuserinterface in (Remote control) + + + Share ratio limiting + Deelverhouding limieteren + + + Seed torrents until their ratio reaches + Seed torrents totdat hun verhouding bereikt is + + + then + dan + + + Pause them + Pauseer hen + + + Remove them + Verwijder hen + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Wissel peers uit met compatibele Bittorrent clients (µTorrent, Vuze, ...) + + + Email notification upon download completion + Email notificatie wanneer download voltooid + + + Destination email: + Bestemming email: + + + SMTP server: + SMTP server: + + + Run an external program on torrent completion + Voer een extern programma uit bij de voltooiing van de torrent + + + Use %f to pass the torrent path in parameters + Gebruik %f om het torrentpad door te geven in parameters + + + Proxy server + Proxy server + + + BitTorrent + BitTorrent + + + Start / Stop Torrent + Start / Stop Torrent + + + Use UPnP / NAT-PMP port forwarding from my router + Gebruik UPnP / NAT-PMP port forwarding van mijn router + + + Privacy + Privacy + + + Enable DHT (decentralized network) to find more peers + Schakel DHT (decentralized network) in om andere peers te vinden + + + Use a different port for DHT and BitTorrent + Gebruik een verschillende poort voor DHT en BitTorrent + + + Enable Peer Exchange (PeX) to find more peers + Schakel Peer Exchange (PeX) in om peers te vinden + + + Enable Local Peer Discovery to find more peers + Schakel Local Peer Discovery in om meer peers te vinden + + + Encryption mode: + Encryptiemodus: + + + Prefer encryption + Verkies encryptie + + + Require encryption + Vereis encryptie + + + Disable encryption + Schakel encryptie uit + + + User Interface + Gebruikersinterface + + + Reload the filter + Herlaad de filter + + + Behavior + Gedrag + + + Language + Taal + + + Power Management + Power Management + + + Inhibit system sleep when torrents are active + Stop systeem sleep wanneer torrent actief zijn + + + Bypass authentication for localhost + Sla authenticatie over voor localhost + + + Ask for program exit confirmation + Vraag voor programma afsluiten bevestiging + + + Use monochrome system tray icon (requires restart) + Gebruik monochrome system tray icon (vereist herstart) + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + De volgende parameters worden ondersteund: +<ul> +<li>%f: Torrent pad</li> +<li>%n: Torrent naam</li> +</ul> + + + Tray icon style: + Tray icon stijl: + + + Normal + Normaal + + + Monochrome (Dark theme) + Monochroom (Donker thema) + + + Monochrome (Light theme) + Monochroom (Licht thema) + + + This server requires a secure connection (SSL) + Deze server vereist een veilige verbinding (SSL) + + + User Interface Language: + Gebuikersinterface taal: + + + Transfer List + Overdrachtenlijst + + + Show qBittorrent in notification area + Toon qBittorrent in de notificatie ruimte + + + Hard Disk + Harde Schijf + + + Listening Port + Luisterpoort + + + Connections Limits + Connectielimieten + + + Proxy Server + Proxy Server + + + Torrent Queueing + Torrent op de wachtlijst plaatsen + + + Share Ratio Limiting + Deel ratio limietering + + + Use UPnP / NAT-PMP to forward the port from my router + Gebruik UPnP / NAT-PMP om de poort van de router te forwarden + + + Update my dynamic domain name + Update mijn dynamische domeinnaam + + + Service: + Service: + + + Register + Registreer + + + Domain name: + Domeinnaam: + + + Global Rate Limits + Globale rate limieten + + + Apply rate limit to uTP connections + Pas rate limiet toe op uTP connecties + + + Apply rate limit to transport overhead + Pas rate limiet to op transport overhead + + + Alternative Global Rate Limits + Alternatieve globale rate limieten + + + Schedule the use of alternative rate limits + Stel het gebruik van alternatieve limieten in + + + Enable bandwidth management (uTP) + Schakel bandbreedte management in (uTP) + + + Otherwise, the proxy server is only used for tracker connections + Anders, de proxy server wordt alleen gebruikt voor tracker connecties + + + Use proxy for peer connections + Gebruik proxy voor peer connecties + + + Append .!qB extension to incomplete files + Voeg .!qB extensie toe aan onvolledige bestanden + + + Use HTTPS instead of HTTP + Gebruik HTTPS in plaats van HTTP + + + Import SSL Certificate + Importeer SSL certificaat + + + Import SSL Key + Importeer SSL Key + + + Certificate: + Certificaat: + + + Key: + Key: + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Informatie over certificaten</a> + + + + PreviewSelect + + Name + Naam + + + Size + Grootte + + + Progress + Voortgang + + + Preview impossible + Vooruitkijken onmogelijk + + + Sorry, we can't preview this file + Sorry, we kunnen dit bestand niet vooruit bekijken + + + + ProgramUpdater + + Could not create the file %1 + Kon het bestand %1 niet maken + + + Failed to download the update at %1 + %1 is an URL + Mislukt om de update te downloaden van %1 + + + + PropListDelegate + + Normal + Normal (priority) + Normaal + + + High + High (priority) + Hoog + + + Maximum + Maximum (priority) + Maximum + + + Not downloaded + Niet gedownload + + + Mixed + Mixed (priorities + Meerdere + + + + PropTabBar + + General + Algemeen + + + Trackers + Trackers + + + Peers + Peers + + + URL Seeds + URL Seeds + + + Files + Bestanden + + + HTTP Sources + HTTP Bronnen + + + Content + Inhoud + + + + PropertiesWidget + + Save path: + Opslag pad: + + + Torrent hash: + Torrent hash: + + + Comment: + Opmerkingen: + + + Share ratio: + Deelratio: + + + General + Algemeen + + + Trackers + Trackers + + + Priority + Prioriteit + + + New url seed + New HTTP source + Nieuwe url seed + + + New url seed: + Nieuwe url seed: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + Deze url seed staat al in de lijst. + + + Choose save path + Kies opslag pad + + + Save path creation error + Opslag pad aanmaak fout + + + Could not create the save path + Kon het opslag pad niet aanmaken + + + Downloaded: + Gedownload: + + + Transfer + Transfer + + + Uploaded: + Geüpload: + + + Wasted: + Verspild: + + + UP limit: + UP limiet: + + + DL limit: + DL limiet: + + + Time elapsed: + Tijd verstreken: + + + Connections: + Verbindingen: + + + Information + Informatie + + + Created on: + Gecreëerd op: + + + Normal + Normaal + + + Maximum + Maximum + + + High + Hoog + + + this session + Deze sessie + + + %1 max + e.g. 10 max + %1 max + + + Availability: + Beschikbaarheid: + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Geseed voor %1 + + + Rename... + Hernoem... + + + New name: + Nieuwe naam: + + + The file could not be renamed + Het bestand kon niet hernoemd worden + + + This name is already in use in this folder. Please use a different name. + Deze naam bestaat al in deze map. Gelieve een andere naam te gebruiken. + + + The folder could not be renamed + Deze map kon niet hernoemd worden + + + Rename the file + Hernoem het bestand + + + This file name contains forbidden characters, please choose a different one. + Dit bestand bevat verboden character, gelieven een andere te kiezen. + + + I/O Error + I/O Fout + + + This file does not exist yet. + Dit bestand bestaat nog niet. + + + This folder does not exist yet. + Deze map bestaat nog niet. + + + Reannounce in: + Heraankondigen in: + + + Select All + Selecteer Alles + + + Select None + Selecteer Geen + + + Do not download + Download niet + + + Pieces size: + Delen grootte: + + + Time active: + Time (duration) the torrent is active (not paused) + Tijd actief: + + + Torrent content: + Torrent inhoud: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1 heeft de maximum ingestelde verhouding bereikt. + + + Removing torrent %1... + Verwijderen torrent %1... + + + Pausing torrent %1... + Pauzeren torrent %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent is verbonden met poort: TCP/%1 + + + UPnP support [ON] + UPnP ondersteuning [AAN] + + + UPnP support [OFF] + UPnP ondersteuning [UIT] + + + NAT-PMP support [ON] + NAT-PMP ondersteuning [AAN] + + + NAT-PMP support [OFF] + NAT-PMP ondersteuning [UIT] + + + HTTP user agent is %1 + HTTP user agent is %1 + + + Using a disk cache size of %1 MiB + Gebruikt een disk cache grootte van %1 MiB + + + DHT support [ON], port: UDP/%1 + DHT ondersteuning [AAN], poort: UDP/%1 + + + DHT support [OFF] + DHT ondersteuning [UIT] + + + PeX support [ON] + PeX ondersteuning [AAN] + + + PeX support [OFF] + PeX ondersteuning [UIT] + + + Restart is required to toggle PeX support + Herstart is vereist om Pex supporten om te wisselen + + + Local Peer Discovery [ON] + Local Peer Discovery [AAN] + + + Local Peer Discovery support [OFF] + Local Peer Discovery ondersteuning [UIT] + + + Encryption support [ON] + Encryptie ondersteuning [AAN] + + + Encryption support [FORCED] + Encryptie ondersteuning [GEFORCEERD] + + + Encryption support [OFF] + Encryptie ondersteuning [UIT] + + + Embedded Tracker [ON] + Embedded Trackker[AAN] + + + Failed to start the embedded tracker! + Mistlukt om the embedded tracker te starten! + + + Embedded Tracker [OFF] + Embedded Tracker [OFF] + + + The Web UI is listening on port %1 + De Web UI luistert naar poort %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Webgebruikersinterface fout - Niet mogelijk om Web UI te binden aan poort %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' werd verwijderd van de overdrachtenlijst en harde schijf. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' werd verwijderd van de overdrachtenlijst. + + + '%1' is not a valid magnet URI. + '%1' is geen geldige magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' staat al in de downloadlijst. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' hervat. (snelle hervatting) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' toegevoegd aan de downloadlijst. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Torrentbestand kan niet worden gedecodeerd: '%1' + + + This file is either corrupted or this isn't a torrent. + Dit bestand is ofwel corrupt of is geen torrent. + + + Error: The torrent %1 does not contain any file. + Fout: De torrent %1 bevat geen enkel bestand. + + + Note: new trackers were added to the existing torrent. + Opmerking: nieuwe trackers werden toegevoegd aan de bestaande torrent. + + + Note: new URL seeds were added to the existing torrent. + Opmerking: nieuwe URL seeds werden toegevoegd aan de bestaande torrent. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>is geblokkeerd door de IP filter</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>is verbannen door onjuiste delen</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Recursieve download van bestand %1 in torrent %2 + + + Unable to decode %1 torrent file. + Kon torrentbestand %1 niet decoderen. + + + Torrent name: %1 + Torrentnaam: %1 + + + Torrent size: %1 + Torrentgrootte %1 + + + Save path: %1 + Opslagpad: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + De torrent werd gedownload in %1. + + + Thank you for using qBittorrent. + Bedankt om qBittorrent te gebruiken. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 is klaar met downloaden + + + An I/O error occured, '%1' paused. + I/O fout gebeurd, '%1' gepauzeerd. + + + Reason: %1 + Reden: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port mapping fout, bericht: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port mapping succesvol, bericht: %1 + + + File sizes mismatch for torrent %1, pausing it. + Bestandgroottes komen niet overeen voor torrent %1, wordt gepauzeerd. + + + Fast resume data was rejected for torrent %1, checking again... + Snel hernemen van de data werd afgewezen door torrent %1, wordt opnieuw gecontroleerd... + + + Url seed lookup failed for url: %1, message: %2 + Url seed raadpleging mislukt voor url: %1, bericht: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Bezig met downloaden van '%1', even geduld alstublieft... + + + The network interface defined is invalid: %1 + De gedefiniëerde netwerkinterface is ongeldig: %1 + + + Trying any other network interface available instead. + Probeer een andere beeschikbaar netwerkinterface in de plaats. + + + Listening on IP address %1 on network interface %2... + Luisteren naar IP-adres %1 via netwerkinterface %2... + + + Failed to listen on network interface %1 + Mislukt om te luisteren naar netwerkinterface %1 + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP support [AAN] + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP support [UIT] + + + Local Peer Discovery support [ON] + Local Peer Discovery support [AAN] + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + De opgegeven IP filter werd succesvol ontleed: %1 regels werden toegepast. + + + Error: Failed to parse the provided IP filter. + Error: Mislukt om de opgegeven IP filter te ontleden. + + + Reporting IP address %1 to trackers... + Melden van IP-adres %1 aan trackers... + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + De computer zal nu in sleep modus gaan tenzij u annuleert binnen 15 seconden... + + + The computer will now be switched off unless you cancel within the next 15 seconds... + De computer zal nu afgesloten worden tenzij u annuleert binnen 15 seconden... + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent zal nu afsluiten tenzij u annuleert binnen 15 seconden... + + + + RSS + + Search + Zoeken + + + New subscription + Nieuwe subscriptie + + + Mark items read + Markeer items als gelezen + + + Update all + Update alles + + + Feed URL + Feed URL + + + Update + Updaten + + + RSS feeds + RSS feeds + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(dubbelklik om te downloaden)</span></p></body></html> + + + Update all feeds + Update alle feeds + + + Delete + Verwijderen + + + Rename + Hernoemen + + + Download torrent + Download torrent + + + Open news URL + Open nieuws URL + + + Copy feed URL + Kopieer feed URL + + + Refresh RSS streams + Vernieuw RRS streams + + + Article title + Artikeltitel + + + Rename... + Hernoemen... + + + New subscription... + Nieuw abonnement... + + + New folder... + Nieuwe map... + + + Manage cookies... + Beheer cookies... + + + Settings... + Instellingen... + + + RSS Downloader... + RSS Downloader... + + + + RSSImp + + Please type a rss stream url + Geef alstublieft een rss stream url + + + Stream URL: + Stream URL: + + + Are you sure? -- qBittorrent + Weet u het zeker? -- qBittorrent + + + &Yes + &Ja + + + &No + &Nee + + + Please choose a folder name + Kies een mapnaam + + + Folder name: + Mapnaam: + + + New folder + Nieuwe map + + + Overwrite attempt + Overschrijfpoging + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Kan %1 item niet overschrijven. + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + Deze rss feed staat al in de lijst. + + + Are you sure you want to delete these elements from the list? + Weet u zeker dat u deze elementen van de lijst wil verwijderen? + + + Are you sure you want to delete this element from the list? + Weet u zeker dat u dit element van de lijst wil verwijderen? + + + Please choose a new name for this RSS feed + Kies een nieuwe naam voor deze RSS feed + + + New feed name: + Nieuwe feed naam: + + + Name already in use + Naam al in gebruik + + + This name is already used by another item, please choose another one. + Deze naam is al gebruikt door een ander item, kies een andere naam. + + + Date: + Datum: + + + Author: + Auteur: + + + Unread + Ongelezen + + + + RssArticle + + No description available + Geen omschrijving beschikbaar + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + Download automatisch %1 torrent van %2 RSS feed... + + + + RssItem + + No description available + Geen omschrijving beschikbaar + + + + RssSettings + + RSS feeds refresh interval: + RSS feeds vernieuwingsinterval: + + + minutes + minuten + + + Maximum number of articles per feed: + Maximum aantal artikelen per feed: + + + + RssSettingsDlg + + RSS Reader Settings + RSS Reader instellingen + + + RSS feeds refresh interval: + RSS feeds vernieuwingsinterval: + + + minutes + minuten + + + Maximum number of articles per feed: + Maximum aantal artikelen per feed: + + + + ScanFoldersModel + + Watched Folder + Bekeken map + + + Download here + Download hier + + + + SearchCategories + + All categories + Alle categorieën + + + Movies + Films + + + TV shows + TV programma's + + + Music + Muziek + + + Games + Spellen + + + Anime + Anime + + + Software + Software + + + Pictures + Afbeeldingen + + + Books + Boeken + + + + SearchEngine + + Empty search pattern + Leeg zoekpatroon + + + Please type a search pattern first + Type alstublieft eerst een zoekpatroon + + + Results + Resultaten + + + Searching... + Zoeken... + + + Cut + Knippen + + + Copy + Kopiëren + + + Paste + Plakken + + + Clear field + Veld wissen + + + Clear completion history + Wis aanvulgeschiedenis + + + Search Engine + Zoekmachine + + + Search has finished + Zoeken is klaar + + + An error occured during search... + Een fout trad op tijdens zoeken... + + + Search aborted + Zoeken afgebroken + + + Search returned no results + Zoeken gaf geen resultaten + + + Results + i.e: Search results + Resultaten + + + Unknown + Onbekend + + + Search + Zoeken + + + Download error + Download fout + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Python-installatie kon niet worden gedownload, reason: %1. +Gelieve het manueel te installeren. + + + Missing Python Interpreter + Ontbrekende Python Interpreter + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x is vereist om de zoekmachine te gebruiken maar dit lijkt niet geinstalleerd. +Wilt u het nu installeren? + + + Confirmation + Bevestiging + + + Are you sure you want to clear the history? + Bent u zeker dat u de geschiedenis wilt wissen? + + + + SearchTab + + Name + i.e: file name + Naam + + + Size + i.e: file size + Grootte + + + Seeders + i.e: Number of full sources + Uploaders + + + Leechers + i.e: Number of partial sources + Downloaders + + + Search engine + Zoekmachine + + + + ShutdownConfirmDlg + + Shutdown confirmation + Afsluit bevestiging + + + + SpeedLimitDialog + + KiB/s + KiB/s + + + + StatusBar + + Connection status: + Verbindingsstatus: + + + No direct connections. This may indicate network configuration problems. + Geen directe verbindingen. Dit kan komen door netwerkconfiguratieproblemen. + + + DHT: %1 nodes + DHT: %1 nodes + + + Connection Status: + Verbindingsstatus: + + + Online + Online + + + Global Download Speed Limit + Globale downloadsnelheidslimit + + + Global Upload Speed Limit + Globale uploadsnelheidslimit + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - O: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - O: %2 + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + D: %1 B/s - O: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + U: %1 B/s - O: %2 + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Offline. Dit betekent meestal dat qBittorrent mislukte om te luisteren naar de geselecteerde poort voor inkomende verbindingen. + + + Click to disable alternative speed limits + Klik om de alternatieve snelheidslimieten uit te schakelen + + + Click to enable alternative speed limits + Klik om de alternatieve snelheidslimieten in te schakelen + + + qBittorrent needs to be restarted + qBittorrent moet opnieuw opgestart worden + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent is geüpdatet en moet opnieuw opgestart worden zodat de veranderingen doorgevoerd zijn. + + + Click to switch to alternative speed limits + Klik om om te schakelen naar alternatieve snelheidslimieten + + + Click to switch to regular speed limits + Klik om om te schakelen naar algemene snelheidslimieten + + + %1/s + Per second + %1/s + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + Selecteer een map om toe te voegen aan de torrent + + + Select a file to add to the torrent + Selecteer een bestand om toe te voegen aan de torrent + + + Please type an announce URL + Type een announce URL + + + Announce URL: + Tracker URL + Announce URL: + + + Please type a web seed url + Type een web seed url + + + Web seed URL: + Web seed URL: + + + No input path set + Geen bron pad gekozen + + + Please type an input path first + Geef alstublieft eerst een doel pad + + + Select destination torrent file + Kies torrent doelbestand + + + Torrent Files + Torrent bestanden + + + Torrent creation + Torrent maken + + + Torrent creation was unsuccessful, reason: %1 + Fout tijdens het maken van torrent, reden: %1 + + + Created torrent file is invalid. It won't be added to download list. + Gecreëerd torrentbestand is onjuist. Het wordt niet toegevoegd aan de downloadlijst. + + + Torrent was created successfully: + Torrent was succesvol gemaakt: + + + + TorrentFilesModel + + Name + Naam + + + Size + Grootte + + + Progress + Voortgang + + + Priority + Prioriteit + + + + TorrentImportDlg + + Torrent Import + Torrent Import + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Deze assistent zal u helpen om een torrent te delen met qBittorrent dat u reeds gedownload hebt. + + + Torrent file to import: + Torrentbestand om te importeren: + + + ... + ... + + + Content location: + Inhoudlocatie: + + + Skip the data checking stage and start seeding immediately + Sla het controleren van de data over en start onmiddellijk het seeden + + + Import + Importeer + + + Torrent file to import + Torrentbestand om te importeren + + + Torrent files (*.torrent) + Torrentbestanden (*.torrent) + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 bestanden + + + Please provide the location of %1 + %1 is a file name + Gelieve de locatie van %1 op te geven + + + Please point to the location of the torrent: %1 + Gelieve de locatie op te geven van de torrent: %1 + + + Invalid torrent file + Ongeldig torrentbestand + + + This is not a valid torrent file. + Dit is geen geldig torrentbestand. + + + + TorrentModel + + Name + i.e: torrent name + Naam + + + Size + i.e: torrent size + Grootte + + + Done + % Done + Gereed + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + Seeds + i.e. full sources (often untranslated) + Uploaders + + + Peers + i.e. partial sources (often untranslated) + Peers + + + Down Speed + i.e: Download speed + Down-snelheid + + + Up Speed + i.e: Upload speed + Up-snelheid + + + Ratio + Share ratio + Verhouding + + + ETA + i.e: Estimated Time of Arrival / Time left + Geschatte resterende tijd + + + Label + Label + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Toegevoegd op + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Voltooid op + + + Tracker + Tracker + + + Down Limit + i.e: Download limit + Down-limiet + + + Up Limit + i.e: Upload limit + Up-limiet + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Hoeveel gedownload + + + Amount left + Amount of data left to download (e.g. in MB) + Hoeveel over + + + Time Active + Time (duration) the torrent is active (not paused) + Tijd actief + + + + TrackerList + + URL + URL + + + Status + Status + + + Peers + Peers + + + Message + Bericht + + + [DHT] + [DHT] + + + Working + Bezig + + + Disabled + Uitgeschakeld + + + This torrent is private + Deze torrent is privé + + + Updating... + Updating... + + + Not working + Niet bezig + + + Not contacted yet + Nog niet gecontacteerd + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Add a new tracker... + Voeg een nieuwe tracker toe... + + + Remove tracker + Verwijder tracker + + + Force reannounce + Forceer heraankondiging + + + + TrackersAdditionDlg + + Trackers addition dialog + Trackers toevoegen dialoog + + + List of trackers to add (one per line): + Lijst van toe te voegen trackers (een per regel): + + + µTorrent compatible list URL: + µTorrent compatibiliteitslijst URL: + + + I/O Error + I/O Fout + + + Error while trying to open the downloaded file. + Fout tijdens het openen van het gedownloade bestand. + + + No change + Geen verandering + + + No additional trackers were found. + Geen extre trackers werden gevonden. + + + Download error + Download-fout + + + The trackers list could not be downloaded, reason: %1 + De trackerslijst kon niet worden gedownload, reden: %1 + + + + TransferListDelegate + + Downloading + Downloaden + + + Paused + Gepauzeerd + + + Queued + i.e. torrent is queued + In de wachtlijn geplaatst + + + Seeding + Torrent is complete and in upload-only mode + Seeden + + + Stalled + Torrent is waiting for download to begin + Wacht + + + Checking + Torrent local data is being checked + Wordt gecontroleerd + + + /s + /second (.i.e per second) + /s + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + Seeded for %1 + e.g. Seeded for 3m10s + Geseed voor %1 + + + + TransferListFiltersWidget + + All + Alle + + + Downloading + Downloaden + + + Completed + Voltooid + + + Active + Actief + + + Inactive + Inactief + + + All labels + Alle labels + + + Unlabeled + Ongelabeld + + + Remove label + Verwijder label + + + New Label + Nieuw label + + + Label: + Label: + + + Invalid label name + Ongeldige labelnaam + + + Please don't use any special characters in the label name. + Gelieve geen speciale characters te gebruiken in de labelnaam. + + + Paused + Gepauzeerd + + + Add label... + Voeg label toe... + + + Resume torrents + Herneem torrents + + + Pause torrents + Pauzeer torrents + + + Delete torrents + Verwijder torrents + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + Geschatte resterende tijd + + + Column visibility + Kolom zichtbaarheid + + + Open destination folder + Open doel map + + + Force recheck + Forceer hercontrole + + + Copy magnet link + Kopieer magnet link + + + Name + i.e: torrent name + Naam + + + Size + i.e: torrent size + Grootte + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + Seeds + i.e. full sources (often untranslated) + Uploaders + + + Ratio + Share ratio + Verhouding + + + Torrent Download Speed Limiting + Torrent downloadsnelheidsbeperking + + + Torrent Upload Speed Limiting + Torrent uploadsnelheidsbeperking + + + Super seeding mode + Super seeding modus + + + Download in sequential order + Download in sequentiële volgorde + + + Download first and last piece first + Download het eerste en het laatste deel eerst + + + Label + Label + + + New Label + Nieuw label + + + Label: + Label: + + + New... + New label... + Nieuw... + + + Reset + Reset label + Reset + + + Rename + Hernoemen + + + New name: + Nieuwe naam: + + + Rename... + Hernoem... + + + Invalid label name + Ongeldige labelnaam + + + Please don't use any special characters in the label name. + Gelieve geen speciale characters te gebruiken in de labelnaam. + + + Choose save path + Kies opslag pad + + + Save path creation error + Opslag pad aanmaak fout + + + Could not create the save path + Kon het opslag pad niet aanmaken + + + Set location... + Stel locatie in... + + + Preview file... + Bekijk bestand vooraf... + + + Limit upload rate... + Uploadverhoudingslimiet... + + + Limit download rate... + Downloadverhoudingslimiet... + + + Move up + i.e. move up in the queue + Verplaats omhoog + + + Move down + i.e. Move down in the queue + Verplaats omlaag + + + Move to top + i.e. Move to top of the queue + Verplaats naar de top + + + Move to bottom + i.e. Move to bottom of the queue + Verplaats naar het einde + + + Priority + Prioriteit + + + Resume + Resume/start the torrent + Herneem + + + Pause + Pause the torrent + Pauzeer + + + Delete + Delete the torrent + Verwijderen + + + Limit share ratio... + Limiet deel ratio... + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + Torrent Upload/Download Ratio limietering + + + Use global ratio limit + Gebruik globale ratio limiet + + + buttonGroup + knopGroep + + + Set no ratio limit + Zet geen ratio limiet + + + Set ratio limit to + Zet ratio limiet op + + + + UsageDisplay + + Usage: + Gebruik: + + + displays program version + Toon programmaversie + + + disable splash screen + deactiveer splash screen + + + displays this help message + toon dit helpbericht + + + changes the webui port (current: %1) + verandert de webui-poort (huidige: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [bestanden of urls]: download de torrent doorgegeven door de gebruiker (optioneel) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + Ik wil de volgende mensen graag bedanken die qBittorrent hebben vertaald: + + + Please contact me if you would like to translate qBittorrent into your own language. + Neem contact met me op als u qBittorrent naar uw eigen taal wilt vertalen. + + + + addPeerDialog + + Peer addition + Peer toevoeging + + + IP + IP + + + Port + Poort + + + + addTorrentDialog + + Torrent addition dialog + Torrent toevoegen dialoog + + + Save path: + Opslag pad: + + + ... + ... + + + Torrent size: + Torrent grootte: + + + Unknown + Onbekend + + + Free disk space: + Vrije schijfruimte: + + + Torrent content: + Torrent inhoud: + + + Download in sequential order (slower but good for previewing) + Download in sequentiële volgorde (langzamer maar goed om voorbeeld weer te geven) + + + Add to download list in paused state + Aan download lijst toevoegen in pauze stand + + + Add + Toevoegen + + + Cancel + Annuleren + + + Normal + Normaal + + + High + Hoog + + + Maximum + Maximum + + + Skip file checking and start seeding immediately + Sla het controleren van het bestand over en start onmiddellijk met het seeden + + + Label: + Label: + + + Select All + Selecteer alles + + + Select None + Selecteer geen + + + Do not download + Download niet + + + + authentication + + Tracker authentication + Tracker authenticatie + + + Tracker: + Tracker: + + + Login + Login + + + Username: + Gebruikersnaam: + + + Password: + Wachtwoord: + + + Log in + Log in + + + Cancel + Annuleren + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + Verwijderbevestiging - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + Bent u zeker dat u de geselecteerde torrents wilt verwijderen van de overdrachtenlijst? + + + Remember choice + Onthoudt de keuze + + + Also delete the files on the hard disk + Verwijder ook de bestanden op de harde schijf + + + + createTorrentDialog + + Cancel + Annuleren + + + Torrent Creation Tool + Hulpprogramma voor torrent maken + + + Torrent file creation + Torrentbestand maken + + + Announce urls (trackers): + Announce urls (trackers): + + + Comment (optional): + Commentaar (optioneel): + + + Web seeds urls (optional): + Web seeds urls (optioneel): + + + File or folder to add to the torrent: + Bestand of map om toe te voegen aan de torrent: + + + Add file + Voeg bestand toe + + + Add folder + Voeg map toe + + + Piece size: + Stukgrootte: + + + 32 KiB + 32 KiB + + + 64 KiB + 64 KiB + + + 128 KiB + 128 KiB + + + 256 KiB + 256 KiB + + + 512 KiB + 512 KiB + + + 1 MiB + 1 MiB + + + 2 MiB + 2 MiB + + + 4 MiB + 4 MiB + + + Private (won't be distributed on DHT network if enabled) + Privé (wordt niet verdeeld op het DHT netwerk indien ingeschakeld) + + + Start seeding after creation + Begin met delen na creatie + + + Create and save... + Aanmaken en opslaan... + + + Progress: + Voortgang: + + + Tracker URLs: + Tracker URLs: + + + Web seeds urls: + Web seeds urls: + + + Comment: + Opmerkingen: + + + Auto + Auto + + + + createtorrent + + Select destination torrent file + Kies torrent doelbestand + + + Torrent Files + Torrent bestanden + + + No input path set + Geen bron pad gekozen + + + Please type an input path first + Geef alstublieft eerst een doel pad + + + Torrent creation + Torrent maken + + + Torrent was created successfully: + Torrent was succesvol gemaakt: + + + Select a folder to add to the torrent + Selecteer een map om toe te voegen aan de torrent + + + Please type an announce URL + Type een announce URL + + + Torrent creation was unsuccessful, reason: %1 + Fout tijdens het maken van torrent, reden: %1 + + + Announce URL: + Tracker URL + Announce URL: + + + Please type a web seed url + Type een web seed url + + + Web seed URL: + Web seed URL: + + + Select a file to add to the torrent + Selecteer een bestand om toe te voegen aan de torrent + + + Created torrent file is invalid. It won't be added to download list. + Gecreëerd torrent bestand is onjuist. Het wordt niet toegevoegd aan de downloadlijst. + + + + downloadFromURL + + Download Torrents from URLs + Download Torrents via URLs + + + Only one URL per line + 1 url per lijn + + + Download + Download + + + Cancel + Annuleren + + + Download from urls + Download uit urls + + + No URL entered + Geen URL ingevoerd + + + Please type at least one URL. + Typ op zijn minst één URL. + + + Add torrent links + Voeg torrent links toe + + + Both HTTP and Magnet links are supported + Zowel HTTP als Magnet links worden ondersteund + + + + downloadThread + + I/O Error + I/O Fout + + + The remote host name was not found (invalid hostname) + De remote hostnaam werd niet gevonden (ongeldige hostnaam) + + + The operation was canceled + De operatie werd geannuleerd + + + The remote server closed the connection prematurely, before the entire reply was received and processed + De remote server sloot the verbinding permanent, voor the gehele reactie werd ontvangen en verwerkt + + + The connection to the remote server timed out + De verbinding naar de remote server timede out + + + SSL/TLS handshake failed + SSL/T|S handshake mislukt + + + The remote server refused the connection + De remote server weigerde de verbinding + + + The connection to the proxy server was refused + De verbinding naar de proxy server werd geweigerd + + + The proxy server closed the connection prematurely + De proxy server sloot de verbinding permanent + + + The proxy host name was not found + De proxy host name werd niet gevonden + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + De verbinding naar de proxy timede out of the proxy reageerde niet op tijd op het verzonden verzoek + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + De proxy vereist authenticatie om in te kunnen gaan op het verzoek maar accepteerde geen van de aangeboden credentials + + + The access to the remote content was denied (401) + De toegang tot de remote content werd genegeerd (401) + + + The operation requested on the remote content is not permitted + De gevraagde operatie op de remote content is niet toegestaan + + + The remote content was not found at the server (404) + De remote content werd niet gevonden op de server (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + De remote server vereist authenticatie om de inhoud te presenteren maar de gegeven credentials werden niet geaccepteerd + + + The Network Access API cannot honor the request because the protocol is not known + De Network Access API kon niet ingaan op het verzoek want het protocol is niet bekend + + + The requested operation is invalid for this protocol + De verzochte operatie is niet geldig voor dit protocol + + + An unknown network-related error was detected + Een onbekende netwerkgerelateerde fout werd gevonden + + + An unknown proxy-related error was detected + Een onbekende proxy-gerelateerde fout werd gevonden + + + An unknown error related to the remote content was detected + Een onbekende error gerelateerd tot de remote content werd gevonden + + + A breakdown in protocol was detected + Een storing in het protocol werd gedetecteerd + + + Unknown error + Onbekende fout + + + + engineSelect + + Search plugins + Zoekplugins + + + Installed search engines: + Geïnstalleerde zoekplugins: + + + Name + Naam + + + Url + Url + + + Enabled + Ingeschakeld + + + Install a new one + Installeer een nieuwe + + + Check for updates + Controleer op updates + + + Close + Sluiten + + + Enable + Inschakelen + + + Disable + Uitschakelen + + + Uninstall + Deïnstalleren + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + U kan hier nieuwe zoekmachineplugins vinden:<a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + engineSelectDlg + + Uninstall warning + Deïnstallatie waarschuwing + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Niet alle plugins konden worden gedeïnstalleerd omdat ze bij qBittorrent horen. +Alleen de door u toegevoegde plugins kunnen worden gedeïnstalleerd. +De plugins zijn uitgeschakeld. + + + Uninstall success + Deïnstallatie succesvol + + + Select search plugins + Kies zoekplugins + + + qBittorrent search plugins + qBittorrent zoekplugins + + + Search plugin install + Zoekplugins installatie + + + Yes + Ja + + + No + Nee + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Een nieuwere versie van %1 zoekmachineplugin is al geïnstalleerd. + + + Search plugin update + Zoekplugin update + + + Sorry, update server is temporarily unavailable. + Sorry, updateserver is tijdelijk niet bereikbaar. + + + All your plugins are already up to date. + Uw plugins zijn al het nieuwst. + + + All selected plugins were uninstalled successfully + Alle gekozen plugins zijn succesvol gedeïnstalleerd + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 zoekmachineplugin kon niet worden vernieuwd. Oude versie wordt behouden. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 zoekmachineplugin kon niet worden geïnstalleerd. + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 zoekmachineplugin is succesvol vernieuwd. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1 zoekmachineplugin is succesvol geïnstalleerd. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + %1 zoekplugin installatie mislukt. + + + New search engine plugin URL + Nieuwe zoekmachineplugin URL + + + URL: + URL: + + + + misc + + B + bytes + B + + + KiB + kibibytes (1024 bytes) + KiB + + + MiB + mebibytes (1024 kibibytes) + MiB + + + GiB + gibibytes (1024 mibibytes) + GiB + + + TiB + tebibytes (1024 gibibytes) + TiB + + + Unknown + Onbekend + + + Unknown + Unknown (size) + Onbekend + + + < 1m + < 1 minute + < 1m + + + %1m + e.g: 10minutes + %1m + + + %1h %2m + e.g: 3hours 5minutes + %1u %2m + + + %1d %2h + e.g: 2days 10hours + %1d %2u + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent zal de computer afsluiten, want alle downloads zijn voltooid. + + + + options_imp + + Choose a save directory + Kies een opslagmap + + + Choose an ip filter file + Kies een ip filter bestand + + + Filters + Filters + + + Choose export directory + Kies export map + + + Add directory to scan + Voeg map toe aan scannen + + + Folder is already being watched. + Map wordt reeds bekeken. + + + Folder does not exist. + Map bestaat niet. + + + Folder is not readable. + Map kan niet gelezen worden. + + + Failure + Fout + + + Failed to add Scan Folder '%1': %2 + Mislukt om scan map toe te voegen '%1': %2 + + + Parsing error + Ontledings error + + + Failed to parse the provided IP filter + Mislukt om de opgegeven IP filter te ontleden + + + Succesfully refreshed + Succesvol vernieuwd + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + De opgegeven IP filter werd succesvol ontleed: %1 regels werden toegepast. + + + Successfully refreshed + Succesvol vernieuwd + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + Invalid key + + + + This is not a valid SSL key. + + + + Invalid certificate + + + + This is not a valid SSL certificate. + + + + + pluginSourceDlg + + Plugin source + Pluginbron + + + Search plugin source: + Zoekpluginbron: + + + Local file + Lokaal bestand + + + Web link + Weblink + + + + preview + + Preview selection + Vooruitblik selectie + + + File preview + Bestand vooruitblik + + + The following files support previewing, <br>please select one of them: + De volgende bestanden ondersteunen vooruitkijken. +selecteer alstublieft een er van: + + + Preview + Vooruitblik + + + Cancel + Annuleren + + + + previewSelect + + Preview impossible + Vooruitkijken onmogelijk + + + Sorry, we can't preview this file + Sorry, we kunnen dit bestand niet vooruit bekijken + + + Name + Naam + + + Size + Grootte + + + Progress + Voortgang + + + + search_engine + + Search + Zoeken + + + Status: + Status: + + + Stopped + Gestopt + + + Download + Download + + + Search engines... + Zoekmachines... + + + Go to description page + Ga naar de beschrijvingspagina + + + + torrentAdditionDialog + + Unable to decode torrent file: + Torrentfile kan niet gedecodeerd worden: + + + Choose save path + Kies opslag pad + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 over na torrent download) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 extra is nodig om te downloaden) + + + Empty save path + Leeg opslag pad + + + Please enter a save path + Geef alstublieft een opslag pad + + + Save path creation error + Opslag pad aanmaak fout + + + Could not create the save path + Kon het opslag pad niet aanmaken + + + Invalid file selection + Ongeldige bestand selectie + + + You must select at least one file in the torrent + U moet tenminste een bestand in de torrent selecteren + + + Priority + Prioriteit + + + Seeding mode error + Seeding modus fout + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + U kiest ervoor om bestandscontrole over te slaan. Alhoewel, lokale bestanden blijken niet te bestaan in de huidige bestemmingsmap. Gelieve deze feature uit te schakelen of update het opslagpad. + + + Rename... + Hernoemen... + + + New name: + Nieuwe naam: + + + The file could not be renamed + Dit bestand kon niet hernoemd worden + + + This name is already in use in this folder. Please use a different name. + Deze naam bestaat reeds in deze map. Gelieve een andere naam te gebruiken. + + + The folder could not be renamed + Deze map kon niet hernoemd worden + + + Rename the file + Hernoem het bestand + + + Unable to decode magnet link: + + + + Magnet Link + Magnetlink + + + Invalid label name + Ongeldige labelnaam + + + Please don't use any special characters in the label name. + Gelieve geen speciale characters te gebruiken in de labelnaam. + + + This file name contains forbidden characters, please choose a different one. + Deze bestandsnaam bevat verboden character, gelieve een andere te kiezen. + + + diff --git a/src/lang/qbittorrent_pl.qm b/src/lang/qbittorrent_pl.qm new file mode 100644 index 0000000000000000000000000000000000000000..1452ecce65cb8a343031541dc657b67450c474c0 GIT binary patch literal 118078 zcmeFa34B!5**|`6lF2feB!GZ`h?gxyBnhk92+@$R1Ve~P07YCTnMpD*nTfLyg1czl zt#!k#*1FWSwr;hxN~@x+TD8`-wOZFM)}^mhTdm^n`#tAwGjk^i+V}sy|Iggd9J)_d!8V~oKhjCpDwRjE#}AHT5pFC%WlB+LLrvV5?b3|g;;T_(3a}B?hsn} zuY_3nTa0&y5QjZ3L~RYO{QEaTwDJ0p5No#zaVFNWE-bV|*WrrKFC8t!`tyW##$7@j z^N0`^?;)?+MPG^>JSQexC~{8k#JYbYuUa*(KgWHS&yiPc&+A0)TUzLkI)~tCOba0tibIy%ItEd!f&I6psek|5Ja53O4kXLQ#57l)=yI8B8 zB(y93CDw)j?=S8Xhd2F0XnPch!_WB=aQsai{y6Bp^FVRL&+Zo5vc1K+jez6vL&dt! zPXHY!#QJ=|^VEf6{nmTI2VLT*_a+GO-0#HEueJ+u)p&W;mb@X3IsZFCYswYJ?#b(1 zaqNayarKK0?_fVRJ}Wk#5)s-#^!@3&8*|%N?`u>-?HeDz#SPpvG zG)ru|4D@hPt-NZDMdFGjZv(FP#MKw)3NiB;aot(Z2yM^D#rL=4zBSY2Rcm}g+;aRR zp^aWDesTfEU%5j(a2aIAKc5v3Ry-=S@05s#zJtGS`-ylsv_fd(KM{|e83bLuDIUN1 zU7__&5zoHN#It{gYzaRro~u6y`}m4@c^;nIYrA-*8S5FiQM|J=Cd9*Mi1%&< zT~{s^@BR7`@Z(+L{XZNnwB`4Tf9>HHT5gN@Vhi|ogGbB#;cLL>A2d&LgV0Wyp^e{$ zb$)TYylPjyr|EU43vJfx+KhYe#OE`#S*wl~B6O)%fBj#CxS>~DcH)Ube0Z96=% zn0&m}V5| zm;X!a`m#faeVepRdrubHsx{i?-^>@JIJr4<`t%FA4G8o3$He z%@yMKmD)|;>K9tPQu|Q^cq)8MyK{L&hJg-q@@?6}nAmo4T~8pQ{6ZAFn<8-g`nDb%FNM9PswdRK_I-_F_V9LUXv>vHxw7xTV#q`YdkX*si2RfBKe%vtp6l|rk(BIn@8W(w{0 z^K$BS;BD!hIX6+BCeFd8$#<|o%2FqK!|G(&w1$` z(A8c$bKVH76&sgSV*5D|0?>t{38mzsULY z(MKT<56szB3wd<-@?33y(ABXIzG--XBcL9X+N@Xu(%=$9$tyh-((+ zPJDPzp&b@d*VSWlCq6n8^!Vr8{i7!d@%<-r57Mp?+S(3v_0Ln+8(+#@IJ!)T3tr7V z_$koS){ki=ZJL_`S|K&cRU9%|n*kj%j;<0yf1GFaw?#vD5?<>Uo z-rW8d?+{w`+}zF2LB3XZ=YF$s8$RDV_pF`g2=UDaa?i`bepVcnd)~N!5T};Pt2VbW z_xz8s|L=9@ek<>N=#OL7^_4f}RqOj_?q!^3%Q3lEjsGX)^}5_^i@pPSI4Ae!Rp5i$ zOLOn~W~~raD{}8?1>Y6_Irk@(fcJ#P+@CK4{<^Ai9}eyz#E<%NAAY%6h=1Lf`^2_0 zgx2`&+}~dYz5LOcxqq4!!usFN{p#CPW9 zd7glNnf&v-k-xrPh-b_4Cf|K8^v!*F<G#dWnmPx3>bo_BHq&G3WqH@#e2&oOtjG0MTz`~z-R-ql*B*J-ecmp_l}F~?eDg1$mmbf%?SfB0 zch$Ilj_a{`x6ir}a_$XvUDuI!XLCeoq4K;t&x;6g&iC`~S~Um!yD)FNw-n=CsIIpb zfW^!I~#dGB?+3w>0a_xFc@|4Cy!d9({_FY|b7tH8H+dd4iN0eyeznfO67 zY~hPNGtT`?Xltgb>-tC3weNmUb?<1%#Wy{3evS2Zj8xaFUhpiqY?sgy&wA>bAWtva z=vn#<_I+xNR{lT+5m+g8N_}brd`G5Ueh)M5zt~%>-AxySRx96S>KcmZY$0dIh;?li5_nZVg&b#09=(!23 z>kN6-CT;UPb~ET@?CqY%PXxVn>z*e&W(x7sUeB|hH-Y!-JkOp0J$mH*p66ZyoKw7> z=U;)o>Dt5d;_*2`JpCunD@(2r;&~s-60Zx?Vdn|FiDXU@zt5e|}FwXzR8W zE|`4TyF%Rk(}Jnq=O90470lkU4ti^^g4t(X34M8J!JJ~?{e)cw3r+@o zUAs>~QyuK%vwm98{Kzu+KaUg~z1K&uBO3~iSy_j5)fR*nVc++=s~}Vd{8ovA(7h)K z5%3m-+aS+ZwiU!jZGoJ9PF}U+Vg>O7fG-g(NY3qspLS)z)?0zcpZ>kz%)bNgZ@yY^ z?$|j(^PEv|-ZR@EUrsK#@Ry&09}g_JHs>PP9p5YX;iMHpo4B*!uD!5dqt7Y0`>3PA zH*XX?1ih@SIJe-5m6L>a*>?+`I(t6sg=Y%hxat6*1wJZx>)-bZ?do3^yuI#z?8^~_ zIkz@~FZV9=>^TDZWL#m%w3Fax>4hV!KtDGhP&o1*hrzy`S2%tZ@NoJSg?o>?Kxh}< zUpUi`n89T`3-`a_hv54k7uMYhdD}mxaPjmA?3#+g`ja{S3xy4oA6uprHoONon@=u0 z^lm(#v#qfCF5t7XL|uR4FKjJY1vz|2Ve8MK567HQc*HjB)3@gr26pWQe6KDHjsX5{ ze!6f|#mz#y_`|}1opJEzy235vr^5eRge&As@|D6Z6+b{6Vei5-u80Zo&TEC|oN)u} zncl(+3Mz%z=iI_=zpN5sVRPY?w*$^Ey9=+o4snaIFBksoU)!7?{ZlTS- zv#9#xQmi9ZH2=EQLaRBW=#V`y|CGy%7EcI)u16KM&VoI-CZw*%Y%eoqCZioD?dZy@SKY~5g`e@N3_h7uezE$+AJ-!Y3bbZm2 z_*_gqspzSFvHq!fMK7LrEBt}nqCXB?0Qlc1`cwZNunRvc`d|v=)I$r4KIp^eXWn1* zQD8daG7o#jDd!9E$qn9Ikq3M2XWr7Cn}zoMpL(b5kMXuY?ybN+Yu{e&t$4Cuh+ppT z&YKLnoAkVQ(Yklw_dV{dy&UxS$EV~~i;eOwdkb`Q!2#aYC$NjDyRRV*^@=yp zs0s1e8Q$RSSocfoy-XCwm z^WPir-uGkh*$qc|e_9MU*XGHqcIZ~`uh!oJeRrz&iT%L0w|&F=>`Rk`IB=r(xhW?J z@$ZkkFEnn1e=*wo!rOrB{)G3%zhNCu#Jw-S`WE6#?|a|AU^(>DBze`2Xi(Sd{_g$L znGx8(&ECHr05~J>c;EjP;&D$O@7;Mkp8u~my&u1^1afblylOXX^#1!s?BAie-p{|h z5^}bnSX>W1c3N+7&Qn|9U*1_<*mM)*)ZxWrH-bLTd!%@;@2-S@v9);O#JA!19;B{+ z`m?-h`>asca7e??$#&4AD4z1kE+Oh4E}k|3I8L5ZTt24_`fpkB?764HZ#=Dd z(QOIP>x;$9_PYvx%9F**{sMZ4ey_MG=K>*4IH&lSP1_N-d$727;tuGyPm81PmkMou zS@EV5YGH@mP~1Oq2kflx6`#B>@Ll=6;?u@se{Q|B_{{HJ1iR&n;&UzpUjF^9;`44F z19|;c@kI-tfIaz>;%%`zgtqq)#oKOpTHt@hm;a~|a(<8EE4N^tU;L@~yT@%1qWrz$ z>;K>beV!z*+HsE*fB(&T$e~Az?;EdWBW^3+ zff%qhH?R1y!=ayU9#i})#Dc_iyNZ8(RFBZEf3Nt(Prx6){a5jepMtNRJD~XWA1;Po z`FHW_J237C*A)Nd*RYdrda(GDTQ7n9y|4J6UdX}wcNTwsPyqhdCVAE7{;2qi^S2A} zenasWcTExEncIAYKfe@q%1&S5o3NjL9QBpWLLB16RlZ4{2E=#H@XdVb4)~u-eY4&L z+~2uVUbXNWzG}qF#3N7n=2rk;Z+sxH+N~wN16zxQc4M9Ipq=2OD?ahnKJyX$_%`3N zi(rRr{ls_Z(K8{Bi+!zYz}J=UscYg`b-i?d-;uXM{v3X_uk*a~AUBr#jynU-edAzX zd@Y`P`Ve1#4)*uxxNq}bRYLrw!gu1180751zEc)HDzqyu^PTeB`G^u#>L$ zZM$U>^jW#@@&%ADGYfoIm18}39qYULbKL*S3w+;w5980e+IQQ57Tytd*;J` z2oZnF_v~l*`~7Ep&riYp2Q2gbZY$_@kCndHbkOCDJA7}RbdJy#uJ`?OJ@|6k{Uy1# zKZo@`T2kP_KEHEeNx|4lL03~tN^^mizeP(%UXA+`zLIe-ye-5jN0m${cocrhuSzDa zy%+m>aLKeIUxR(}qmt=|6xeRcBb3@6-cMpTU8&PungGV4<@I}dqm&9Qg99Ocn=mw!3xVGe++py1n zx~b&K10ND%*Y8WNdFyES+bt!x`M~#o=qkDUU)ax?rti}wIu6Bm@cJnC}r z*SeBF-1!>vH%sJIJ1VE-z2lx2qWSQW_n&~BG{ax=_Yl_k`N<{!xD4aJ`)k(z%Zw4Lho~bpHzAb=p;>2Ymu>V%zfe`(u9(CH5baD5JX zV0`K7hXC(it}i{de!I~2`DW>{f5W~$FuOE(72sL>O?CZqWobwU-L7qwSMAW>l!h8l z65_Z~r6)0NFl}n-sjtJ&yl!skS>JpLaf>%guS9%Uyt6=FwfLQ-H?08w9r%mVyXzp| z&e*&3?%M$8p0%a-?sYNr@MER-?HUjLxJT*z6JLU#JEipgyP)T%&n^AgL7#zdPAdKN zmtR0{&o6!I2a|+$5i*I3Z!wda-Ys@;y9*@LBD1~J~>e_58>xtOHwrff{zLqgLMWs*Ot&MPbbO#pJXuWZK6lZ5zlqHMq3w}n{ryRwB#PZQ!> zJIa>bc?R-C+sm5PUFn^!F=dw)IPp8k`vPnJUd{C$1dzb?8% zh`QgFeVM!f{IFeKwWB_R5&NSOth8*4SSTio2C)k9#CCCnXc0?m7)p1wTRWo zm^O($muL}Ro z!_TOQiEez}E?V)k74z3)7CzA{!eYK0D~`WnA|yI-tr7wJ3}Dn+;RW>Oowf4!pzz~6 z{@yEsxX+LIBlyX`7U7xWjB)r>P;ACeLf8o?BJvadG0hUfYUxRP@080>S?Z?%RzYfA@C(1Qd z<4$uT`jX_i*n+c%~9#M=^Je zgkZBAKlOXAnp70U*xB#mE_F#bxe~W=NJr*c?0YIf83{nq0jQ(cp^f;Ra0M_PX@WBn zE9RbOeye8VdKVh|9C2B*jrH^$YQRhzfRQ!WCtbARw+P1JUUAHI_}dRkQJ+SQ-$(-+ zC9NqaNf9B8(}|xt);jiP8LWtRQ~t!0$0|_Cov? z!xM_{?BDA#b|2=p_f8kLh`HF4*k)XuaT1BzYl8C zot`lVp&*XQXOudW3YoI~IP7F5^_kNCt8=U-(_ z=@e9r@s#ZD!IT)eW520=H%c!1-^e}G(cO?kRnSIX zhktA>wL8*gcllzt&}QQdQ*!N&9h03xluWU8M*6J(+1b7hJua1!hZ^aBBMs6*iAjC= zb*V7Bt@A%2#fQJHbjtZZNlvfjKV{8+9nNWle^~$j5!X!3B7=4C2XV1f+Ca3b>5T<5 z?4)Ywd!_$Pf6esdlxNFgV1b0SD7b0ij+FK%kA*QZogSFfE{ zUtQhM-k`piUp2eBdP(yXeM(Ov(N|Ml-QV9|)jzK)8tblZZ>?@!QeWAV=nc=GT^&!v zLY;}KKq4@u*1M1&)-LP``UABKdxHtT9`W}E7fm@1_w*!!n-f#?&S)eNj3gFKnKMPN zu3Z>U41|MvVxSLq@rLTocpL-u&C`uq`V=9C3B1ULBCB=t6bBt8Ro z)Fi!(NWUL?GB1jrkLyXrx9@0!guOC=$d{mq&YpdW*k1 zShJhMPN~(+C;WO(EZDWkN!Q19gs_7WZ6xqPk*}~m7?_~&a5Ppkb@uE92lxrKgM-p$ zGGVIrgO2<5g)`OWz;KJnkfuZ7#Lc|7Y zGH)+M5}^{v@dG_!$0G$xDtrB*uf zVF&0%?LGd;#yD(=Oz6h~`Y7gPjGnQ7Mn#;cbiexL$X-OMx@U| z%LSnJ?T%Nu%w3xSzs58u|wqPO=igd>%1LkAdy&`Vio~!r9 zv)?@hfncI6ie*O-PUbeKv`-AdOord>kxJ?!12E2DZ*{@U%|2!=LiJ4KFgVYR!I2}3 z>j!cZV3t$_GZf8xZT7{KRuP}BRO zu|)ROSK(0IV$B0gtK>}TY^3UxnXFarxg_H6fLj+#n=boIn<4PAi@;hOqc&oVObB&r zi?NQlq;!JdyAHW{?v3la4dqY>bUs8j@ND^Zwr7%g|t$i(+=QXzIb%8)E z7^fi9V?m;ZzZs~C>lLx!amf&Fz?boaKbF`x`+8cjhHeQ3=Osl_{E<$WY?ZtTiVc89 zqM$BC$xMzplWI&GD8VVI+JbaOV>jGWIL(xtUBMXqw%$-8PQwCjr9Z4kf{FfUY-4ul z)=8D3pdl1U+S@mjE;$6oX+X-d0Z_Q&N+qK=7}F}+ClE2Q6ZAxCT86)(QX<*10wBbr;Y~rk zF9^!+l-6Mga-m{bFxuEMh*+p~0l~D*NEJPpiuq(UIaM8*(E`X~u02x#=!wP?GSD`N z+8B+x43$r(+EU8Ow&x2BQztw7%|a!PO`R$yucKywx}Q}lRLyZ*gFx{N3(nDPGCHWo zlYKx`JQxgsg0oN3j*#mX$VHV>r?w4Y7a$?E0t^oZGBvSwfZw5P?cRu$+Nb zmfS@Pm`T#qR00zSLlg*dyhmAHoBZMIVAYD%m~cP}M~d<|e&>X&N}$*=)h;VrOdPYe zAw=;mA{GE+R>xs)3?Q=BtA`*0^+ZpwcM#*F6gXEDAW^_^Cam#?lNcnJkoH@mClu!& zG*fBXdF0pGSCWr>AO2Yood@Y1wKEchxF= zrbK@z(F1&8xr`|5{%{O2<^esp8Ii~MEFH{`sHWc86OH2Hhb`3ug5#}2u5W@g)hT_H z;fNh21SxnbgJl4<+Am=l2F~`ERWw{X`B{k?8aEP)AaGS(!HOD6H$N~-j<>zC(RF=& z;Q_UBm>^wXoVaw-2HU7Ea*yN!qL>0Sh(T!yvE+kb0JRd$si4qaVhWi2qJ%A<=2NC< z;&;^e(^2?xuthuv)xiiEh$g|^#xMPTM4YAZ)Ek9##2)AYgP7D>xFG?3`kaG@BD(d% zUP~$|>R5wGtds|CYqM9da5yW7!%67`XQVDAKI9Un!3I!uOsWQorV{G}S>Z&4CO`-F zj+fNM<3L6Zz)iqXpgl4ZY*Oc?)wq$Z7XK#hxZL_v-oW=8cYg?OcbNx_z zQz%tQQfsh=DsG@77nFNE)YIe4rvXsP-dUrKF-EfxPXQoR+h8b}O$BAqF_%l`VgVWL zXclGAPhuE_e`99nd~pa+>3Hb@82FvAECz;J#}tQH%tC3_45cP=C5DDvN==H}xZwhz0(I!U*WhiYhl#WAiYa;{)nTU1>G0 z@cmGmc`WLO$&(b6&;*dj6n}6oq^xGBh0dFa2a=Cp3epq;29fb8C*+nevf!<-;SKdF z7n4Bq0(6#2+caI&SiMSL5{s#L>0p~Y*D+4|#$+rS8UZm5Ycak? zwS-|!G!{m*jYAh&QiBbHmS!2dWd_4SFbuh4bY7{rls%drX)JAwz{(2+biZ^whaw4z zZ;~efl};OpqaQ=l)+E2D3ezzw{fW*Vx@VN7hz*1~has~jA_Pgz%+gg7nKI3xg+W{n z)vz)NbCr2>e<(7f6)?>rWf-S0vXt=8Hugw4Hq52n8eavIiEI^TQ6`{8><&6CX*P@| zX^Rbo^L3zM#_Rmjcmy?aTjd%|hr^Y*00%{c!r@RfyI+ek75m^!tN0H1kDF%7MJ1z$ z#e>TMuZpsg^a2{Sj$tzyMjqpZP60=^J_B10bGOQXjs+1?l1Xb9u@lO18lWjq4r$v~ z$v8y1ZJP?D+qUhU0mklZW0$Odq%t@!C&+WY(I+9lf(`p)fiebAc5qk*TeXS z3PP#C7_FQz*o7xWXsU)SF;v+a><(_$dy!E?y#Vb07E}yWhC>@+kp#PwVSfyM0*Xgq zVIkl&6cJ8@?Jfhl5+-{)Q#D^{Yfx?t1@nR@F5Mx=@HSpb zgvXwHPxrZpoN>NnebcX_WKuFxy4YBuGFDP;WIM>VcblIMTvYeNBJM)WgtbJ&wvETS z&TVV7LSytHmD!pUv@wFfEv1b`wMpY%MHH0nMhlsh#k3>U@|c9N?N`%ov!e@D?GUSS zTM<|Y_Vy(PW>M0@on@c_K?G`aU;*NTX6{f_JU=Z^G%NvUvCWcTm8{wI3QyIQtAR@aY;W0c8BtnwI+wg z=$Bx{u#bMJGn5%ad1L4gX?ZV{tjkIVhW~2C!T45YrR9}7tx~ThCD61b{V*lSJi1LI z^qZMPP0FeXHJUl<%&em_RzzW8r*F)07|CJ%Me0bb)}UXZ(5_~r*%ya#X@)JC$W>M> zjRZ!~2p0_-+oqK@5m0tLgMds3I38QKlIV z)gDahh8F1TLC_2Zl%RKLpUxgX@`Dg;3#)Mt@0)4gwh>c}1UG6x0AgwI(I#H}aR zvT{=vZpKxFT=&QIy5Nx;OadG=3zw-Mh`Ptd7TCsWl4 zQl7hHK7%378B(k8_qq7J3MZ->AtO{(KcA)f##v}6sAvWqH$<)_Us^&{$|=enJ5sLV zaHj5(?w&@=mrjI|NMXQ5dp(AgQ9f{7Wsp!NC<34ZVe7DPeYCe1$%Ku;fw)WxbVj2a znT=vyM~yyX`kWcF@N@2rD(?{t*7itQ-Hi-_45x=8C%UK!#ox!-&fZlpFfmxb18(Tquw@A?G$C`F%I{ImCz_hjm)F@*lNT3L+dV67H zP!yz3z?v*$cdbWr4-Lu?UHZK)ITKm*VrNFupLp6408!dORlAX1h;wC0G(g(6Ng7!V znY|dariu-i^I)0@OU0*3W08hvmnhc|iRBDbxFJay9acO{={DLkEZ8xTmwGaA zxF?`&y69>cpsn1gH#E2DL56~A5P8@8!Ev!*A{mQ-`#J`sV~Jhfgii&doR4}_$%_@q(6su(gkxChTb2m}i3^ET&bg4LnGn_-@5XqMM2b!o9nb}~1jh~04 zx=n)7m_h}^OGMkKsB}Sv84ZFIiqTc6?(@gvD4PhluIS3$Tu~~K&~@#V!imC287Fk1 zxN2JE*m{siA3jkAEro`Ptndz#AjnxdNA<(H3qNl+7j8tgK*t1(N`qihu+zA6?ynUA#OFj6RRNz+sY%5NH2%y&0l#Da zn_L#j(g5j*BLm-u6Cqe!6smy%KbbmJ$1C)BU$7I!XZYIRDa#q$maX}AbJ?j(Ktfls zb?%swjb?4Jo~54IbXqBkRZK{sg0?l~<-q>}IU939yQ8?-pe&q=pq~j0|2N6p6LxcR zS}f|~b~vRhH;OF`lsRKN-HJ}Rap_XpX0&-O$Z(JzYN8`5fe&F6Qt@~$(N##mo2LFw`^vzl zZ-tVKnF??4MLC7Spi8o(A63JkOKOo3onBcB%Zg^=O^Myq>SNP=rCiJ0H%cyLNZB~w zSIXgl!&ae%5>Ix*+>Cc6si>r7;jWi=Cktj}VcT&6%pZ`&Ek|3aB+@)9eYrYQKy>pO?02HdIGn};^(X)4Hc(9vaMN0)w4|XytC1m3_BNX12x!isT>w#U6uTni z1-0KBWl^*`o++gkPA5_&RLq|}M}`~S;9N(-a6tnDj;sfZLEH1E>foZJ{^m44No8B9 z9q0woi{pCj>NFXp17JqUD0MR-#?i*j2wA{(g_EMp+AdIZAR9^_0H~aR+|Nn?8W9Su zO1&@@tv+W2jFo4~lQEex+m5F%m91)=3#IEq%hZVuTkCV#pd`$utU<=+7${OQS%ovP znYNY3t;>dtM2Ph@I5xxpjg6xKvYu4=u5A5+f%4(o9Z86zIlUdZqi)4azkL!9qbcGT5LUZ}`}X(e2opnU+zX+gzofvUy4g zKXVPXEG9S7Rbk|jq-BRmYYDjud?5veeUK>UR>>m3bmoIN=5`@ahQe;x4B3`4A3`D} z*$w2So5rMJW;smBYy&kR6)18LqJy0%MaVi~iqs)?Gqqo#0; zA}464cP0}U#nDzdt7K{-q6-zaSz-DM1g>?j`;Ld@Ncx7PH?Em_g$G;|?^7ly)vpXWMXz=pnkmoHl(V+QqRVav zE{02(XuS|buvHaykk9a|Qpw7C=?sQ8fwI|(0g{l$S$0Xhcu?#)We4MugY#HL=2{T) zr74xhW!d!5Uj_wccZD#^Jye~hY2wC(ijSFpD*c1?TZMqL?VwMp$<4qCg4fow`G^xis~~S7Z-t{{ zo2Gfw=Tyt`n#`N?Qf|!2cAL2%=IoV(VzQdtXj=*+n}Hd+Da=qJ=^T_fgUl&MTXIt+ zylGV1#!oRv;VC(zm?ZQ0a?y&Jx4>+trdQ4Y^|GnmsPmo3DrrNNJ^zdXA=SZzEDwYv-fM=8!WkTqKGi|yH_R0#@4z{YXSc%G9F{DUk7NJ}q1Fi4toZk#>UVMA9>{!yDFN4hv@KpD^dQ zx)IHU5c3DtWRhNYM!ir|jT8aJ7RuB7$uPXk2rBLrv6s3mvmMyBvo~L7nM6komg8i& zeJO)ofo5FG3^NV}-_59eFAan~pBYP@SwgC*I&dDm|Lifn@ z1*^=I`^SRD0h!`6&#gyf0?>>~a#P8KNjZ|*Iu$=+YFVASJEZ24kdz9iHJ0zTUEEp=UUq+Q@qeLYzmc;*>&5)`ysNFQDbG^Vimk~`;0t9~)GV@7mZrsB zRCxfk692UTK(h+KB;>gk_mwq}NUP&|rQVL;<|?UyzH9YX%u5O{oC|@lLiss_U-r4= zJ;og_bFCiUT;E3kvme5lTEdBV^Ju=@dLvLpb17XNC{3xNlV;dmdEcsrSNS3Gv;~O6 ztn?)jsGzH2grU4Ely_aL0n!M+L|egqC-Rd=DDNk+L*Y%pL%UwJgf z={EZjZ9x^FN_Unn&)kA*zw)^>vvQpdhZ63jW##~t+_6(yW;s~ODOTLYCn=$n^kEAQ z(@$ljUG}+foX$Hk>)AHhbwfEJ*0~ewEVYym6!DJk0tgP$CqYpd(uWW>vYgLL?6k?? zt0d0S6jrbur9$)U6RA4=AsIae?NGeZ2csAuB2?{*8=7odqUAk)fEry0wY1(v|*hbWK1hXhgP6NQbj2b#cRh)83Md4YME{YeA;^ zHW-`WhNzQdAuNpqRsPC;C#l^dC?!oqD&asq(<`+MDF;j_brP5m&$7Z(ofTEGl{Ez> z65+2|0exwDJM_;17RWFUSUQUUrQXZ)DX1LimItuFWKcc&Y@!v^BKtb19A6fSp_${f z0KMiM%JE6x3m;CU5xX*4YvD3)Ng$+(htg&##MViYvTt2#oCr%Fd30J#OH!BhSn=}q z_7+`HyxSIeC5`Yzc&GJD-tu6$&;8~V*ahyuM(gInCTQ#=>Y&^n=t?61N6tlK1=)Xk zqnBm2?|=rins$7xjX!6IwU~9hrYs<*r^|x>^m^L{UoYDi80`7=i2llywZ}o4j7rf7 zQpaJP+MNviKY@$(Ok5=U*bzXFhofjT^B+UTu{i(6^IfzKmE{e$MM^1k*oWSw%HUJi zu@$Z@{%zq;)G-Oe;HX_5LIcBgYsapNAoB%xMT&U20`?Sj;7iBmkz$%V_A@ znkj=CEe0ObVx1{78eEwNInyPLPrA^?xp3?GJRXa11L>j^cQIR0fL$u;<|x_>14}`p z0cqmeKIW?0vMXzS14N24(r5zC!+$Euv{4ePZFn8v@WL!F!_)`}bMv%aLZ9a-5l5FI z1U1~(>GT)>_pZ~boA`?BQw? zni<@Iu4p(M?We!jhuVF#UdE{;Spm%I8x*Pp1M;vLtxDja0INGd}+(B|4w`ynu(8u?dX1eEOeQc6;_z3ph?4|1MaetBPvE< zN9dJUb^1MSHmtqB^9}o59?gxbC^`B>vtI*bJN!O)c?h-#%#I_hw{zV-1_AA`RH|iR z$5DOebgZ9rlU90$q8M_hK7XReZK#W^She%C6PZBi2*n^N0VA!!s(mDiiAe=Q`icmWgtg7gg;3Q)(ARwJ*iFFk@p)XN|zgOc)*3wZ0^FF1XsY=tt zlzf(}qx4{34%w#*#s}}^U+M%5am8RcjRmtMn++#nGK0Z18f?#n>d%buNw_dFQ!XlX zMES!rS<2**a!CFago(;dV5$y=-zsClP_0r*nNScihSO7FP?%Bcg&|?I+2m<1FXE`S zk;3yiY%^iD;WXzWBcx-_RAe1eOqs`M88At05lctJR$R|HSy;yI=@+1Y7zZ(Eu&HQ# zm5#Ht5qXFKlToK3e*Z;RK1|6X=5(-sbZ!>z1C1bD_kVcXG26by34++KN z$)GC6O($qEK?bO0PR)qyv&f3ECOaHgS`UwaF(QN*@zx76a$yr(F~)DC7@Ee=J@&_$ zlvng&M$nzwX(Bj}p317Ar;cddeQ)ewuQ zO22;s?rs2?^7yi<*{29j4ULtSH$*$}UJhi;&4v=`!<1qex2T$@+zP9uVS>@Fa&RHI z*Fv19+={HF-R;A@Es~p@(J@cC6&_2we-!R#X(Jbskryvt)h9d0W`~r^{-g4sRw9%D8{>5?ZgUVJGcCedAq1ZFMAQ@$n??01`Jt|Y}&EnsU1)>~13(D`AspLGW| z7!&K*-Ujjp#oTPuB6FPP`82o5euXu;42a=}wz*Oj1wm36Z^MY}6ir`M9rx{)B`gpz$jH>!{yG^L#f&G%K9Ezwe-0vT7 zWz8cTCYC4I_$ZsJ+y4mur}*kr}A6Hlq>J3(84EK5KZ|O_z?G|=;)Beg3JZfDmRgI>uTR9n z`z>{+A^U-*vC!N+)ZLg=YJBw+GdWD?o5? zJ9M}*G~DQpkhrK{X`d?j@6?anTD#9Mo)LXLw#< zRQfJ9cl#QmkPbogQHdC>4AP9CnUY;>w&0?b>`iA1d(b@^OnMuf1*SDEr?E!k{jdDC!Jp85cG)YS^G1{%SE zoVw9%O=<(u<<;N=@4xyYB>NzNviOJSl zW;Ax$ov9qVVwKDVBp*(8!`|$So~7I!r5OhI_$C;wQROLn(!=1kk9uJfRS?4~48qtG zrMi+Mje!RrZ>g(_8_ZsHMYe@RowK4Qm~VA~A(v@ex?yh$n9^Bp!X;(Z0*#SjXaPDh zl&2g=MfJ>9A+#jS0?Vic_6W1fhnbml1G7TP4zqww;eK#zjA%k>^H3b_m9VninypAY z%|RI8Zb0O#m06JIG|QK1rL#)~*x4=okdcA01{$@BFI;Ii64G?gT@A{G2t3edR#k56x)$5-EhrSa)#*w)C^chxx)jlmQDp!dmQ>G#bL)Z${ePMGEVAS zYx1^~(}~yX!m>;}9ZAz*zNflnMo7d#Bev&R)?ze%F{s*YcUb>L)yP=kc#J|uHPh!7 z)!}oKh!{JhiIJK5OF9y_lheDbqWYRe^GM;URx~PQo2Ke?pvwp`V1{%gl{+kq;?{B* zc*usQ{Iu{!E}|Q5t8bQuBFT>XuipJ-N0VJ_bil>bErU|3$gvaH*dS>Iv1Dr-_raT7 zlJNH7AX#QIB9$q9Nz?aMCMk?~Edw+e$6Z?0i<|sYQpn|Oj_Vx#V8uxTfzOlxyvs@mLx zgEHuB@>Ul7%}yE3cJ|3>Y1UF2*m8zpz^iJ;ZU4ZL^4yK!pWfCJ?YE0`Re(XB>>nf& zs7~(mf^uo`)5d`LC-=;G%)ZR>snxq`+?eQ_DI(TPi%^2A5MQQHP_Di*om7g-j;fjQ zPWyc&v{WRV#v4mq^|2#%c32x<4NV_gRlPv2uw^YW&}JPoQ!Q2AtVPi{yO-h*s2b-q zNkGv{ZA2GO9W2j=!_u}Swgg4f*-_XbrK)`@$JVW>x=RH)mFs6y_po%0C28d;>U8ZQ z^Cq%H-l?L^b}MeXUMoSiD>$6sI0L;|Of(CeJ=-0O$VjhoXxMGeH7T`kq${c+`mFSY zNhhXSG6OeicSuv&YuN0{K-mh#6bfc{MCQxbs>ttFzvc$zCLEWb?XJ`vtEtQ+mIFR~ zYB~=Y_L_8SXkzfRk?cZZP(Hhb8*k!E3xx$8^xsO1+Mzg^@WTR7$>gX+#CwtgQRxer zFX}<+v6GQW9SE$~ZGR?$a+T~M=BvQNj@`285u<6X0uo-2wLXg&wqgJ;JCjdFi(SR#c z6EWXI1D(W%Osiw?SlA+e`?z#ELMFil3xE%l*ikQiP)Y#-I!C!o>6%a+I;9*Z6mfMm z3G=Z@$RJq|uOJHi@nNS^5aJn#T1WsOqm7zOcNw}AqK4J7HS1&rk$ zQl2Z%!!dH6ZO7-yJ8bHlo(hm&!Qdv73)PThtNZZVylT~YKYfpSQp^*_d#5qGyD7mC zu+qS$ih+kGY0@Zza*g@h$g6O|s#<&5ff7fs-wmzW&_LPRmH9W@Xi%+*7!I*(8JtBz z+zeH}+l}RA7pbaRjdxH=MqnW-p}P|F$@kc@>X;d#dTIG62iTH=(rnF!)*&S$=5)?$ zN>As^c8>H4Cz_2iI9m1Qfn-0sT&i~{6aDgKvrq~0^##g0Og-!sufl1g6qN|qTT0}h zGrq&IQitJzILDze^*Xq8GOVz|RnA&i1_o^TlX`02YX+zkHz%GP5zm7jzqSgGKW0PKv1zrIqgR-()Ne@`G*NqA+PRR|Xqs|XM$w38Sr4O2xOv(w+pLo?E4e9T#Ot&1bU}TzZvd>7Z5#;* z2!!f~NRgas145;zvOL)aSPY9qH4EUQEWa}?DGF*wd;#AnC6KP8?Ld}&Ce<#6hUc7Z zYV*{ug4+)5rJdn)ql^*I(WViWDg<+~$kLZSQfpgUA8Cxp_Df z4;3XEt)?~NL_IzF?Bz?ZWsoD z)P!zpYq0QT=INaxp2BW-K$>cS#O7eT2Z=0}NOh`gT(9mMT$*IEm~-UBq>yb7)`KTWHZAJ>*w3qq0J_pDRX@zWE9ZX^7Oq z6XtZPUjVm;h7q?-m3b+8VfG@kg5K|F^f#)a6|Fqc$Bpk)h$rygNB8-Di&wF5mL81A z(!xdfErEZ1s3@w&Kl85ugcQ&Gs75fXd}WxT8+VY_JF%tJI0RRP3Z!cM&eOx@^%#um zhi_9Q$Lhs5Q}K5Pp5jXaShC2(avX0;YQ#EI-(_O!Ve$%b!T^@}%mD6Yc?dtHQ^1$X z_(iR?%iRn8IvOf>E$Tr-h??qZUIJDAJ{cecsz=pR;oE!LUR%)Fi{q4 z$kU9$_<}p0HBq8ey##`UZd*Ksb%9MhoFm&#Wjwze+A>>7A^}pBB(yfU_~8^NPI49~ z8ucEnEJ%_XN{ZqPD2`1*i3(RTEk^3%Pg6-$iOJH>Hp@lT=O|?YWDJ4QouvC=+QMqX zKwTD9?Ta^{Gk#t*`MAY+RRNmj$*N$;VtJ;sPrh$jdUVto8GyE?0LtlDbVv(}nkOwb zhi$O|wHw%`?zkN%nr(nazf-=ho2M=Khv^|og#p7{o|ZFC{AECREYgrvNb(J{LvNb} zA+rx895W!O{B(NRbWperWO!#jr`&j%Joi>6(xgU<;h2a#EQ>d_$9hoG?utjg^yaHT z32|zh)*2gBB;m{1-QlLX!IVUQ4Mg6}CKIjzHNb#S4ckWd?54l-6e zT8b~StC@~+O4Y)}!5;r66mPn&59MJ%dIJ0J7IXJ54kg-EgvRx0P>sY)$e^M@@s5?7 zHkNWaDX*y<Qg7=hueU&NoRd_KGbzk%-NyfCnXjUu-GuQ(aH7swJjSJi# zrO(6;?u<0pX|IBYV0HBtdu#nAa(_a?Qrcz1&YmSWI4Nkpo|=Q7m@8Q-8V4xZM=qtau7lh zBTQ`X_xJ)G9o#YAR;xy$Xo* z7NExV-Kz|+QD=)3Xk*QRD`dc+^B+WE{lPz%B@wO4N zF4pDm1ca^j+kDXU)IBJ%Fa%Z<{!k#%gO1_m z%RKc8nDp+GPr)#xo(>G^rcv-FO^X{xEU|QndXurMupABgB8xarq1fJa5&D;db^?BR zx+sHR?=iwbs%Zd~jT?bb=z)kpK%9mdH`Aq6c00w1I?zEUj+?PZygBbQyhc?7?!2G$s40avn-3D0f!u!^AeN6xBf_u2(#KuVHo1 z($^%n;1!UFT)1!58g1x?XbcfCJVD=-E2sj7h!X{EAA(kWj^8^V-R$k%XK9E>B~h6P z;;E=Yrvm`fH@8pz?AX^`X*kc%kXeQs^%ynGNXPzYO~=E%ERdw_#BJr$I1k;k4*3@d z!jdttz8#C2Zp?%B`JvuquO3PEc3_Q&6gWIw_oWp|^AKESF+d($Pr4HQScpxQ&+rTz zonVSz=YfNwyn<$oA`|L3OFt@YwyAN4pwWUVl zD1+OoT#nVag&TFAz8Cgk#<9lP7rabOclcMXuugNC!+uG0`pBh@k&QPCXFwgZ%tOin z^-fxzt)&W6#F3QbLOb2GvMAiF3R`e6PavwJ0jkrRIzMioE>4vNcClAwW26V|IbcT) z;3bm1Xv7!{_UZj>7-DcXd|13S0`EjXIlU`FmO^Z+D4prXtBkCBY>qsY1`IywchJei zLkWT-8fO6#inx=HO4Bl;zQr+49`NmcKi~VDegxHHojT3fAFmjqr)tI%6Mz!NB zDsf1mN)L{}GTWeHxU>-~@H=GzkHqtDKA}2F*jDtOEAf)H&K~q7hwS5`F6*6^Qx6e@t zZcC%07UyBbj4fm-0_{tchvD|yXYRbR6_ccN*9jLp)Uz4Z&qRgV2&KNH|A*3io;OU5 zPEV!sw%6>|7}i}3sjeur5$rX4IGFqGsu2NJ3n=I$+J+$AKyDNYaW#)cX(L*q?0SUq z95jAsk1khC9F3Ejd=U+w?>D5NjQGR&jANy=)|5D=acMSUeJp&3%h~RT|!papy22WIR1A$b6+Rd@IUGkBtDr2ZfF*|{o!d0!2 zJFenR%px0|`z(wWw8TQ2{GIN8{y6v(3W@yb;7aRpA8L`nEOwv&43hRCTt%me9*{$h zwITo#?RCWs53SM)WOs6&IUqX#L)M&yt-)?uneO?sNv7ehsjl4$x0c6kjWV(|D4VpC z2H(Y7JDv=n)R(4k9!Q%|Wb(ij9Y;w_K6HUSf8|4V@-8^6*;& zjxtJXhN6!yfa0vvVc<+2Bt)1-$sMHwNj0pLpopfZh9tpHXI5)?vEj;Ac4x%<^iY(5 z{!U@De$l+Rg_XS1299uwkKf;7{|)? zWRrX2q$VQIQq;g|a9?DXR5>&ol#ylco>H1LtQeIcI4pW#YaeBPDV3}w9l@ZqG~crT zN{}Hus92TXw2-l18;X_!NjA9v6S2hr0ycg}BQLv@Eo+cm3Sf1diA1h6IITgNV~hZ( z#y}LxePSngn%}X-EDb8gagtJTU}5-<_fyuW=FHMnw}73&7Y>>v7e}jQyq=A4;}9Rf z3`N;t3d?Z^w3G}iCt%B8oA3%L_|Os9eLvW^KD7!~@eK7(wgqv2QkG;bV00Tgpayjm z9RXNbb(Ae&bgZ-lD6LE%fT#jZ$XI^1ytz7tZfDIY7Zl%T&znz|=c-dqnM6|aK!c>s zTL6+1NVY(rxZ#^CDD_n&AXRTnk`uDMRJ=!z;|L=xS4a|-FHE|pcSleo*d(kKSSa<# zRz0rFd?4hn-8Z5dAZ1u)26j@jVz$B_-Np(>y;^T$AFTF4iZ+@YGTE6y&9+nOMR}>d zo*7`YRqS4Be&^=!RfY84+^d(K2Dv)VKPelVM6et0S-`2Mg&^QCN+W&2_OE zoLL@$-eTPM^pKff7E7upoXuXvs`&dx#h3TF#1IfpD;U=3!e@Y}xN=ALz?+^HLO)q_!ncR;WS4 zQVdhmsUE}xosI~U?J3raH3Vm;7WL-rTv(8QrH@> zK$VHRtF5_WwQM@h{ijZ5`3>!@HvCS+5=Lrg#(|CRtbxa`h84j4OB-U{u+i}rB-jL5 z6Ecaksa9i}2>#PiHLW9tQiq8v@%KvknKBM&nQ~`Ufhw(3lTgVTv{UJRsvI>@s$Mm! z$~@(h7O-;&?CO?C3xsrYU3+EA$`rb$OJKpEnj{IyvI;voyFt$pIyWPmqoBf zK`lWAH0aC^V<9bRyTN#3iYStprIBU&%4UHE)3+);+b;1>=M8CG3)A}%NIzWUE_tvZ zVWC-PsRd7m4pG;52uQ)rXr*?d0HA&CBn4$+QFgI)GAu?5lnD|P(@4b*$Iuz3Ga8O& zDdbp@h7{!(ZI%MZB*@gXCb@)!=*(nDuCZX4L>N?619Lv6cr%$34`Xhc(;BhjJ3Kk6wlg&hC7M`DH`WY`p2G1d*vtXmZ|$!^@rOtpxL} z_%~yi<~cN)c6e`wVFoH$9e{_VUSVt}5l0yV>LII*B3JA(&oBh_#ji#N|D9v z6}7=O&N9>Cpbw>YC;*6Or3wdRp$4^%y%MgBYh_2b%tPfA8c?3bF4=-4X;P|nuf#u4*#9X_-W3fLb&%yb`GQk!q{c{!u2s9IKnSB z15Rh7lYBIy8G zwj_De^UgfNp`^De22BkhjHvI4veZB2xRLuLqoqG&zbAz3Z%gb#6!0?xF$k2hiakrk zlMi%e9^Dyah|vfQFsDbhQMImkNx4O=#r5prgs_$o5p-Y26zO}Zke(8{CgN1O#Tn2l zLeFw}>S+*|#%19}+g~X&%D7Et%uYLu&5)l}+$UviW=XX1E=KpY4M+B6P|xmkV0NE& zw6t1S|3Xa&sQPdplx9i;9*Fhgk@&|a{*^q(3 ziXb$aZQ=Mh8oKc#qTmp%89+^P47eI9q6q_AgE=U-#5vp`v^IQ|;Q~sEmIolP?X>ZR z^tc&)Y6*U8 z!&llGL=%E&5{F&kQx5_m8%UGOSz2k4gp4&<=7=RZ%36c8;iY?MnilSWvkRu%sHtaq zi`00=d0zLCra+#iWXve7{VP&T?m_j@=LI81%znr?P zgh>F%OL|?ZXO}yuy0j1&|K-k5zoce`ZHw8ftX{KeaJJ!A$xR=6xME{C9>&iuI%djX z^loG0&Es_ElP%t@`9rx91uT+ZK?u>zz z8@4(OQOFdYWs*JZ^?{&zyQ=%jPr}OW@V3RSn3J-=Jj7|r2C7SD`1pnp#%FjJNsAFN zmXMSFX=SPI+uS9oVCBxqm=3BfoC3mzzsZJQiU$Nm+1V5BM>N(ELVu5lE9hxV~dGu*+yXZkbR+HJSv-mNG0;j+=5wi!0l%&1nD>{ z8p``rn3>^crp40;5S9G8)DvF~{mbQ=B<8U;e;C$X0HNuK%&oFrvAyIf-DroNOpC1X z=|NDx7_NazNMx#Kd&xEu)RMswX7a|-2WGki*E9;`JIHL15pjSeX}nX|oeYSoG-nRz zb4YJXqWIcFP*$pvb`asE%861OI}Df>v~g$|D|bOUAKaFoD0Ay^SqqeXK&vGxUa~lt z<}w{LD+OY$lnz=Xjwoq%>92Arrae#gc82+#rb7`LfDUENk5JJA>7b%K$bp?AvzN>u z7$1$CA=^?h(aZxysUsAu#oO!$wcmHQSEoB6jfIHhK2sbkdy}urvtuDX$vAPeOfo7i z-G}L;t$+c@yi9SRl_S~;FUBW4sz5zMNz6s2S{bw~8JtjVm9iCvqnvHII~_i@sy{%9 z0vHGWwmb);Dih>;NDckrJ#2BJO)W&mBn}ZXB-AqiCCw>DEV&8lFLeTkuq%jDxs7YI zVVF2$`kWbd>m<{6vza)3>ZOjUZGmA*%}l}J?t9t*OqKwo3cjJCXmW)@scMGhC{DO> zX3eSX=BP7z40%{RJ1sWc$ApC%+^=uKDbN6Rr5ndU_0_G7QoyF;W4Qy8eyNh_TA2hx z&A@Z4tX}Dms#@hJlJj!AqY4iAju}N zYM#HNz*1QWnl>gmD96JRK}O1qp?CXil-UcyE|j$QYp#Tj{kCGV0uE+1V$)U&c}X}j zw}ZNsfGm%6Mcd-94YUo?v|)hc3dCioJ)k?!vxj77Go!Q!z%iLc%(9MQj;v8I@2thW z3xUyE>?+$wF$=|Plfxp<3<&d)2|W2_)HD2e-yz$v#AprFXlqIwT7e(kW)kf77~c zC9cbcSj^qAf)pp;BnF*pYZ%VjQ2DmeUYtDFgM)Lba5LNDRw&gro*scE zqf$6faM%C&TU4Wy4*JNTF!(MnFpifk-%H3G0Lpe?6UJSlay=A&TPvtnCc-Oy5P zbhb{@I;z$@HH=7cW@0hZ3!xXS-t(9KPI&9(Y|NbzkCtE2?++!6h(h|>tFZPC@Df#? z&26cn6kTLucI*-yER}r(F4aoIkl9#Xr7(B+T|LB?h^ zqDbptay8@q(>A&6S522PcvjE$&vKIx=?CAR)vno)s#$jRDD2WuL+gHBfFbA&#D<0+yY82TMSe!iN&I^ z8ht4mUqCED-uC%p@Wg1mA+fLeL0baKRpqQn0l6JOX1)+Z83Y+o063&HV{B0Eh=C2_ zYy(6FW6Vlxn3+~w!tm{(p$BAk(G|$$7LdwIw$FUp=Qd3b+N~-T}o zAm0J*bTjXi87QM?k}OGTsj`zOq%k1941-{4FgP7660})&lkS14CbmlIDkn_lDDec9 zjxvCqQRmd)?ZHcJyAq`p3IG4=?%SH9y0SDSgDw^zF2)#Km`YS!WH*vP#tb9NltBWU zYQP#K%C2%(ms3(oq)BC_^I{pgdZHiup&#m@V;<&dVmhLuBl@KursoIDPncga5%oMV z^L=aW>pAvM`yC~qc^<0d; z;X25!xePFw)M;L^-daFQp-od@s4Va#k>G^SL&Sbte7TSSko&U>V*>3VX)NxEwJ&v* zc*d$Yc{N3^5Xq08a_X8j3(i=o31Qx06S-A9X7&MbLWSNui=KIuDr4jLS`nxD2At-PP-F)i3lJl|ba4QH zX%6+D!MrJ{NCJTzvmO&=ve-|ip^G6opz`jOdnE+qX^|m%l!<)y*t6HkAOC+qltgVw ziupf#iU!qih;+39CGbF58JSqF6Km>?o#vPEs0`od@9bK$8hI$C!# z(K8eA$nHo$Pxo58yEvr)O;hJGoAV^)e9C|;WYfpIXSskqzryOm zJU%_`yxyQ|)m5w6m2}Q)4SFyX6KEac4pPA5?pPD8qB-qLyYMpI3z+oXb=L>@rK%Qc z7|!b!=<9T&(m@iQC421YQ(%R70PP?7_7I>Lnn;^13#ux75OM-Pm##UTfaG~eW#f6Z z`9hlD(4(%TFGx5_%2kgfb|x7i3{Z$}UNTZ3txQDpvgVVl^ff~@N8^f#Nvc{9^C8lR z86_=>{iBKTYGXeXq<~Wa7~Kb8xeMdssdLY;dvJ--o=WiaIi4$XpA>8gM!c#oz?b2T z!0#ko5YWJ>ao+g-#>hwbNzsz$!Fc8P0zc!Tm>tX91Jo%)N_i8}>gcu5MGrzIUn09= z2f2(m{jMCt7Hgt6q@oXkhiNx7bF9w9%If z?U1*Lz^2D1Z+D9B-G&=CHW-BRmC_^|RYxF+d89V}?q1}+TBb*R&$?PTe-qOtFYh*J zV;mkqdpWs6)}~F@Qy*%s-4+{8!RIae=B*(+i&?mb@s>E4g3(jlux01VwYN41bHfNXTZsqm7^O?-6 zff}BQ=Lej0G_beM;-|B6KBs0qs?gfqQ5{o7Z~HL5*^}re0O;e*6ZLg{o*q%#o zGQMOF5RxphBRxrC^`io4@}}Y;pm753&vLMYfGmm2BSqrB4-kwzByVRSn$hOjz`uGe zdoEA*Bmq=*Ro!LL$HQ4 z#j@pm=K#|aBSwX|kh1Cek!ldP8T6q_i5*K-mQY%ZFWbk78o**Kugq2aVQsR?vymui z-)9nKni=1Li6|{9{|2j4A-{w@J4|{1>p*t?4N(?hL{L_n^)5v{%b-CMQuy-g0vKY( z+sX;DRaA|-)S zg96Hqt_oqG{7IVir;x!PhD&xLxO6`G@gnEpO?bmEVsBWRW@F@6*zo&U7t@3uOYA&S za*wi2uTSvKcV-;ERYR&#PaxFDF@8eBI-k2CpD)NroSik^c;fu6ZN{=AEC4RH z_fm+oacZB|qHDINo&Q#$=6aXS3EK)X>9dJ< z^%mC68TkH&>>#m%r^u7z*(=sG@jat`>|bT4AD#+vk0-+0qqEFnjVeHp4rc*;madZCq!ovM0GnE z+*y`-8H@AZ#8I6}qSJx3td-Y@eOq8x0*V{ew_kN9KJeO`>ziuCp z@*hp9u=z0;)OLgJRXe-&<{T>dEM0H^@G)d_`Fpd4Qt^AyM~&J}FZ!S(v&dU>-}UA; z8ObyU*@E%Ln3?N#e`4qvY)iY^bTi9x45+sN>dc)DwN!VPunl+;@n88Dw311^hq%Qp zyfVAp^6mS`udOWcz8PbAp^e?-K5|oejubHtJzZayDARc{57G2P(^hDI))06|T%%fk z>nTXxx|3**Nz7!$yE0iVd9izKcZL>9zEU252ZpU`GlUi^R=-YaM+*e~mb3k5~;lpepR+FWK ztxSdl-sv-#+Gh$Lf6U^w!16sBzqPBJ8#c_Pi}MU(=p>g;6CtvYoregZ7O3!?Dq!>B zDV<<4UbnxAdRleYgUEp~Q#M9squ$Dnlm+MmNIF!f{s3CX)3m-%jen)>p2EL0o^xk= zOzP7%Yx~_C65Wc>!yhY$=9Vd5szX)QoPqZw5ZuL|xptIp>6ZZQHlQJNHOU3>gOW1G z+xXVg+72A)&np}hl(AOblQe5L91B|#xoV?Pf}UIGxF*p>sQWtUcWy$~FjVJ!SV(q! zy;kjPNo@f4iV2s zYWleMr%c%+lv0hxxIK7`==}3Xb;6HaA$5w+X>#O>>Y@&kLsy zyyxzz!&iQ#^#jAlehqn=%Tqa+1VPGe3UN?x8j}n(RLLZ2kwoBmb~2)U)Jh}Ni^72Z zpSy`axr@Spk|h8;k^Hh>MF5IeKcw|1jC}}B19@e}I#f!D(}w+*ZjzsKZ$pT`dM${# z!WiOWct0KtFYUbw?f__S7ef1UKs1N{3R(ra-8&yb^YhBwTv*&ZyE)S^1JYGQQG02m z;s%*y>qV(1yi+3Vvr?zYFho8`0?kqb zA^%cQ8l_a-zE8;jvhFNInu+%Z$i)_>ZQMStQ5l6#Za?`23dinuz=tc<9++`k>du9C zg7L=G7uCkQJ<6L%GZS`D!qGB^;=ucf$#DdS$_Gd$btkuah zAP-bL@UGn#&lOLZW-^<}$@GBA=1VwW)cr!i&qcdi6fxh~4B8NOpSnf8Fz5$b-j)&S4?MwM)C8%^;-(n03YW@g9$-SEfELLb-ZR{FVG9_tB zaSm*+T0b~xUb+TtLd+Su#-rT43ZkSSsX10D6M!yLq@+cK))px|Cg=sK8p!m97eog{ zg~2cPCzdKwM^g!3;?$88Sh&h55%d`i;)@_op!_ZZIYib>L9P9jY+yK1hTb@`JYQMo znA3CN3fBq|>$nNZ_`8qc>1xO>vkd?Xp=!-p>zO21i7uDp4bxvTL>kmdN8-kwNDj<& z;ZR=pl`y97B0Pni5O!M~D9Jj6Xc{Z-LxF7ymx|W~lC7J6>@F%3oAspLnT7#^860Ea zjbW9uv3pR-OXeCM`3%?7*S{M33?#Ya`6<)04RKKpw(-Zv=O}yWD2(-NH^}f~FI0>@ zMm*G3@itIv(hv=XPWWWy$u*eNAjg+LDHW}O*|xyDhjntjwbMiG(vqz_4W*E1K?RQr z20cB$bc>zb_+_R0ytQ94dwE)&N-ZRlw5w3POS>*(l6UbgS_CkqrqbHl!s406*df8| z3N{$pc2qUj`%T#5YJy9j7E1p*v+yV7escHe3s9jfv#0MlGy_h z3BKExqA}%RVTo{M5a$Fol&pI)c4(z9 zB6fa)3xUTt&td)Tns$Ux&?Y@Oi@8w8CgUbP&|<*8r~~5HljO71NG@p;H^`qlm1R7w+7I9aPZ(sH}SiV>!?%!$s*(;RwMKREr|&wF(y%H7$!}Isw#13HPPQHL&R}VxlzVc6Vtih zd2-Yt^~FqjeQh;TKC2QCMTl!7Q(!!#l~&I4Fp<#FVMR0}MfJ>YtE}P;pZ&wDXu?3W5_@2*!*N}*L_*$RHmRXHA zxs@`LYPam-paM9FnAc?Z4o?;K-}vp!tJ_8DPfE&#Wwif|~EKNksPq z6s6E;1+FMFP16acK&QAjFM`zo*=%d?SbGjeqkAv0=A$OA}=LebDfgG{i8qm6Hw z!NbUyH1Lf0q|?>k*#vENKHiyRW66+X~4 z2i3&0<_lcW0iHsS89oTO)+?>WKl+J%5;HK5k~_ z+2N5%sZwHyX%PDw2r-E^693$k6H<^b3E{vh%^4`?F$I;qgoGnRh>ksx(1nKki}3dP z^L~$Hg5K#!{5fU6F>;YrVaq%1o{*+8(x7LxUTw5g?VS`G27(FP(hpz0u^@EgO*Crh z^}Dvpa1$a{93J2U0YrFl5nP(Mu3Uz`rrodw}fH@YuPAUZ9+JcB~%l(SoY=5x= zUokpqBC1}J3;0{u%&Chq_1o|m?A4XrWx(EfEwCvb*_ahIs|*Y7)daYm+HSuAS$zPg zm!JWWS8Fo)unzmfX z5`F{wbXar@#XA^^33`PNo_g~lbYfS~UHDry=~n$miVn(^t-ZmBNN(Vtn3n8L&K9)R z##4!Du9ZxqG8a;4u;*l;{_dSKlW3)}O8FH31(9%+FWB|VcFbu(?4re3n+9k~F=P#Y zoTIBE+C9c+D!@@nVQQfgThUWR!XQ6mqyeR9<|L@ejsiS0x|pxSxsk~;N-Mk%wD(fT z=VUGE@io|MEEcb-R*6hyf__LymI*J&VeIo3jOcKcH03u#K7)+StDT@gSs==Hy` zy*v1iw}bbDqU9Ii8fc?7D~v-?)qCifpch=36QV*Z4@HIBF!@R(@KxGm%Si66uv z;wMOr>|!RA8Q*bVbXU~7A?M(3;KeZVv`H_uk?bLtu(g&8Z;CVKq7{U+(ZzMJp4_CavrJ$pU-5MX{-!^xc+6hFs2@T+eclqejBAH zaDMCtlU%KFQz0V`S%LuCI-)v@jra=} zs7tp>WthyxyZ1ykCOBcURbie!&sNn_&PF`2r=6j>!PczWitb^KK#&hMUwPQ8?6;Wj z1QpL^>{~5I?u6j@NfRX|6oB_vIq))jB6su00(sd3seu6p1(S8A zNyAA5G+xVQ?&)3ywYwdb{M1Yu_7e}0xnx()184M*NPp(z%jqU?HC9>UMI@erO`eBg z+unRjgh*|5id-s@o4_Uip}nLtg%-@Q=_o;}))c)r76Myks$h03Sh3XGNtW+nP;A-6j$wrGd=GT2Ql!5+swz<&-o z4;d>$`soj-1COHMnTUeQ!iZS3i@I(%Ab9n_y?GM)4T~Sg&4ttBpFkqYo)P0HJ9vx! zxPr~YPQS{~CL&sjqZT5XTlVRPO|8M2B_-*}G%gguGZL*V3PEO1VtPwr5FX5e;XLgY zJiU}NNY)X!E#!b54FfW7(=pSKT<3{E3@C;qBuF6)7cC50PA&(6=Axx%ZOE)p^Pv7v z$hVsw2R{=kW01j9DzIw517Z&2yh+qVgoPfeJ;hX%<%-y$jTR(db$@C7MZGO>N)a(v zCk)c+E`$}xbt1Pya;Qn8v^pB-Y}X<5HN<(8Udn$16({v(&^hW{iyXzjHIH25g;ld# zktL|npOJ`l;p6lgpTpaBn>D^$Qy^6ipwJo$$CL|fEX}?MzpV72mx-G~f!FFap%wbK zqUcrOy1_DmHj*s%yw+%IXr^>;hGpe>q|Q{Ww19nsrb9FRbGH1pAwyQOGZj73d&KN7 zYPI&ldokS}d?>&Ay~vVvPi8L4TA;Tw#>Un^4)2}_nQ3TlMnuA@70P7nDHL@-q+#8qjTZ7 z-OB6-^F7TMk&4mjkr|_^L<)+Wqq&oJr6AZBO>V|fGpuLCH0k<_;9om=cMn;i^hxbE z8!g1^s7E^Yz804XFP}Hd)}@T0blm|;Z@UoCBNpl z^u7`T6^^r(E%@AEQ5Gw3dI6`+_Jyx|ABw&%_OSHp<4Dxp7`f{X>(Kp;yXhxS;7O{U z^m0l{rh8}XQFXH>VVL=qmWpQi#|OD0e6PCvyGL=9&Q|Mk*QNL94yXyNIaq!9wa73C}+!dQedX#A#ty&vjQ1fzc zPMD&_>9;OKecp?^aSWq% zaeH&4os!6xsD_6dVdAk?=19J1TUW+Xn3$s605GkH(YS{eC!ktr7L*+7w9_`-eF==| zM>xoStHau?$=6A7!)B5Qb94~+3z}Q`S=>()SP)S%y@O~`wueAmdz8t^nTzC{E^gZ3 zGUeuFU>faq-a5zA)S`?GDDqa?cSKq-e2&(#cBlS5+}smimK@g<%1UU1ZC~np>}&XYq^Ngp20s1>o4guS z1|R$S(Yn?EPd=_y{KC;uZZAFhkBG~9%UtO$?tGo0WmdQSDiiCaRbMo0kVnnb4U$mx z>e|xz3^0jBaBGLQrWG&7E@)W~Bob4&)9Oc%@z9x6od#Y;5j&m;wT0jwq-|v3AYTcQ z7N-E#5nU&&mo6DKJo2aNXBxLOE4Ft{ink6Ht`{Od)SLGM!SX6er|77r)hnf1S|?{A z)<}FdJsR(epjim!FC3*w1Wgzq2_94S#7Zod)YO9fVa&jO3^)V@strplOxeO6RuU=S z|5Nb)F-U^i8a#7LD4k^))Xrz$@KmWdX($0Lz}A1v<^Owz zGJA92h5z;MM)Jb4_uwa}gFTB^!X@Jr9!|24@M$bY`e6~PnIOIkx-NpjnUK8$B~$_r zgo71Rr<}_!9;RFlKSD8{T8!bT#p9F*g%rPc8sZkwjZ&g(IO5K7oCSqdz9}ApB9i*+ zBm|TW4L`tt>eu>%2ABcip=HI2e39IWp+mD&zJ+EvVBxsnn+`CE{292b>@P<5qgKeI z?;T#|U<{3LEI(nUYJ*4?ED0Q?WZR%( zWhB}GWApIBgo<#F4k4w2Yx@yHOff4%z!AM@;7D1m+HcpJPOBaQB+VzcGGi#k`O`bD z^&YGNY&iJT=0E|A3R0*HWUuOgrCM29-QXr%%3;>z!=`o{9Ad4v3oY9=h}h=YMwk=e z@hNNFmV=U<%pvAIl~wEmAz)lod*Sf|_JQh&8pbl19cUKPN?Jx70xYd;9uhQOn%I%* zkziT~+(B?4MKC><1_X1!!r60`c%;%4C?|X-Bz&$6GR?>MjM<6aO0MG23nQyhr(=8s z>wSb>4JgMo@tGdHh9$*^@5Q1eW9Q!%uRg=PS)a4pu5E#72klnj{ubN1#}N^i2COo? zh!F&%=Nz&hHR_v;Jj4l~2g%|-sJvQqvS=~QMs)`{+Otl=i$D!-%A3!c0;O`a0c*bw zIAiy9?DZ*jVxL&imbP7*;u-D0T{#spi7)HhyEU~?u$pW4D1-VX;(4G9#TvMK zft(6wTcf|%tbAYZ);H^odQUtbMI&Dcvu%JYt!^e06$PR|^<~T<;?JzKrFkRb zGHS3ljWn_I$s|S4#cjz59pTY)V3|l*w@t7#onn+Jm~hghOd;Qf`7`GoEVy^w+IM}p zNO>V!9b}-E?dxnPmr9|4SX(95#hmMyH9(2StZeK*8mlSV(P50oMeh#DpNd}pR3b{1 z%QKE&^{!0xGLAQ4h0lm&XT%Ke91<18Th@$lc96;Ufipw3b&VYMr*-nKxc?;5bHLPh zhFo_nvQr(71yM6`zfJXJm^IVCq_%3@O0dJP&HdRP`NQZvcSqkuHf&AyvJ6o#CB`D9 zh{6ipnA0*Q%oJKrt!&`g!hwkgBt2swE4bQj@FR9`6mKgVnWe^3%V+R3u+EJ)A>;K+ z$2z!BRfLFV0`bgC6kg#L(ahCODH>(kjS}O?II5=%Ku5-pGm449XuN`178+f@(N(ui z??~0IFbYgdpOhVe>Ozs|=*B}nBV?npxBpB8x}q~=t|)DSHbc?7@%x#Ze|)V|L&iD^ z>%irJ6Cwq3Ta5dWY$=MxJ%(hFWZtUd!<95|TS< zhtzUzxCfcQtN5xNN6`uwLNwq|X2kzT(Urx`S=^dx2K(nyYGJm+RR`#)^*(EE*q9pj z!YBiJBgb8g-3)`n<_>d4kQ*eQ(Z{dCojyq-9?Sebn&PL{_~(SDAf>|?dx}os=>Z|j z^S@%a-m`G!6HNv{#X>}Ct*0odX(wS4jgNjh#RG04Ymk0x&6DCmOh0RLGsK&19UteT zL1}Qd895;F!O3F4U^Hk_MFX;cv=)OP>!z&aPqj#F;W_qk+SV)OS8^rZtp#_OvIzAZ zn{7+2?%K#RQKhN&gIIxRu>u#>W1BMISL`P}^9-8rZlkpc89P{X(TbHHD`5F}P+2z8@*{&G1qbO{nVe0h6YLkM7Sfu@P92E;JeG~y|TK02Ez2a3^X zZP!I*D;Lmv>C3ZtBtMJUh>i46w{|<#y$Z@#b>R|C<11^lqm~GMa_8a+x!>ye)OsA? z5^hoNx@mgMJ(Czj(>x?S(Z3**n28Y3B1Z4wy83i2IcRVNb@OTTClLaBici@#%NXT> zKH9O57lzKGY>1`OAqm)&K6kuoz9T3zkTkvS96paz*lYkmn3cKl5TOqJ1`|?W5cP2b z*ouq@4>_~Z+6RGxv$KUbFw~K5RlbMa1!2x8nzSuX)2q~g9vB8=in(+QY3qG8?EIZ* z1T-9Fm z4Pzrj!XQILkQ-O2?`TbjcoR~~g5ePRgUC`8*Fj8L1Ibf;1mueKFj(zD>!by*o``&h zXh-NU@r{RT#JFSd`>tX0gM{cy&ZiQ3H8X8Y+&IVhw)1Be3^^$hGVZy1?eH2x=?k7N zjI0N&h5-iPPC0OW%=;m@dN}xr9Z}8-Cry6pLtcO4JGw0civIHw{kea*_W<=ip zQb;l>51&fC>zT$Sz(|DOHhxU?#loc37RMqZvNcX7y@;bYS=ZCfZR_}ow3#bjJL`6m zWM!fAdv_c)Nf=vf;VK^Mf6A#^8T7S`dVpgV_mAdSrPu5jLw-S%DycXr5mOWFr=;In zw3l>Ge^)NT_jzLphh^Bj_dEr!oAm?s_K6dp5{AUeY!|c&sLetyyRDYC*Fmix>Te)n z8nm0lFILdd6%l?>L_mwWpf&tknKs*0bb)nYmDm#xz~K-P(0u`(SKX><#Bp*8t$D(p zm0``3!=Iy~eern>Y4%Iw+v$M&CCC0QWRil_v{a_gEhIdjI{o8B5Ge3KjV zWXp#`p>F0vSDu(S=Ja^q%e?~Lj2DBpS1#*epPY}XArN*z17{O8K8JrmmMkHE{c(JxSBKRr4D2Y z(^VA1roTiJrbPFemi^JI6(x>6YVAToA*89-rVua3+la$-hckv(ir+YjW=LAbpcQQQ zn<$6YMR4r4>~m_S>tJ=vfh5Ab#BPf;il3HW#{pM!fuerK1YA|(Wfv{!L>%2606A#} zDuglaVwqMYy)OJFRO*hi4X4)psTd+`m<9;1NU~fp?FYOrJvk+1FFJb?{t<+OzACBZ$chT+kXukG-|FLJ z#PQY81%#rO9wW=OQCDS<>3&dv?Qvlh$Y5z*TWX?bIhBSI)i&BIQ?E?MosMR#&s+5^H8>WW>J)VS3b=ZG#QTuOZd4xE?-3W?(v;!6ygiNA7DsO5 z)xV5how%`hyYiOyPT9`3u*7?DTG zjWi`Axx)U1h%#x(wtMq1%V(F)KahbH&UP9*MwMPOP)QVDh4dRCa_q1n^t*73o1p); zDu6d2k#>>kFk*tzuf6-(OoLM^tV+NjA*9nHJjJ*Y3TJx`I-}B#w|7Q6j(Nk17?hj| ziHXq=DaHq*(`cgs>M@-SO*5AfKv|=eQXPKOJ|RV^jmB9i%eUx4PU3;Y%b*fSonh|! zk+pgasXI>ADcpsBz%E3&BUr~Qm>C(F?z)u0W+PKC-w$o6p6qG0ilFK??5K#fB{jyC#ol8czi~Emu!j*Of_U<&2rc9Jo4nwGSxb! zsyhg(b)_pxuje&fGTQv8XK-vsW`tR14#v&*w)I-b1%X^q*=V&Se710>UbjMsn@Y8p zpiD^NR7@ta!COR)Sem2|;t%SWl_!yzG~loLG?_i4c-rYob7CRAYJhwl;gp@ zh)C1Aq2W`!1~3O;4N3^C@Re|exU)G)Vs4}*h(=8<*?!y_e;%Nf0oE#d!Z$E$FwRD$ zA}fY=C3cKAOC>gd0svA#F&CauYBbE!lAsZ1v?}b1Nb8M*v-i-2104@H)`XZouI{28 zx=vMZW_5aI6V+2-0+g!;;E2IT64OZ%+#e| z4Q@0pd<&wZw3ZSEwRW5K&zQ)y)eO!N#eR_ng_I}2CbsV6mgb}N)UxlB z{)|_`ZR|fQfar%&<59 zMZ4%u0HMdGT6Fph@_D7&;wZn`{{sR=&Z+8^W}?-2EwB)^=EHX>f|r~hE&vxe)Plun zy^N77;NIk+JJL>>4TO6bdkOy&H^iQT8Rwx=lALIJU!Q6_54>T6U^d0|@3P_a!QN+k z+UkgFK|8Wo%J1xoI5q4C}>A+#xL7D93YUMc^u6$y<(3)@OzuT;%>#Deh*^+kV zj_Fcc@cr^aRhpUR&tWG*BkoxN8sQtdti1?m&x{cvTG)%MDa0ImUl5h)FlYhgo>B{r zGXxEinSw9JL*%#dBfodd--bfI)>5)qviAXL~p(siq7wP30K zaEbSZTB0fSc&+lHR%_Ey3pLMr!j)8~R{f1|ziipEqKzll3RW!+-16h~2lZjmDp=$! zEN%wFB^+o{WM7zT3hd27uoH(R6#Ml7zcDo6<_L;+`|p5bBv49%NSv~#9)StuAAEg$ zT_Rgwsp#}VoO*D#ve$wUjtCsXUAKX8!Ds6;KN|$J^_sGmOX-mJ}3%cn_*teB)n#>eKPm zdYKDnz71p{G8=_sc)}PiRXmF3TnvU3O*lGl_>;9Or34t2@U<1-uF>v7o0GBl8%uOe zLT$*C^gZY&a8-aK$(w<3NdAuPb-jhi9((_yJ|-cB*sN_ac!O>h^peCa zMWyRTABDE?OBl~IKZW{NjhEt%fvDe=fFYRT@E|WbNYM`4D6*1pF#P<~=ZHu^T-r6f z2u;PoBa{mEDXF+qOa|71sve<4q}Z-(VknY;ZKTxYNz~PKNPRD_1!P~h%3i&S)&?&I z?XQuVMZuPqK%P9^=nQ3}oJ4s+af>)$t!HY-qg91{PWY3$aOxVPg^;^0*A1Y0FG0;Z z*iP1^VQ<-1r`oCGRQk>8_o!vg-7JQf;p`|@6BvgMgA9t{CP~}oVYI15f~Y4lTq~ju zMptFsyh&a^I_Z=f%YTY4_sDf8zc6_@I$%$w591rA5qLCe0+3CI{=gVR`f6DCWqtpgN0cvLR^DALa6mZ8Z6m zaGS$>_3oB2E%0JIH&5@mnI|sac#fy{cy|8jaT(h`b?EYq%oCF%%NXm%h=1nrawYrF z8-W9FRGfF=6rbVby@T)2XX>E~pNL&ehl~#|d?I$(9WpM$@QIChmW}Kz!$mdt5tGkP zo2EO6&8okuy)XTlf<8R{?SD)=WEFKBkymRkNeA=6HG-6-RcHa=r&igD8JpSxyb)A| z(opCm!D4f#@Ir?I-IEXvr50(|HoBpIp57YmhGA`*fyRoIF}vVM#NQ(tvEKbH3UUh4zkW9N zJ0_dEDh@M0U2+=jc@+vv*1%nXF@<$-)O25g6zSt!&)O+arM^uED0i0Lf#e*6m%;#c zTEWS!pwYVl3$%6(o7!+y zh|5*6JArgLKxZDfJ{@%av6rmrEnB&I`Nmbm^e-m2##d-!ZVIE(iRZqEucDOqI@z-7 zT%9@#G(x5LsIGX(+EoZaA|4?e|NA-xqlate^pem`+8uT4oZx6^SektNsOct4jPWHe zCg2|hdWaD+hvgr@_Z3GWTJEYOn12rDt zO5bR8j^svvl^i_;oMeEspT-z9%_+8%w|Gn!k|Z}##aen#Rk-Dn`KDSiX%|LABit>& zzjr;nFA*D#djW?X*hKzfNVlm@pP5La5mejlM%`E|b4xpmrTORs#t~=Za;F}lta`)I z%Ht~1uR}lCs#$yI`O%ly0Nax!qg@5(sET-3-sOc%4tBe2Fziu*+8>DE8O2}cQ<*#k z{n@}rt2R`6!9rx2q+iz7>qr7U(9<|!V#bA4YO`M-j!u*@5wC8yj)DsDcqP)Dn-z_q zK1w%&duzg^7Uy12*Q9&F?4viJfhxN}PMSfCG0dbtMf3j~xGR+mPwvE0fNREeKwES5 zMM(HZ6M_^sNZ1sB+ujkM3^@2lzt{1b~f*I@I<(D%$8(V5SXQN?)9?pCKRse>R2yTauX zbFj9n%6PCCyD`SqNJUghyugdr^E!)0E#9VIz+m`0ZnNA zX4&DyYp2DPs_JdN9v@zAwcAR^6E80!s7PrnF4U&+cpSR7Y5Sz7>DoWCr4wD_s?K?%1hg&aVc20%MXz+NB%C1TQuf#M!1D39W zW)bo`8~2OAQ2ef0CL!!Igk6mE)EUCI#lu2BSR|$_nrb+dtkqPqPrkHiD2IS!j%wc& zl_;~4h|0o#e%TR+>K9fd4UdwE2DA$AjH*YKK;*0X@G4SIWbaP$_85vR3|`teZd#Rx z<*G_1w42STR4`CFOQekfFnq%;^o*@kN4gf%?~?ia0(Eh|8wF916#F$R`0K1<2e=hJKyOCMCnI26~NGfi>`wH!0q2tH2i# zt+OtP&4p!p6{rM?YY`N*rEh}8+DKT9cXeh3M>$X)L%aU4Ldj6`EEPmKC=&w3G9fZb zJxDI|=k=aQW29A)Hw9${aEg+=Te8qk4-7!&0Nmn#YJ@_Rj(Z(INHsi-bgRUQsp#1Z z5@G=VCgZ1mQJ0@&<{I0~piMP4hEaI2d`t5^vTX2 zZ#3~yk-UWgrwfGM_nt}kpvv@Hyn#WLND+lgj^Y<)v*PB+1O(P+{IoVf%7%;=4-qt$ zJ-wQAAqS9^cZpsDAR1-JhEdCK+*Z;iVPH6t3Nuu-tuSMQ@@>YvQHJF@s7gn4rxVx0 zPCuouPN8v+el&_ny7Emoo1HbX)5%pLDuzx&%68nRELy5uZcWcsup@0XD>>>=eM#bQ zUA<>P2w+dz^cEPrSf1&9l9m+j)P<@gdqHSNz07SfPG)nHknREltCYQw z7QwM>J?IvFi`+9RfIJpzyD`1vkw(H!sJvKEqnte5l hN0uEFI^nWmO2ml2hlDXTI{N=kzj65gUYmOB{{u1^;adOz literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_pl.ts b/src/lang/qbittorrent_pl.ts new file mode 100644 index 000000000..d06c649ed --- /dev/null +++ b/src/lang/qbittorrent_pl.ts @@ -0,0 +1,5629 @@ + + + + + AboutDlg + + About qBittorrent + O qBittorrent + + + About + O programie + + + Author + Autor + + + Name: + Imię i nazwisko: + + + Country: + Kraj: + + + E-mail: + E-mail: + + + Christophe Dumez + Christophe Dumez + + + France + Francja + + + Translation + Lokalizacja + + + License + Licencja + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + chris@qbittorrent.org + chris@qbittorrent.org + + + Thanks to + Podziękowania dla + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Klient sieci bittorrent napisany w języku C++, wykorzystuje biblioteki Qt4</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">i libtorrent-rasterbar.<br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Strona domowa:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Zaawansowany klient sieci bittorrent napisany w języku C++, z wykorzystaniem biblioteki Qt4 i libtorrent-rasterbar.<br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Strona domowa:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + AdvancedSettings + + Property + Parametr + + + Value + Wartość + + + Ignore transfer limits on local network + Ignoruj limity prędkości w sieci lokalnej + + + Include TCP/IP overhead in transfer limits + Ignoruj narzuty protokołu TCP/IP w limitach prędkości + + + Disk write cache size + ? + Rozmiar pamięci podręcznej na dysku + + + MiB + MiB + + + Outgoing ports (Min) [0: Disabled] + Port wychodzący (Min) [0: wyłączony] + + + Outgoing ports (Max) [0: Disabled] + Port wychodzący (Max) [0: wyłączony] + + + Recheck torrents on completion + Sprawdzaj dane po pobraniu + + + Transfer list refresh interval + Częstotliwość odświeżania listy transferów + + + ms + milliseconds + ms + + + Resolve peer countries (GeoIP) + Odczytuj kraje partnerów (GeoIP) + + + Resolve peer host names + Odczytuj nazwy hostów partnerów + + + Maximum number of half-open connections [0: Disabled] + Limit pół-otwartych połączeń [0: Bez limitu] + + + Strict super seeding + Wyłącznie 'super seed' + + + Network Interface (requires restart) + Interfejs sieciowy (wymaga ponownego uruchomienia) + + + Any interface + i.e. Any network interface + Dowolny interfejs + + + Display program notification balloons + Wyświetlaj powiadomienia w dymkach + + + Enable embedded tracker + Włącz wbudowany tracker + + + Embedded tracker port + Port wbudowanego trackera + + + Check for software updates + Sprawdzaj aktualizacje programu + + + Use system icon theme + Używaj systemowego zestawu ikon + + + Confirm torrent deletion + Potwierdzaj usuwanie torrenta + + + IP Address to report to trackers (requires restart) + Adres IP zgłaszany trackerom (wymaga ponownego uruchomienia) + + + Setting + Ustawienie + + + Value + Value set for this setting + Wartość + + + Display program on-screen notifications + Wyświetlaj powiadomienia na ekranie + + + Exchange trackers with other peers + + + + + AutomatedRssDownloader + + Automated RSS Downloader + Automatyczne pobieranie z RSS + + + Enable the automated RSS downloader + Włącz automatyczne pobieranie + + + Download rules + Reguły pobierania + + + Rule definition + Definicja reguły + + + Must contain: + Musi zawierać: + + + Must not contain: + Nie może zawierać: + + + Save torrent to: + Zapisz torrent do: + + + ... + ... + + + Assign label: + Przypisz etykietę: + + + Apply rule to feeds: + Zastosuj regułę do kanałów: + + + Matching RSS articles + Pasujące wpisy RSS + + + Save to a different directory + Pobierz do innego katalogu + + + Save to: + Pobierz do: + + + Import... + Importuj... + + + Export... + Eksportuj... + + + New rule name + Nazwa nowej reguły + + + Please type the name of the new download rule. + Wprowadź nazwę dla tworzonej reguły. + + + Rule name conflict + Konflikt nazw reguł + + + A rule with this name already exists, please choose another name. + Reguła o wybranej nazwie już istnieje, należy wybrać inną. + + + Are you sure you want to remove the download rule named %1? + Czy na pewno usunąć regułę pobierania o nazwie: %1? + + + Are you sure you want to remove the selected download rules? + Czy na pewno usunąć wybrane reguły pobierania? + + + Rule deletion confirmation + Usuwanie reguły + + + Destination directory + Wybierz katalog docelowy + + + Invalid action + Nieprawidłowa operacja + + + The list is empty, there is nothing to export. + wtf? + Lista jest pusta, nie ma czego eksportować. + + + Where would you like to save the list? + Wskaż położenie pliku gdzie zostanie wyeksportowana lista + + + Rules list (*.rssrules) + Lista reguł (*.rssrules) + + + I/O Error + Błąd We/Wy + + + Failed to create the destination file + Błąd podczas tworzenia pliku docelowego + + + Please point to the RSS download rules file + Wskaż położenie pliku reguł do zaimportowania + + + Rules list (*.rssrules *.filters) + Lista reguł (*.rssrules *.filters) + + + Import Error + Błąd podczas importowania + + + Failed to import the selected rules file + Nie udało się zaimportować wybranego pliku reguł + + + Add new rule... + Dodaj nową... + + + Delete rule + Usuń + + + Rename rule... + Zmień nazwę... + + + Delete selected rules + Usuń wybrane + + + Rule renaming + Zmiana nazwy + + + Please type the new rule name + Podaj nową nazwę reguły + + + Use regular expressions + Używaj wyrażeń regularnych + + + Regex mode: use Perl-like regular expressions + Tryb regex: używaj wyrażeń regularnych w stylu Perl + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Tryb wzorca: można użyć <ul><li>? dla dowolnego pojedynczego znaku</li><li>* dla dowolnej ilości znaków</li><li>Białe znaki są traktowane jako operatory AND</li></ul> + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Tryb wzorca: można użyć <ul><li>? dla dowolnego pojedynczego znaku</li><li>* dla dowolnej ilości znaków</li><li>Białe znaki są traktowane jako operatory OR</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 osiagnął ustawiony przez ciebie współczynnik udziału. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent jest połączony przez port: TCP/%1 + + + UPnP support [ON] + Wsparcie UPnP [WŁ] + + + UPnP support [OFF] + Wsparcie UPnP [WYŁ] + + + NAT-PMP support [ON] + Wsparcie NAT-PMP [WŁ] + + + NAT-PMP support [OFF] + Wsparcie NAT-PMP [WYŁ] + + + DHT support [ON], port: UDP/%1 + Wsparcie DHT [WŁ], port: UDP/%1 + + + DHT support [OFF] + Wsparcie DHT [WYŁ] + + + PeX support [ON] + Wsparcie PeX [WŁ] + + + Local Peer Discovery [ON] + Wyszukiwanie partnerów lokalnych [WŁ] + + + Local Peer Discovery support [OFF] + Wyszukiwanie partnerów lokalnych [WYŁ] + + + Encryption support [ON] + Wsparcie szyfrowania [WŁ] + + + Encryption support [FORCED] + Wsparcie szyfrowania [WYMUSZONE] + + + Encryption support [OFF] + Wsparcie szyfrowania [WYŁ] + + + Web User Interface Error - Unable to bind Web UI to port %1 + Błąd interfejsu www - Nie można uruchomić interefejsu www na porcie %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' usunięto z listy transferów i twardego dysku. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' usunięto z listy transferów. + + + '%1' is not a valid magnet URI. + '%1' jest niepoprawnym adresem magnet. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' jest już na liście pobierania. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' wznowiony. (szybkie wznawianie) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' dodano do listy pobierania. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Nie można odczytać pliku torrent: '%1' + + + This file is either corrupted or this isn't a torrent. + Plik jest uszkodzony lub nie jest plikiem torrent. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>zablokowany przez filtr IP</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>zablokowany z powodu uszkodzonych części</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekursywne pobieranie pliku %1 osadzonego w pliku torrent %2 + + + Unable to decode %1 torrent file. + Nie można odczytać pliku torrent: '%1'. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Błąd mapowania portu, wiadomość %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Udane mapowanie portu, wiadomość %1 + + + Fast resume data was rejected for torrent %1, checking again... + Szybkie wznowienie danych zostało odrzucone przez torrent %1, ponowne sprawdzanie... + + + Url seed lookup failed for url: %1, message: %2 + Błąd wyszukiwania url partnera dla adresu:%1, wiadomość: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Pobieranie '%1', proszę czekać... + + + Using a disk cache size of %1 MiB + Rozmiar pamięci podręcznej na dysku wynosi %1 MiB + + + PeX support [OFF] + Wsparcie PeX [WYŁ] + + + Restart is required to toggle PeX support + Zmiana statusu PeX wymaga ponownego uruchomienia + + + The Web UI is listening on port %1 + Interfejs www nasłuchuje na porcie: %1 + + + HTTP user agent is %1 + HTTP user agent: %1 + + + Reason: %1 + Powód: %1 + + + Note: new trackers were added to the existing torrent. + Uwaga: nowe trackery zostały dodane do istniejącego torrenta. + + + Note: new URL seeds were added to the existing torrent. + Uwaga: nowe URL seedów zostały dodane do istniejącego torrenta. + + + An I/O error occured, '%1' paused. + Wystąpił błąd We/Wy, '%1' wstrzymany. + + + Removing torrent %1... + Usuwanie torrenta %1... + + + Pausing torrent %1... + Wstrzymywanie torrenta %1... + + + Error: The torrent %1 does not contain any file. + Błąd: Torrent %1 nie zawiera żadnego pliku. + + + File sizes mismatch for torrent %1, pausing it. + Błędny razmiar pliku z torrenta %1, wstrzymuję pobieranie. + + + + ConsoleDlg + + General + Główne + + + Blocked IPs + Zablokowane IP + + + qBittorrent log viewer + Przeglądarka dziennika qBittorrent + + + + CookiesDlg + + Cookies management + Zarządzanie ciasteczkami + + + Key + As in Key/Value pair + Klucz + + + Value + As in Key/Value pair + Wartość + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Zwykle klucze dla ciasteczek mają format: '%1', '%2'. +Informacje te powinny zostać pobrane z ustawień przeglądarki internetowej. + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + Pomyślnie zaktualizowano dynamiczny DNS. + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Błąd dynamicznego DNS: Usługa tymczasowo niedostępna, ponowienie za 30 minut. + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Błąd dynamicznego DNS: Wskazane konto nie zawiera podanej nazwy hosta. + + + Dynamic DNS error: Invalid username/password. + Błąd dynamicznego DNS: Nieprawidłowa nazwa użytkownika i/lub hasło. + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Błąd dynamicznego DNS: Usługa dodała program qBittorrent do czarnej listy, proszę zgłosić błąd na stronie http://bugs.qbittorrent.org. + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Błąd dynamicznego DNS: Usługa zwróciła: %1, proszę zgłosić błąd na stronie http://bugs.qbittorrent.org. + + + Dynamic DNS error: Your username was blocked due to abuse. + Błąd dynamicznego DNS: Z powodu nadużycia nazwa użytkownika została zablokowana. + + + Dynamic DNS error: supplied domain name is invalid. + Błąd dynamicznego DNS: Podana nazwa domeny jest nieprawidłowa. + + + Dynamic DNS error: supplied username is too short. + Błąd dynamicznego DNS: Podana nazwa użytkownika jest zbyt krótka. + + + Dynamic DNS error: supplied password is too short. + Błąd dynamicznego DNS: Podane hasło jest zbyt krótkie. + + + + DownloadThread + + I/O Error + Błąd We/Wy + + + The remote host name was not found (invalid hostname) + Nie odnaleziono nazwy zdalnego hosta (nieprawidłowa nazwa hosta) + + + The operation was canceled + Operacja została anulowana + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Zdalny serwer przedwcześnie zakończył połączenie, zanim otrzymano i przetworzono odpowiedź + + + The connection to the remote server timed out + Przekroczono czas oczekiwania na połącznie ze zdalnym serwerem + + + SSL/TLS handshake failed + Niepomyślna próba negocjacji połączenie SSL/TLS + + + The remote server refused the connection + Zdalny serwer odrzucił połączenie + + + The connection to the proxy server was refused + Połączenie z serwerem proxy zostało odrzucone + + + The proxy server closed the connection prematurely + Serwer proxy przedwcześnie zakończył połączenie + + + The proxy host name was not found + Nie znaleziono nazwy hosta serwera proxy + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Przkroczono czas oczekiwania na połączenie z serwerm proxy lub serwer nie odpowiedział na czas + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Serwer proxy wymaga uwierzytelnienia aby zaakceptować żądanie lecz oferowane dane uwierzytelnienia zostały odrzucone + + + The access to the remote content was denied (401) + Odmówiono dostępu do zdalnego zasobu (401) + + + The operation requested on the remote content is not permitted + Żądana operacja na zdalnym zasobie nie jest dozwolona + + + The remote content was not found at the server (404) + Nie znaleziono zdalnego zasobu na serwerze (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Zdalny serwer wymaga uwierzytelnienia w celu dostępu do zasobu lecz dane uwierzytelniające nie zostały zaakceptowane + + + The Network Access API cannot honor the request because the protocol is not known + + + + The requested operation is invalid for this protocol + + + + An unknown network-related error was detected + + + + An unknown proxy-related error was detected + + + + An unknown error related to the remote content was detected + + + + A breakdown in protocol was detected + + + + Unknown error + Nieznany błąd + + + + EventManager + + %1/s + e.g. 120 KiB/s + %1/s + + + Working + Działa + + + Updating... + Aktualizowanie... + + + Not working + Nie działa + + + Not contacted yet + Niesprawdzony + + + this session + w tej sesji + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Rozsiewany przez %1 + + + %1 max + e.g. 10 max + max %1 + + + + ExecutionLog + + Form + Formularz + + + General + Główny + + + Blocked IPs + Zablokowane IP + + + + FeedDownloader + + RSS Feed downloader + Pobieranie z kanałów RSS + + + RSS feed: + Kanał RSS: + + + Feed name + Nazwa kanału + + + Automatically download torrents from this feed + Automatyczne pobieranie plików torrent z tego kanału + + + Download filters + Filtry pobierania + + + Filters: + Filtry: + + + Filter settings + Ustawienia filtra + + + Matches: + Zgodne: + + + Does not match: + Niezgodne: + + + Destination folder: + Katalog docelowy: + + + ... + ... + + + Filter testing + Testowanie filtra + + + Torrent title: + Tytuł torrenta: + + + Result: + Wynik: + + + Test + Testuj + + + Import... + Importuj... + + + Export... + Eksportuj... + + + Rename filter + Zmień nazwę filtra + + + Remove filter + Usuń filtr + + + Add filter + Dodaj filtr + + + + FeedDownloaderDlg + + New filter + Nowy filtr + + + Please choose a name for this filter + Należy podać nazwę dla tego filtra + + + Filter name: + Nazwa filtra: + + + Invalid filter name + Nieprawidłowa nazwa filtra + + + The filter name cannot be left empty. + Nazwa filtra nie może być pusta. + + + This filter name is already in use. + Taka nazwa filtra już istnieje. + + + Filter testing error + Błąd testowania filtra + + + Please specify a test torrent name. + Należy podać nazwę torrenta do przetestowania. + + + matches + pasuje + + + does not match + nie pasuje + + + Select file to import + Należy wybrać plik do zaimportowania + + + Filters Files + Pliki filtrów + + + Import successful + Udane importowanie + + + Filters import was successful. + Pomyślnie zaimportowano filtry. + + + Import failure + Błąd importowania + + + Filters could not be imported due to an I/O error. + Nieudane importowanie filtrów z powodu błędu We/Wy. + + + Select destination file + Należy wybrać plik docelowy + + + Export successful + Pomyślne eksportowanie + + + Filters export was successful. + Pomyślnie wyeksportowano fitry. + + + Export failure + Błąd eksportowania + + + Filters could not be exported due to an I/O error. + Nieudane eksportowanie filtrów z powodu błędu We/Wy. + + + Choose save path + Wybierz katalog docelowy + + + + FeedList + + Unread + Nieprzeczytane + + + + FeedListWidget + + RSS feeds + Kanały RSS + + + Unread + Nieprzeczytane + + + + GUI + + Open Torrent Files + Otwórz pliki Torrent + + + Torrent Files + Pliki Torrent + + + qBittorrent + qBittorrent + + + Transfers + Transfery + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Prędkość DL: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Prędkość UP: %1 KiB/ + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 został pobrany. + + + I/O Error + i.e: Input/Output Error + Błąd We/Wy + + + Search + Szukaj + + + RSS + RSS + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Wystąpił błąd We/Wy dla pliku torrent %1. +Powód: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Błąd pobierania adresu + + + Couldn't download file at url: %1, reason: %2. + Nie można pobrać pliku z url: %1, powód: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Options were saved successfully. + Ustawienia pomyślnie zapisane. + + + Download completion + Zakończenie pobierania + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Aktualnie trwa pobieranie plików. +Czy napewno zamknąć qBittorrent? + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Ogólny limit wysyłania + + + Global Download Speed Limit + Ogólny limit pobierania + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Pobieranie: %2/s, Wysyłanie: %3/s) + + + Recursive download confirmation + ?? + Potwierdzenie pobierania rekursywnego + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent %1 zawiera pliki torrent, rozpocząć ich pobieranie? + + + Transfers (%1) + Transfery (%1) + + + Torrent file association + Powiązanie z plikami torrent + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent nie jest domyślnym programem do obsługi plików torrent i linków Magnet. +Czy powiązać qBittorrent z plikami torrent i linkami Magnet? + + + Yes + Tak + + + No + Nie + + + Never + Nigdy + + + Always + Zawsze + + + Exiting qBittorrent + Zamykanie qBittorrent + + + Set the password... + Ustaw hasło... + + + Password update + Aktualizacja hasła + + + Invalid password + Nieprawidłowe hasło + + + The password is invalid + Podane hasło jest nieprawidłowe + + + A newer version is available + Dostępna jest nowa wersja + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Nowa wersja qBittorrenta jest dostępna na Sourceforge. +Czy chcesz zaktualizować program do wersji %1? + + + Impossible to update qBittorrent + Nie można zaktualizować qBittorrenta + + + qBittorrent failed to update, reason: %1 + Aktualizacja qBittorrenta nie powiodła się, powód: %1 + + + + GeoIP + + Australia + Australia + + + Argentina + Argentyna + + + Austria + Austria + + + United Arab Emirates + Zjednoczone Emiraty Arabskie + + + Brazil + Brazylia + + + Bulgaria + Bułgaria + + + Belarus + Białoruś + + + Belgium + Belgia + + + Bosnia + Bośnia + + + Canada + Kanada + + + Czech Republic + Czechy + + + China + Chiny + + + Costa Rica + Kostaryka + + + Switzerland + Szwajcaria + + + Germany + Niemcy + + + Denmark + Dania + + + Algeria + Algeria + + + Spain + Hiszpania + + + Egypt + Egipt + + + Finland + Finlandia + + + France + Francja + + + United Kingdom + Wielka Brytania + + + Greece + Grecja + + + Georgia + Gruzja + + + Hungary + Węgry + + + Croatia + Chorwacja + + + Italy + Włochy + + + India + Indie + + + Israel + Izrael + + + Ireland + Irlandia + + + Iceland + Islandia + + + Indonesia + Indonezja + + + Japan + Japonia + + + South Korea + Korea Południowa + + + Luxembourg + Luksemburg + + + Malaysia + Malezja + + + Mexico + Meksyk + + + Serbia + Serbia + + + Morocco + Maroko + + + Netherlands + Holandia + + + Norway + Norwegia + + + New Zealand + Nowa Zelandia + + + Portugal + Portugalia + + + Poland + Polska + + + Pakistan + Pakistan + + + Philippines + Filipiny + + + Russia + Rosja + + + Romania + Rumunia + + + France (Reunion Island) + Francja + + + Sweden + Szwecja + + + Slovakia + Słowacja + + + Singapore + Singapur + + + Slovenia + Słowenia + + + Taiwan + Tajwan + + + Turkey + Turcja + + + Thailand + Tajlandia + + + USA + Stany Zjednoczone + + + Ukraine + Ukraina + + + South Africa + Republika Południowej Afryki + + + Saudi Arabia + Arabia Saudyjska + + + + HeadlessLoader + + Information + Informacje + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Aby uzyskać dostęp do qBittorrent należy przejść w przeglądarce pod adres http://localhost:%1 + + + The Web UI administrator user name is: %1 + Nazwa administratora interfejsu www to: %1 + + + The Web UI administrator password is still the default one: %1 + Hasło administratora interfejsu www ustawione nadal na domyślne: %1 + + + This is a security risk, please consider changing your password from program preferences. + Uwaga, z powodu bezpieczeństwa należy rozważyć zmianę hasła w ustawieniach programu. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + Twój adres IP został zablokowany po zbyt wielu nieudanych próbach uwierzytelnienia. + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Pobieranie: %1/s - Pobrano: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Wysyłanie: %1/s - Wysłano: %2 + + + + HttpServer + + File + Plik + + + Edit + Edycja + + + Help + Pomoc + + + Delete from HD + Usuń z dysku twardego + + + Download Torrents from their URL or Magnet link + Pobierz pliki torrent z adresu www lub magnet + + + Only one link per line + Można podać tylko jeden adres www w jednej linii + + + Download + Pobierz + + + Download local torrent + Pobierz pliki torrent z dysku twardego + + + Torrent files were correctly added to download list. + Pliki torrent poprawnie dodane do listy pobierania. + + + Point to torrent file + Ścieżka do pliku torrent + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Czy na pewno usunąć wybrane pliki torrent z listy transferów i z twardego dysku? + + + Download rate limit must be greater than 0 or disabled. + Limit prędkości pobierania musi być większy od 0 lub wyłączony. + + + Upload rate limit must be greater than 0 or disabled. + Limit prędkości wysyłania musi być większy od 0 lub wyłączony. + + + Maximum number of connections limit must be greater than 0 or disabled. + Limit połączeń musi być większy od 0 lub wyłączony. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Limit połączeń dla pliku torrent musi być większy od 0 lub wyłączony. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Limit slotów wysyłania dla pliku torrent musi być większy od 0 lub wyłączony. + + + Unable to save program preferences, qBittorrent is probably unreachable. + Nie można zapisać ustawień, prawdopodobnie qBittorrent jest nieosiągalny. + + + Language + Język + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Port na którym nasłuchiwane są połączenia przychodzące musi zawierać się w zakresie 1024 - 65535. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Port na którym działa interfejs www musi zawierać się w zakresie 1024 - 65535. + + + The Web UI username must be at least 3 characters long. + Nazwa użytkownika interfejsu www musi składać się z co najmniej 3 znaków. + + + The Web UI password must be at least 3 characters long. + Hasło użytkownika interfejsu www musi składać się z co najmniej 3 znaków. + + + Downloaded + Is the file downloaded or not? + Pobrany + + + Save + Zapisz + + + qBittorrent client is not reachable + Klient qBittorrent jest nieosiągalny + + + HTTP Server + Serwer www + + + Torrent path + Ścieżka torrenta + + + Torrent name + Nazwa torrenta + + + The following parameters are supported: + Obsługiwane są poniższe parametry: + + + + LegalNotice + + Legal Notice + Nota prawna + + + Legal notice + Nota prawna + + + Cancel + Anuluj + + + I Agree + Zgadzam się + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent jest programem do wymiany plików. Uruchomienie torrenta powoduje, że jego zawartość jest dostępna dla innych. Użytkownik ponosi pełną odpowiedzialność za udostępniane treści. + +W przyszłości powiadomienie nie będzie wyświetlane. + + + Press %1 key to accept and continue... + Nacisnij klawisz %1 aby zaakceptować i kontynuować... + + + + LineEdit + + Clear the text + Wyczyść tekst + + + + MainWindow + + &Edit + &Edycja + + + &File + P&lik + + + &Help + &Pomoc + + + Preview file + Podgląd pliku + + + Clear log + Wyczyść dziennik + + + Decrease priority + Zmniejsz priorytet + + + Increase priority + Zwiększ priorytet + + + &Tools + &Narzędzia + + + &View + &Widok + + + &Add File... + &Otwórz plik... + + + E&xit + &Zakończ + + + &Options... + &Opcje... + + + Add &URL... + Dodaj &URL... + + + Torrent &creator + Kreator plików torre&nt + + + Set upload limit... + Ustaw limit wysyłania... + + + Set download limit... + Ustaw limit pobierania... + + + Set global download limit... + Ustaw ogólny limit pobierania... + + + Set global upload limit... + Ustaw ogólny limit wysyłania... + + + &Log viewer... + Przeg&lądanie dziennika... + + + Top &tool bar + &Górny pasek narzędziowy + + + Display top tool bar + Pokaż górny pasek narzędziowy + + + &Speed in title bar + &Prędkość na pasku tytułu + + + Show transfer speed in title bar + Pokaż prędkość na pasku tytułu + + + Alternative speed limits + Alternatywne limity prędkości + + + &About + &O programie + + + &Pause + &Wstrzymaj + + + &Delete + U&suń + + + P&ause All + Ws&trzymaj wszystkie + + + Visit &Website + Od&wiedź stronę + + + Report a &bug + Zgłoś &błąd + + + &Documentation + &Dokumentacja + + + &RSS reader + Czytnik &RSS + + + Search &engine + Wy&szukiwarka + + + Log viewer + Przeglądarka dziennika + + + Lock qBittorrent + Zablokuj qBittorrent + + + Ctrl+L + Ctrl+L + + + Shutdown computer when downloads complete + Wyłącz komputer po zakończeniu pobierań + + + &Resume + W&znów + + + R&esume All + Wznów wszystki&e + + + Shutdown qBittorrent when downloads complete + Zamknij qBittorrent po zakończeniu pobierań + + + Exit + Zakończ + + + Import torrent... + Importuj plik... + + + Donate money + Przekaż pieniądze + + + If you like qBittorrent, please donate! + Jeśli lubisz qBittorrent, przekaż pieniądze! + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + Ustaw hasło... + + + Transfers + Transfery + + + Torrent file association + Powiązanie z plikami torrent + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent nie jest domyślnym programem do obsługi plików torrent i linków Magnet. +Czy powiązać qBittorrent z plikami torrent i linkami Magnet? + + + UI lock password + Hasło blokady interfejsu + + + Please type the UI lock password: + Proszę podać hasło blokady interfejsu: + + + Password update + Aktualizacja hasła + + + The UI lock password has been successfully updated + Pomyślnie zaktualizowano hasło blokady interfejsu + + + RSS + RSS + + + Search + Szukaj + + + Transfers (%1) + Transfery (%1) + + + Download completion + Zakończono pobieranie + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 został pobrany. + + + I/O Error + i.e: Input/Output Error + Błąd We/Wy + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Wystąpił błąd We/Wy dla pliku torrent %1. +Powód: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Potwierdzenie pobierania rekurencyjnego + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent %1 zawiera pliki torrent, rozpocząć ich pobieranie? + + + Yes + Tak + + + No + Nie + + + Never + Nigdy + + + Url download error + Błąd pobierania adresu + + + Couldn't download file at url: %1, reason: %2. + Nie można pobrać pliku z url: %1, powód: %2. + + + Global Upload Speed Limit + Ogólny limit wysyłania + + + Global Download Speed Limit + Ogólny limit pobierania + + + Invalid password + Nieprawidłowe hasło + + + The password is invalid + Podane hasło jest nieprawidłowe + + + Exiting qBittorrent + Zamykanie qBittorrent + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Aktualnie trwa pobieranie plików. +Czy na pewno zamknąć qBittorrent? + + + Always + Zawsze + + + Open Torrent Files + Otwórz pliki torrent + + + Torrent Files + Pliki .torrent + + + Options were saved successfully. + Ustawienia pomyślnie zapisane. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Pobieranie: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Wysyłanie: %1 KiB/ + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Pobieranie: %2/s, Wysyłanie: %3/s) + + + A newer version is available + Dostępna jest nowa wersja + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Nowa wersja qBittorrent jest dostępna na Sourceforge. +Czy chcesz zaktualizować program do wersji %1? + + + Impossible to update qBittorrent + Nie można zaktualizować qBittorrent + + + qBittorrent failed to update, reason: %1 + Aktualizacja qBittorrent nie powiodła się, powód: %1 + + + &Add torrent file... + &Otwórz plik torrent... + + + Add &link to torrent... + &Dodaj odnośnik do pliku torrent... + + + Import existing torrent... + Importuj plik torrent... + + + Execution &Log + &Dziennik programu + + + Execution Log + Dziennik programu + + + Auto-Shutdown on downloads completion + Zamykanie po ukończeniu pobierania + + + Exit qBittorrent + Zakończ qBittorrent + + + Suspend system + Wstrzymaj system + + + Shutdown system + Zamknij system + + + Disabled + Wyłączone + + + The password should contain at least 3 characters + Hasło powinno zawierać przynajmniej 3 znaki + + + + PeerAdditionDlg + + Invalid IP + Niepoprawny adres IP + + + The IP you provided is invalid. + Wprowadzony adres IP jest niepoprawny. + + + + PeerListDelegate + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + IP + Adres IP + + + Client + i.e.: Client application + Klient + + + Progress + i.e: % downloaded + Postęp + + + Down Speed + i.e: Download speed + Pobieranie + + + Up Speed + i.e: Upload speed + Wysyłanie + + + Downloaded + i.e: total data downloaded + Pobrano + + + Uploaded + i.e: total data uploaded + Wysłano + + + Ban peer permanently + Blokuj parnera na stałe + + + Peer addition + Dodawanie partnera + + + The peer was added to this torrent. + Dodano partnera dla tego torrenta. + + + The peer could not be added to this torrent. + Nie można dodać partnera dla tego torrenta. + + + Are you sure? -- qBittorrent + Czy na pewno? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + Czy na pewno zablokować na stałe wybranych partnerów? + + + &Yes + &Tak + + + &No + &Nie + + + Manually banning peer %1... + Ręczne blokowanie partnera %1... + + + Upload rate limiting + Ograniczanie prędkości wysyłania + + + Download rate limiting + Ograniczanie prędkości pobierania + + + Add a new peer... + Dodaj partnera... + + + Limit download rate... + Ogranicz prędkości pobierania... + + + Limit upload rate... + Ogranicz prędkości wysyłania... + + + Copy IP + Kopiuj adres IP + + + Connection + Połączenie + + + + Preferences + + UI + User Interface + Wygląd + + + Downloads + Pobieranie + + + Connection + Połączenie + + + Bittorrent + Bittorrent + + + Proxy + Proxy + + + Web UI + Interfejs www + + + Language: + Język: + + + (Requires restart) + (Wymaga ponownego uruchomienia) + + + Visual style: + Styl wizualny: + + + Transfer list + Lista transferów + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Alternatywne kolorowanie wierszy + + + File system + Katalogi + + + Torrent queueing + Kolejkowanie torrentów + + + Maximum active downloads: + Maksymalna liczba aktywnych pobierań: + + + Maximum active uploads: + Maksymalna liczba aktywnych wysyłań: + + + Maximum active torrents: + Maksymalna liczba aktywnych torrentów: + + + When adding a torrent + Podczas dodawania torrenta + + + Display torrent content and some options + Pokaż zawartość torrenta i kilka opcji + + + Listening port + Port nasłuchu + + + Port used for incoming connections: + Port dla połączeń przychodzących: + + + Random + Losowy + + + Enable UPnP port mapping + Włącz mapowanie portu UPnP + + + Enable NAT-PMP port mapping + Włącz mapowanie portu NAT-PMP + + + Connections limit + Limit połączeń + + + Global maximum number of connections: + Maksymalna liczba połączeń: + + + Maximum number of connections per torrent: + Maksymalna liczba połączeń na torrent: + + + Maximum number of upload slots per torrent: + Maksymalna liczba slotów wysyłania na torrent: + + + Upload: + Wysyłanie: + + + Download: + Pobieranie: + + + KiB/s + KiB/s + + + Bittorrent features + Ustawienia bittorrent + + + Enable DHT network (decentralized) + Włącz sieć DHT (rozproszona) + + + Use a different port for DHT and Bittorrent + Używa innego portu dla DHT i bittorrent + + + DHT port: + Port DHT: + + + Enable Peer Exchange / PeX (requires restart) + Włącz Peer eXchange / (PeX) (wymaga ponownego uruchomienia) + + + Enable Local Peer Discovery + Włącz Local Peer Discovery + + + Enabled + Włączone + + + Forced + Wymuszone + + + Disabled + Wyłączone + + + Type: + Typ: + + + (None) + (Żaden) + + + HTTP + HTTP + + + Port: + Port: + + + Authentication + Uwierzytelnianie + + + Username: + Nazwa użytkownika: + + + Password: + Hasło: + + + SOCKS5 + SOCKS5 + + + HTTP Server + Serwer www + + + Filter path (.dat, .p2p, .p2b): + Ścieżka do pliku filtra (.dat, .p2p, .p2b): + + + HTTP Communications (trackers, Web seeds, search engine) + Połączenia HTTP (trackery, seedy www, wtyczki wyszukiwania) + + + Host: + Host: + + + Peer Communications + Połączenia z partnerami + + + SOCKS4 + SOCKS4 + + + Speed + Prędkość + + + Global speed limits + Ogólne limity prędkości + + + Alternative global speed limits + Alternatywne ogólne limity prędkości + + + to + time1 to time2 + do + + + Every day + codziennie + + + Week days + dni robocze + + + Week ends + weekendy + + + Advanced + Zaawansowane + + + Copy .torrent files to: + Kopiuj pliki .torrent do: + + + Remove folder + Usuń katalog + + + No action + Nie rób nic + + + Options + Opcje + + + Visual Appearance + Wygląd + + + Action on double-click + Podwójne kliknięcie + + + Downloading torrents: + na liście pobieranych: + + + Start / Stop + Uruchom/Zatrzymaj + + + Open destination folder + Otwórz katalog pobierań + + + Completed torrents: + na liście ukończonych: + + + Desktop + Pulpit + + + Show splash screen on start up + Pokazuj ekran startowy + + + Start qBittorrent minimized + Uruchamiaj qBittorrent zminimalizowany + + + Show qBittorrent icon in notification area + Pokazuj ikonę qBittorrent w obszarze powiadomień + + + Minimize qBittorrent to notification area + Minimalizuj qBittorrent do obszaru powiadomień + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Zamykaj qBittorrent do obszaru powiadomień + + + Do not start the download automatically + The torrent will be added to download list in pause state + Nie uruchamiaj automatycznie pobierań + + + Save files to location: + Domyślny katalog zapisywanych plików: + + + Append the label of the torrent to the save path + Dodaj etykietę torrenta do nazwy katalogu + + + Pre-allocate disk space for all files + Rezerwuj miejsce na dysku dla wszystkich plików + + + Keep incomplete torrents in: + Przechowuj niekompletne torrenty w: + + + Append .!qB extension to incomplete files' names + Dodaj rozszerzenie .!qB do niekompletnych plików + + + Automatically add torrents from: + Automatyczne pobieranie plików torrent z katalogu: + + + Add folder... + Dodaj katalog... + + + IP Filtering + Filtrowanie IP + + + Schedule the use of alternative speed limits + Harmonogram użycia alternatywnych limitów prędkości + + + from + from (time1 to time2) + od + + + When: + kiedy: + + + Look for peers on your local network + Wyszukiwanie partnerów w sieci lokalnej + + + Protocol encryption: + Szyfrowanie protokołu: + + + Enable Web User Interface (Remote control) + Włącz interfejs www (Zdalne zarządzanie) + + + Share ratio limiting + Ograniczenie współczynnika udziału + + + Seed torrents until their ratio reaches + Wysyłaj do czasu aż współczynnik udziału osiągnie + + + then + następnie + + + Pause them + Wstrzymaj + + + Remove them + Usuń + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Wymiana partnerów pomiędzy kompatybilnymi klientami sieci Bittorrent (µTorrent, Vuze, ...) + + + Email notification upon download completion + Wyślij e-mail po ukończeniu pobierania + + + Destination email: + Adres e-mail: + + + SMTP server: + Serwer SMTP: + + + Run an external program on torrent completion + Uruchom zewnętrzny program po ukończeniu pobierania + + + Use %f to pass the torrent path in parameters + Użyj %f w celu przekazania ścieżki torrenta jako parametru + + + Proxy server + Serwer proxy + + + BitTorrent + BitTorrent + + + Start / Stop Torrent + Wznów / Wstrzymaj pobieranie + + + Use UPnP / NAT-PMP port forwarding from my router + Używaj UPnP / NAT-PMP do przekierowania portów na routerze + + + Privacy + Ochrona prywatności + + + Enable DHT (decentralized network) to find more peers + Włącz sieć DHT (sieć rozproszona) w celu odnajdywania partnerów + + + Use a different port for DHT and BitTorrent + Używaj innego portu dla DHT i BitTorrent + + + Enable Peer Exchange (PeX) to find more peers + Włącz wymianę partnerów (PeX) + + + Enable Local Peer Discovery to find more peers + Włącz wykrywanie partnerów w sieci lokalnej (LPD) + + + Encryption mode: + Tryb szyfrowania: + + + Prefer encryption + Preferuj szyfrowanie + + + Require encryption + Wymagaj szyfrowania + + + Disable encryption + Wyłącz szyfrowanie + + + User Interface + Interfejs użytkownika + + + Reload the filter + Przeładuj filtr + + + Behavior + Zachowanie + + + Language + Język + + + Power Management + Zarządzanie energią + + + Inhibit system sleep when torrents are active + Nie pozwalaj na usypianie systemu gdy są aktywne torrenty + + + Bypass authentication for localhost + Pomiń uwierzytelnianie dla lokalnego hosta + + + Ask for program exit confirmation + Pytaj o potwierdzenie przy wyjściu + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Obsługiwane są poniższe parametry: +<ul> +<li>%f: ścieżka torrenta</li> +<li>%n: nazwa torrenta</li> +</ul> + + + Tray icon style: + Styl ikony w obszarze powiadomień: + + + Normal + normalny + + + Monochrome (Dark theme) + monochromatyczny (ciemny motyw) + + + Monochrome (Light theme) + monochromatyczny (jasny motyw) + + + This server requires a secure connection (SSL) + Ten serwer wymaga bezpiecznego połączenia (SSL) + + + User Interface Language: + Język interfejsu: + + + Transfer List + Lista transferów + + + Show qBittorrent in notification area + Pokazuj ikonę qBittorrent w obszarze powiadomień + + + Hard Disk + A może lepiej "Pamięć masowa", odnosi się to do ustawień związanych z miejscem gdzie mają być pobierane dane + Dysk twardy + + + Listening Port + Port nasłuchu + + + Connections Limits + Limit połączeń + + + Proxy Server + Serwer proxy + + + Torrent Queueing + Kolejkowanie torrentów + + + Share Ratio Limiting + Ograniczenie współczynnika udziału + + + Use UPnP / NAT-PMP to forward the port from my router + Używaj UPnP / NAT-PMP do przekierowania portów na routerze + + + Update my dynamic domain name + Aktualizuj nazwę domeny dynamicznej + + + Service: + Usługa: + + + Register + Zarejestruj + + + Domain name: + Nazwa domeny: + + + Global Rate Limits + Ogólne limity prędkości + + + Apply rate limit to uTP connections + Stosuj limity prędkości do połączeń uTP + + + Apply rate limit to transport overhead + Jeszcze nie wiem o co kaman +Stara opcja była: +Ignoruj narzuty protokołu TCP/IP w limitach prędkości + Stosuj limity prędkości do transferów z narzutem + + + Alternative Global Rate Limits + Alternatywne ogólne limity prędkości + + + Schedule the use of alternative rate limits + Harmonogram użycia alternatywnych limitów prędkości + + + Enable bandwidth management (uTP) + Włącz zarządzanie pasmem (uTP) + + + Otherwise, the proxy server is only used for tracker connections + W przeciwnym razie serwer proxy będzie używany tylko do połączeń z trackerem + + + Use proxy for peer connections + Używaj proxy do połączeń z partnerami + + + Append .!qB extension to incomplete files + Dodaj rozszerzenie .!qB do niekompletnych plików + + + Use HTTPS instead of HTTP + Używaj HTTPS zamiast HTTP + + + Import SSL Certificate + Importuj certyfikat SSL + + + Import SSL Key + Importuj klucz SSL + + + Certificate: + Certyfikat: + + + Key: + Klucz: + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Informacja na temat certyfikatów</a> + + + + PreviewSelect + + Name + Nazwa + + + Size + Rozmiar + + + Progress + Postęp + + + Preview impossible + Nie ma możliwości podglądu + + + Sorry, we can't preview this file + Przepraszamy, podgląd pliku jest niedostępny + + + + ProgramUpdater + + Could not create the file %1 + Nie można utworzyć pliku %1 + + + Failed to download the update at %1 + %1 is an URL + Nie można pobrać aktualizacji z %1 + + + + PropListDelegate + + Normal + Normal (priority) + Normalny + + + High + High (priority) + Wysoki + + + Maximum + Maximum (priority) + Maksymalny + + + Not downloaded + Nie pobierany + + + Mixed + Mixed (priorities + Różne + + + + PropTabBar + + General + Główne + + + Trackers + Trackery + + + Peers + Partnerzy + + + URL Seeds + Seedy www + + + Files + Pliki + + + HTTP Sources + Źródła HTTP + + + Content + Zawartość + + + + PropertiesWidget + + Save path: + Katalog docelowy: + + + Torrent hash: + Hash torrenta: + + + Comment: + Komentarz: + + + Share ratio: + Współczynnik udziału: + + + General + Główne + + + Trackers + Trackery + + + URL seeds + Seedy www + + + Files + Pliki + + + Priority + Priorytet + + + New url seed + New HTTP source + Nowy adres seeda + + + New url seed: + Nowy URL seeda: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + Ten URL seeda już jest na liście. + + + Choose save path + Wybierz katalog docelowy + + + Save path creation error + Błąd tworzenia katalogu docelowego + + + Could not create the save path + Nie można założyć katalogu docelowego + + + Downloaded: + Pobrano: + + + Transfer + Transfer + + + Uploaded: + Wysłano: + + + Wasted: + Odrzucono: + + + UP limit: + Limit wysyłania: + + + DL limit: + Limit pobierania: + + + Time elapsed: + Czas działania: + + + Connections: + Połączeń: + + + Information + Informacje + + + Created on: + Utworzono: + + + Peers + Partnerzy + + + Normal + Normalny + + + Maximum + Maksymalny + + + High + Wysoki + + + this session + w tej sesji + + + %1 max + e.g. 10 max + max %1 + + + Availability: + Dostępność: + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + rozsiewany przez: %1 + + + Rename... + Zmień nazwę... + + + New name: + Nowa nazwa: + + + The file could not be renamed + Nie można zmienić nazwy pliku + + + This name is already in use in this folder. Please use a different name. + Wybrana nazwa jest już używana w tym katalogu. Proszę wybrać inną nazwę. + + + The folder could not be renamed + Nie można zmienić nazwy katalogu + + + Rename the file + Zmień nazwę pliku + + + This file name contains forbidden characters, please choose a different one. + Nazwa pliku zawiera zabronione znaki, proszę wybrać inną nazwę. + + + I/O Error + Błąd We/Wy + + + This file does not exist yet. + Plik jeszcze nie istnieje. + + + This folder does not exist yet. + Katalog jeszcze nie istnieje. + + + Reannounce in: + Sprawdzanie trackera za: + + + Select All + Zaznacz wszystko + + + Select None + Odznacz wszystko + + + Do not download + Nie pobieraj + + + Pieces size: + Rozmiar części: + + + Time active: + Time (duration) the torrent is active (not paused) + Pobierany przez: + + + Torrent content: + Zawartość torrenta: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1 osiagnął ustawiony przez ciebie współczynnik udziału. + + + Removing torrent %1... + Usuwanie torrenta %1... + + + Pausing torrent %1... + Wstrzymywanie torrenta %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent jest połączony przez port: TCP/%1 + + + UPnP support [ON] + Wsparcie UPnP [WŁ] + + + UPnP support [OFF] + Wsparcie UPnP [WYŁ] + + + NAT-PMP support [ON] + Wsparcie NAT-PMP [WŁ] + + + NAT-PMP support [OFF] + Wsparcie NAT-PMP [WYŁ] + + + HTTP user agent is %1 + HTTP user agent: %1 + + + Using a disk cache size of %1 MiB + Rozmiar pamięci podręcznej na dysku wynosi %1 MiB + + + DHT support [ON], port: UDP/%1 + Wsparcie DHT [WŁ], port: UDP/%1 + + + DHT support [OFF] + Wsparcie DHT [WYŁ] + + + PeX support [ON] + Wsparcie PeX [WŁ] + + + PeX support [OFF] + Wsparcie PeX [WYŁ] + + + Restart is required to toggle PeX support + Zmiana statusu PeX wymaga ponownego uruchomienia + + + Local Peer Discovery [ON] + Wyszukiwanie partnerów lokalnych [WŁ] + + + Local Peer Discovery support [OFF] + Wyszukiwanie partnerów lokalnych [WYŁ] + + + Encryption support [ON] + Wsparcie szyfrowania [WŁ] + + + Encryption support [FORCED] + Wsparcie szyfrowania [WYMUSZONE] + + + Encryption support [OFF] + Wsparcie szyfrowania [WYŁ] + + + Embedded Tracker [ON] + Wbudowany tracker [WŁ] + + + Failed to start the embedded tracker! + Nie udało się uruchomić wbudowanego trackera! + + + Embedded Tracker [OFF] + Wbudowany tracker [WYŁ] + + + The Web UI is listening on port %1 + Interfejs www nasłuchuje na porcie: %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Błąd interfejsu www - Nie można uruchomić interefejsu www na porcie %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' usunięto z listy transferów i twardego dysku. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' usunięto z listy transferów. + + + '%1' is not a valid magnet URI. + '%1' jest niepoprawnym adresem magnet. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' jest już na liście pobierania. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' wznowiony. (szybkie wznawianie) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' dodano do listy pobierania. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Nie można otworzyć pliku torrent: '%1' + + + This file is either corrupted or this isn't a torrent. + Plik jest uszkodzony lub nie jest plikiem torrent. + + + Error: The torrent %1 does not contain any file. + Błąd: Torrent %1 nie zawiera żadnego pliku. + + + Note: new trackers were added to the existing torrent. + Uwaga: nowe trackery zostały dodane do istniejącego torrenta. + + + Note: new URL seeds were added to the existing torrent. + Uwaga: nowe URL seedów zostały dodane do istniejącego torrenta. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>zablokowany przez filtr IP</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>zablokowany z powodu uszkodzonych części</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekurencyjne pobieranie pliku %1 osadzonego w pliku torrent %2 + + + Unable to decode %1 torrent file. + Nie można odczytać pliku torrent: '%1'. + + + Torrent name: %1 + Nazwa torrenta: %1 + + + Torrent size: %1 + Rozmiar torrenta: %1 + + + Save path: %1 + Katalog docelowy: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent został pobrany w %1. + + + Thank you for using qBittorrent. + Dziękujemy za używanie qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 został pobrany + + + An I/O error occured, '%1' paused. + Wystąpił błąd We/Wy, '%1' wstrzymany. + + + Reason: %1 + Powód: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Błąd mapowania portu, komunikat %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Udane mapowanie portu, komunikat %1 + + + File sizes mismatch for torrent %1, pausing it. + Błędny razmiar pliku z torrenta %1, wstrzymuję pobieranie. + + + Fast resume data was rejected for torrent %1, checking again... + Szybkie wznowienie pobierania zostało odrzucone dla torrenta %1, ponowne sprawdzanie... + + + Url seed lookup failed for url: %1, message: %2 + Błąd wyszukiwania url partnera dla adresu:%1, komunikat: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Pobieranie '%1', proszę czekać... + + + The network interface defined is invalid: %1 + Podany interfejs sieciowy jest nieprawidłowy: %1 + + + Trying any other network interface available instead. + Testowanie innego interfejsu sieciowego. + + + Listening on IP address %1 on network interface %2... + Nasłuchiwanie na adresie IP %1 interfejsu sieciowego %2... + + + Failed to listen on network interface %1 + Błąd nasłuchiwania na interfejsie %1 + + + UPnP / NAT-PMP support [ON] + Wsparcie UPnP / NAT-PMP [WŁ] + + + UPnP / NAT-PMP support [OFF] + Wsparcie UPnP / NAT-PMP [WYŁ] + + + Local Peer Discovery support [ON] + Wykrywanie partnerów w sieci lokalnej (LPD) [WŁ] + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Pomyślnie przetworzono podany filtr IP: zastosowano %1 reguł. + + + Error: Failed to parse the provided IP filter. + Błąd: Nie udało się przetworzyć podanego filtra IP. + + + Reporting IP address %1 to trackers... + Zgłaszanie trackerom adresu IP %1... + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Komputer zostanie uśpiony jeśli nie anulujesz akcji w ciągu 15 sekund... + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Komputer zostanie wyłączony jeśli nie anulujesz akcji w ciągu 15 sekund... + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + Działanie qBittorrent zostanie zakończone jeśli nie anulujesz akcji w ciągu 15 sekund... + + + + RSS + + Search + Szukaj + + + New subscription + Nowy kanał RSS + + + Mark items read + Zaznacz jako przeczytane + + + Update all + Odśwież wszystkie + + + Feed URL + Adres kanału RSS + + + Update + Odśwież + + + RSS feeds + Kanały RSS + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrenty:</span> <span style=" font-style:italic;">(kliknij dwukrotnie aby pobrać)</span></p></body></html> + + + Article title + Tytuł + + + Update all feeds + Odśwież wszystkie kanały RSS + + + Delete + Usuń + + + Rename + Zmień nazwę + + + Download torrent + Pobierz torrent + + + Open news URL + Otwórz URL wiadomości + + + Copy feed URL + Kopiuj adres kanału RSS + + + Refresh RSS streams + Odśwież kanały RSS + + + Rename... + Zmień nazwę... + + + New subscription... + Nowy kanał RSS... + + + RSS feed downloader... + Pobieranie z kanałów RSS... + + + New folder... + Nowy katalog... + + + Manage cookies... + Zarządzanie ciasteczkami... + + + Settings... + Ustawienia... + + + RSS Downloader... + or something shorter? + Pobieranie z kanałów RSS... + + + + RSSImp + + Please type a rss stream url + Wprowadź URL kanału RSS + + + Stream URL: + Adres URL dla nowego kanału RSS: + + + Are you sure? -- qBittorrent + Czy na pewno? -- qBittorrent + + + &Yes + &Tak + + + &No + &Nie + + + Please choose a folder name + Wprowadź nazwę katalogu + + + Folder name: + Nazwa dla nowego katalogu: + + + New folder + Nowy katalog + + + Overwrite attempt + Próba nadpisania + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Nie mozna nadpisać katalogu %1. + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + Ten kanał RSS już jest na liście. + + + Are you sure you want to delete these elements from the list? + Czy na pewno usunąć wybrane elementy z listy? + + + Are you sure you want to delete this element from the list? + Czy na pewno usunąć wybrany element z listy? + + + Please choose a new name for this RSS feed + Należy podać nową nazwę dla tego kanału RSS + + + New feed name: + Nowa nazwa kanału RSS: + + + Name already in use + Podana nazwa już istnieje + + + This name is already used by another item, please choose another one. + Podana nazwa już istnieje, należy wybrać inną. + + + Date: + Data: + + + Author: + Autor: + + + Unread + Nieprzeczytane + + + + RssArticle + + No description available + Opis niedostępny + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + Automatyczne pobieranie torrenta %1z kanału RSS %2 ... + + + + RssItem + + No description available + Opis niedostępny + + + + RssSettings + + RSS Reader Settings + Ustawienia czytnika RSS + + + RSS feeds refresh interval: + Częstotliwość odświeżania kanałów RSS: + + + minutes + minut + + + Maximum number of articles per feed: + Maksymalna liczba wiadomości na kanał RSS: + + + + RssSettingsDlg + + RSS Reader Settings + Ustawienia czytnika RSS + + + RSS feeds refresh interval: + Częstotliwość odświeżania kanałów: + + + minutes + minut + + + Maximum number of articles per feed: + Maksymalna liczba wiadomości na kanał: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Automatyczne pobieranie torrenta %1z kanału RSS %2 ... + + + + ScanFoldersModel + + Watched Folder + Obserwowany katalog + + + Download here + Pobierz tutaj + + + + SearchCategories + + All categories + Wszystko + + + Movies + Filmy + + + TV shows + Seriale TV + + + Music + Muzyka + + + Games + Gry + + + Anime + Anime + + + Software + Programy + + + Pictures + Obrazki + + + Books + Książki + + + + SearchEngine + + Empty search pattern + Pusty wzorzec wyszukiwania + + + Please type a search pattern first + Proszę podać wzorzec wyszukiwania + + + Results + Wyniki + + + Searching... + Wyszukiwanie... + + + Cut + Wytnij + + + Copy + Kopiuj + + + Paste + Wklej + + + Clear field + Wyczyść pole + + + Clear completion history + Wyczyść historię + + + Search Engine + Wyszukiwarka + + + Search has finished + Wyszukiwanie zakończone + + + An error occured during search... + Wystąpił błąd podczas wyszukiwania... + + + Search aborted + Wyszukiwanie przerwane + + + Search returned no results + Nic nie znaleziono + + + Results + i.e: Search results + Wyniki + + + Unknown + Nieznany + + + Search + Szukaj + + + Download error + Błąd pobierania + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Nie można pobrać instalatora Python z powodu %1 . +Należy zainstalować go ręcznie. + + + Missing Python Interpreter + Nie znaleziono interpretera Python + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python w wersji 2.x jest wymagany do poprawnego działania wyszukiwarki. Wygląda na to, +że nie jest zainstalowany. Zainstalować teraz? + + + Confirmation + Potwierdzenie + + + Are you sure you want to clear the history? + Czy na pewno wyczyścić historię? + + + + SearchTab + + Name + i.e: file name + Nazwa + + + Size + i.e: file size + Rozmiar + + + Seeders + i.e: Number of full sources + Pełnych + + + Leechers + i.e: Number of partial sources + Częściowych + + + Search engine + Wyszukiwarka + + + + ShutdownConfirmDlg + + Shutdown confirmation + Potwierdzenie zamykania + + + + SpeedLimitDialog + + KiB/s + KiB/s + + + + StatusBar + + Connection status: + Status połączenia: + + + No direct connections. This may indicate network configuration problems. + Brak bezposrednich połączeń. Może to oznaczać problem z konfiguracją sieci. + + + DHT: %1 nodes + Węzły DHT: %1 + + + Connection Status: + Status połączenia: + + + Online + Połączony + + + Global Download Speed Limit + Ogólny limit pobierania + + + Global Upload Speed Limit + Ogólny limit wysyłania + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Pobieranie: %1/s - Pobrano: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Wysyłanie: %1/s - Wysłano: %2 + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + Pobieranie: %1/s - Pobrano: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + Wysyłanie: %1/s - Wysłano: %2 + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Offline. Oznacza, że qBittorent nie jest w stanie nasłuchiwać połączeń przychodzących na wybranym porcie. + + + Click to disable alternative speed limits + Kliknij, aby wyłączyć alternatywne limity prędkości + + + Click to enable alternative speed limits + Kliknij, aby włączyć alternatywne limity prędkości + + + qBittorrent needs to be restarted + qBittorrent musi zostać uruchomiony ponownie + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent został zaktualizowany i konieczne jest jego ponowne uruchomienie. + + + Click to switch to alternative speed limits + Kliknij aby przełączyć na alternatywne limity prędkości + + + Click to switch to regular speed limits + Kliknij aby przełączyć na normalne limity prędkości + + + %1/s + Per second + %1/s + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + Wybierz katalog który chcesz dodać do torrenta + + + Select a file to add to the torrent + Wybierz plik który chcesz dodać do torrenta + + + Please type an announce URL + Wprowadź adres trackera + + + Announce URL: + Tracker URL + Adres trackera: + + + Please type a web seed url + Wprowadź adres seeda www + + + Web seed URL: + Adres seeda www: + + + No input path set + Nieznany katalog źródłowy + + + Please type an input path first + Proszę podać katalog żródłowy + + + Select destination torrent file + Wybierz plik docelowy + + + Torrent Files + Pliki .torrent + + + Torrent creation + Tworzenie pliku torrent + + + Torrent creation was unsuccessful, reason: %1 + Nie udało się utworzyć pliku torrent z powodu: %1 + + + Created torrent file is invalid. It won't be added to download list. + Utworzony plik torrent jest nieprawidłowy. Nie zostanie dodany do listy pobierania. + + + Torrent was created successfully: + Pomyślnie utworzono plik torrent: + + + + TorrentFilesModel + + Name + Nazwa + + + Size + Rozmiar + + + Progress + Postęp + + + Priority + Priorytet + + + + TorrentImportDlg + + Torrent Import + Importowanie pliku torrent + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Ten asystent pomoże Ci dzielić się plikami, które zostały już wcześniej pobrane. + + + Torrent file to import: + Plik torrent do zaimportowania: + + + ... + ... + + + Content location: + Położenie zawartości: + + + Skip the data checking stage and start seeding immediately + Pomiń sprawdzanie danych i zacznij udostępniać od razu + + + Import + Importuj + + + Torrent file to import + Plik torrent do zaimportowania + + + Torrent files (*.torrent) + Pliki .torrent + + + %1 Files + %1 is a file extension (e.g. PDF) + Pliki %1 + + + Please provide the location of %1 + %1 is a file name + dialog window when only one file is in torrent + Podaj położenie pliku %1 + + + Please point to the location of the torrent: %1 + dialog window when directory is in torrent + Podaj położenie katalogu %1 + + + Invalid torrent file + Nieprawidłowy plik torrent + + + This is not a valid torrent file. + To nie jest prawidłowy plik torrent. + + + + TorrentModel + + Name + i.e: torrent name + Nazwa + + + Size + i.e: torrent size + Rozmiar + + + Done + % Done + Ukończono + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + Seeds + i.e. full sources (often untranslated) + Pełnych + + + Peers + i.e. partial sources (often untranslated) + Częściowych + + + Down Speed + i.e: Download speed + Pobieranie + + + Up Speed + i.e: Upload speed + Wysyłanie + + + Ratio + Share ratio + Udział + + + ETA + i.e: Estimated Time of Arrival / Time left + ETA + + + Label + Etykieta + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Dodano + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Ukończono + + + Tracker + Tracker + + + Down Limit + i.e: Download limit + Limit pobierania + + + Up Limit + i.e: Upload limit + Limit wysyłania + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Pobrano + + + Amount left + Amount of data left to download (e.g. in MB) + Pozostało + + + Time Active + Time (duration) the torrent is active (not paused) + Aktywny przez + + + + TrackerList + + URL + URL + + + Status + Status + + + Peers + Partnerów + + + Message + Komunikat + + + [DHT] + [DHT] + + + Working + Działa + + + Disabled + Wyłączone + + + This torrent is private + Torrent prywatny + + + Updating... + Aktualizowanie... + + + Not working + Nie działa + + + Not contacted yet + Niesprawdzony + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Add a new tracker... + Dodaj tracker... + + + Remove tracker + Usuń tracker + + + Force reannounce + Sprawdź tracker + + + + TrackersAdditionDlg + + Trackers addition dialog + Dodawanie trackerów + + + List of trackers to add (one per line): + Lista trackerów do dodania (jeden na linię): + + + µTorrent compatible list URL: + Adres kompatybilny z µTorrent: + + + I/O Error + Błąd We/Wy + + + Error while trying to open the downloaded file. + Błąd podczas próby otwarcia pobranego pliku. + + + No change + Bez zmian + + + No additional trackers were found. + Nie znaleziono dodatkowych trackerów. + + + Download error + Błąd pobierania + + + The trackers list could not be downloaded, reason: %1 + Nie można pobrać listy trackerów z powodu %1 + + + + TransferListDelegate + + Downloading + Pobieranie + + + Paused + Wstrzymany + + + Queued + i.e. torrent is queued + W kolejce + + + Seeding + Torrent is complete and in upload-only mode + Wysyłanie + + + Stalled + Torrent is waiting for download to begin + Oczekujący + + + Checking + Torrent local data is being checked + Sprawdzanie + + + /s + /second (.i.e per second) + /s + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + Seeded for %1 + e.g. Seeded for 3m10s + wysyłany przez %1 + + + + TransferListFiltersWidget + + All + Wszystkie + + + Downloading + Pobierane + + + Completed + Ukończone + + + Active + Aktywne + + + Inactive + Nieaktywne + + + All labels + Wszystkie + + + Unlabeled + Bez etykiety + + + Remove label + Usuń etykietę + + + New Label + Nowa etykieta + + + Label: + Etykieta: + + + Invalid label name + Nieprawidłowa nazwa etykiety + + + Please don't use any special characters in the label name. + Nie należy używać żadnych znaków specjalnych w nazwach etykiet. + + + Paused + Wstrzymane + + + Add label... + Dodaj etykietę... + + + Resume torrents + Wznów torrenty + + + Pause torrents + Wstrzymaj torrenty + + + Delete torrents + Usuń torrenty + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + ETA + + + Column visibility + Widoczność kolumn + + + Open destination folder + Otwórz katalog pobierań + + + Force recheck + Sprawdź pobrane dane + + + Copy magnet link + Kopiuj adres magnet + + + Down Speed + i.e: Download speed + Prędkość DL + + + Up Speed + i.e: Upload speed + Prędkość UP + + + Name + i.e: torrent name + Nazwa + + + Size + i.e: torrent size + Rozmiar + + + Done + % Done + Ukończono + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + Seeds + i.e. full sources (often untranslated) + Pełnych + + + Peers + i.e. partial sources (often untranslated) + Częściowych + + + Ratio + Share ratio + Współczynnik udziału + + + Torrent Download Speed Limiting + Ograniczanie prędkości pobierania torrenta + + + Torrent Upload Speed Limiting + Ograniczanie prędkości wysyłania torrenta + + + Super seeding mode + Tryb 'super seed' + + + Download in sequential order + Pobierz w kolejności sekwencyjnej + + + Download first and last piece first + Pobierz najpierw część pierwszą i ostatnią + + + Label + Etykieta + + + New Label + Nowa etykieta + + + Label: + Etykieta: + + + New... + New label... + Nowa... + + + Reset + Reset label + Usuń + + + Rename + Zmień nazwę + + + New name: + Nowa nazwa: + + + Rename... + Zmień nazwę... + + + Invalid label name + Nieprawidłowa nazwa etykiety + + + Please don't use any special characters in the label name. + Nie należy używać żadnych znaków specjalnych w nazwach etykiet. + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Dodano + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Ukończono + + + Down Limit + i.e: Download limit + Limit DL + + + Up Limit + i.e: Upload limit + Limit UP + + + Choose save path + Wybierz katalog docelowy + + + Save path creation error + Błąd tworzenia katalogu docelowego + + + Could not create the save path + Nie można utworzyć katalogu docelowego + + + Set location... + Zmień położenie... + + + Preview file... + Podgląd pliku... + + + Limit upload rate... + Ogranicz prędkości wysyłania... + + + Limit download rate... + Ogranicz prędkości pobierania... + + + Move up + i.e. move up in the queue + Przenieś w górę + + + Move down + i.e. Move down in the queue + Przenieś w dół + + + Move to top + i.e. Move to top of the queue + Przenieś na początek + + + Move to bottom + i.e. Move to bottom of the queue + Przenieś na koniec + + + Priority + Priorytet + + + Resume + Resume/start the torrent + Wznów + + + Pause + Pause the torrent + Wstrzymaj + + + Delete + Delete the torrent + Usuń + + + Tracker + Tracker + + + Limit share ratio... + Ogranicz współczynnik udziału... + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + Ograniczanie współczynnika udziału + + + Use global ratio limit + Użyj globalnego limitu + + + buttonGroup + + + + Set no ratio limit + Ustaw bez limitu + + + Set ratio limit to + Ustaw limit na + + + + UsageDisplay + + Usage: + Użycie: + + + displays program version + wyświetlenie wersji programu + + + disable splash screen + wyłączenie ekranu startowego + + + displays this help message + wyświetlenie tego opisu + + + changes the webui port (current: %1) + zmiana portu na którym działa interfejs www (obecnie: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [pliki lub adresy URL]: pobieranie plików torrent podanych przez użytkownika (opcjonalnie) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + Chciałbym podziękować następującym osobom, które wspomogły lokalizację qBittorrenta: + + + Please contact me if you would like to translate qBittorrent into your own language. + Proszę o kontakt, jeżeli chcesz pomóc w tłumaczeniu qBittorrent. + + + + addPeerDialog + + Peer addition + Dodawanie partnera + + + IP + Adres IP + + + Port + Port + + + + addTorrentDialog + + Torrent addition dialog + Dodatkowe informacje o pliku torrent + + + Save path: + Katalog docelowy: + + + ... + ... + + + Torrent size: + Rozmiar torrenta: + + + Unknown + Nieznany + + + Free disk space: + Wolne miejsce na dysku: + + + Torrent content: + Zawartość torrenta: + + + Download in sequential order (slower but good for previewing) + Pobierz w kolejności sekwencyjnej (wolniejsze ale lepsze przy korzystaniu z opcji podglądu) + + + Add to download list in paused state + Dodaj tylko do listy pobierania (bez rozpoczynania pobierania) + + + Add + Dodaj + + + Cancel + Anuluj + + + Normal + Normalny + + + High + Wysoki + + + Maximum + Maksymalny + + + Skip file checking and start seeding immediately + Pomiń sprawdzanie danych i natychmiast rozpocznij wysyłanie + + + Label: + Etykieta: + + + Select All + Zaznacz wszystko + + + Select None + Odznacz wszystko + + + Do not download + Nie pobieraj + + + + authentication + + Tracker authentication + Autoryzacja do tracker-a + + + Tracker: + Tracker: + + + Login + Login + + + Username: + Nazwa użytkownika: + + + Password: + Hasło: + + + Log in + Zaloguj + + + Cancel + Anuluj + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + Potwierdzenia usuwania - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + Czy na pewno usunąć wybrane pliki torrent z listy transferów? + + + Remember choice + Zapamiętaj wybór + + + Also delete the files on the hard disk + Usuń także dane z twardego dysku + + + + createTorrentDialog + + Cancel + Anuluj + + + Torrent Creation Tool + Kreator plików torrent + + + Torrent file creation + Tworzenie pliku torrent + + + Announce urls (trackers): + Adres trackera: + + + Comment (optional): + Komentarz (opcja): + + + Web seeds urls (optional): + Adres seedów www (opcja): + + + File or folder to add to the torrent: + Plik lub katalog który ma zostać dodany do torrenta: + + + Add file + Dodaj plik + + + Add folder + Dodaj katalog + + + Piece size: + Rozmiar części: + + + 32 KiB + 32 KiB + + + 64 KiB + 64 KiB + + + 128 KiB + 128 KiB + + + 256 KiB + 256 KiB + + + 512 KiB + 512 KiB + + + 1 MiB + 1 MiB + + + 2 MiB + 2 MiB + + + 4 MiB + 4 MiB + + + Private (won't be distributed on DHT network if enabled) + Prywatny (gdy zaznaczone torrent nie będzie rozprowadzany w sieci DHT) + + + Start seeding after creation + Uruchom wysyłanie po utworzeniu + + + Create and save... + Tworzenie i zapisywanie... + + + Progress: + Postęp: + + + Tracker URLs: + Adresy trackerów: + + + Web seeds urls: + Adresy seedów www: + + + Comment: + Komentarz: + + + Auto + Auto + + + + createtorrent + + Select destination torrent file + Wybierz plik docelowy + + + Torrent Files + Pliki Torrent + + + No input path set + Katalog źródłowy nie zdefiniowany + + + Please type an input path first + Proszę podać katalog żródłowy + + + Torrent creation + Tworzenie torrenta + + + Torrent was created successfully: + Utworzono plik torrent: + + + Select a folder to add to the torrent + Wybierz katalog który chcesz dodać do torrenta + + + Please type an announce URL + Wprowadź adres trackera + + + Torrent creation was unsuccessful, reason: %1 + Nie udało się stworzyć torrenta , powód: %1 + + + Announce URL: + Tracker URL + Adres trackera: + + + Please type a web seed url + Wprowadź adres seeda www + + + Web seed URL: + Adres seeda www: + + + Select a file to add to the torrent + Wybierz plik który chcesz dodać do torrenta + + + Created torrent file is invalid. It won't be added to download list. + Utworzony plik torrent jest nieprawidłowy. Nie zostanie dodany do listy pobierania. + + + + downloadFromURL + + Download Torrents from URLs + Pobierz pliki torrent z adresów URL + + + Only one URL per line + Można podać tylko jeden adres URL w jednej linii + + + Download + Pobierz + + + Cancel + Anuluj + + + Download from urls + Pobierz z adresów + + + No URL entered + Nie wprowadzono adresu URL + + + Please type at least one URL. + Proszę podać przynajmniej jeden adres URL. + + + Add torrent links + Dodaj odnośniki do plików torrent + + + Both HTTP and Magnet links are supported + Wspierane są zarówno odnośniki HTTP jak i Magnet + + + + downloadThread + + I/O Error + Błąd We/Wy + + + The remote host name was not found (invalid hostname) + Nie odnaleziono nazwy zdalnego hosta (nieprawidłowa nazwa hosta) + + + The operation was canceled + Operacja została anulowana + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Zdalny serwer przedwcześnie zakończył połączenie, zanim otrzymano i przetworzono odpowiedź + + + The connection to the remote server timed out + Przekroczono czas oczekiwania na połącznie ze zdalnym serwerem + + + SSL/TLS handshake failed + Niepomyślna próba negocjacji połączenie SSL/TLS + + + The remote server refused the connection + Zdalny serwer odrzucił połączenie + + + The connection to the proxy server was refused + Połączenie z serwerem proxy zostało odrzucone + + + The proxy server closed the connection prematurely + Serwer proxy przedwcześnie zakończył połączenie + + + The proxy host name was not found + Nie znaleziono nazwy hosta serwera proxy + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Przkroczono czas oczekiwania na połączenie z serwerm proxy lub serwer nie odpowiedział na czas + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Serwer proxy wymaga uwierzytelnienia aby zaakceptować żądanie lecz oferowane dane uwierzytelnienia zostały odrzucone + + + The access to the remote content was denied (401) + Odmówiono dostępu do zdalnego zasobu (401) + + + The operation requested on the remote content is not permitted + Żądana operacja na zdalnym zasobie nie jest dozwolona + + + The remote content was not found at the server (404) + Nie znaleziono zdalnego zasobu na serwerze (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Zdalny serwer wymaga uwierzytelnienia w celu dostępu do zasobu lecz dane uwierzytelniające nie zostały zaakceptowane + + + Unknown error + Nieznany błąd + + + + engineSelect + + Search plugins + Wtyczki wyszukiwania + + + Installed search engines: + Zainstalowane wyszukiwarki: + + + Name + Nazwa + + + Url + URL + + + Enabled + Włączone + + + Install a new one + Zainstaluj nową + + + Check for updates + Sprawdź aktualizację + + + Close + Zamknij + + + Enable + Włącz + + + Disable + Wyłącz + + + Uninstall + Odinstaluj + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Tutaj możesz pobrać nowe wtyczki wyszukiwania: <a href="http:plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + engineSelectDlg + + Uninstall warning + Ostrzeżenie deinstalacji + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Niektóre wtyczki nie mogą zostać usunięte, ponieważ są częścią qBittorenta. +Tylko te, które dodałeś możesz usunąć. +Jednak tamte wtyczki były wyłączone. + + + Uninstall success + Deinstalacja zakończona + + + Select search plugins + Wybierz wtyczkę wyszukiwania + + + qBittorrent search plugins + wtyczka wyszukiwania qbittorrent + + + Search plugin install + Instalacja wtyczki wyszukiwania + + + Yes + Tak + + + No + Nie + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Najnowsza wersja wtyczki wyszukiwania %1 jest już zainstalowana. + + + Search plugin update + Aktualizacja wtyczki wyszukiwania + + + Sorry, update server is temporarily unavailable. + Sorry, czasowo niedostępny serwer aktualizacji. + + + All your plugins are already up to date. + Wszystkie twoje wtyczki są aktualne. + + + All selected plugins were uninstalled successfully + Wszystkie wybrane wtyczki zostały zainstalowane + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + Nie można zaktualizować wtyczki wyszukiwania %1, pozostaje stara wersja. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Wtyczka wyszukiwania %1 nie może być zainstalowana. + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + Pomyślnie zaktualizowano wtyczkę wyszukiwania %1. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Pomyślnie zainstalowano wtyczkę wyszukiwania %1. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Błąd instalacji wtyczki wyszukiwania %1. + + + New search engine plugin URL + URL nowej wtyczki wyszukiwania + + + URL: + URL: + + + + misc + + B + bytes + B + + + KiB + kibibytes (1024 bytes) + KiB + + + MiB + mebibytes (1024 kibibytes) + MiB + + + GiB + gibibytes (1024 mibibytes) + GiB + + + TiB + tebibytes (1024 gibibytes) + TiB + + + Unknown + Nieznany + + + Unknown + Unknown (size) + Nieznany + + + < 1m + < 1 minute + < 1m + + + %1m + e.g: 10minutes + %1m + + + %1h %2m + e.g: 3hours 5minutes + %1h %2m + + + %1d %2h + e.g: 2days 10hours + %1d %2h + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent wyłączy teraz komputer, ponieważ pobieranie zostało ukończone. + + + + options_imp + + Choose a save directory + Wybierz katalog docelowy + + + Choose an ip filter file + Wybierz plik filtra IP + + + Filters + Filtry + + + Choose export directory + Wybierz katalog eksportu + + + Add directory to scan + Dodaj katalog do przeszukiwania + + + Folder is already being watched. + Katalog jest już obserwowany. + + + Folder does not exist. + Katalog nie istnieje. + + + Folder is not readable. + Nie można czytać katalogu. + + + Failure + Błąd + + + Failed to add Scan Folder '%1': %2 + Błąd podczas dodawania katalogu do obserwowanych '%1': %2 + + + Parsing error + Błąd przetwarzania + + + Failed to parse the provided IP filter + Nie udało się przetworzyć podanego filtra IP + + + Succesfully refreshed + Przeładowano pomyślnie + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Pomyślnie przetworzono podany filtr IP: zastosowano %1 reguł. + + + Successfully refreshed + filtr czy lista? + Pomyślnie odświeżony + + + Invalid key + + + + This is not a valid SSL key. + + + + Invalid certificate + + + + This is not a valid SSL certificate. + + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + + pluginSourceDlg + + Plugin source + Źródło wtyczki + + + Search plugin source: + Źródło wtyczki wyszukiwania: + + + Local file + Plik lokalny + + + Web link + Adres strony + + + + preview + + Preview selection + Podgląd wybranego + + + File preview + Podgląd pliku + + + The following files support previewing, <br>please select one of them: + Istnieje możliwość podglądu następujących typów plików, <br> proszę wybrać jeden z nich: + + + Preview + Podgląd + + + Cancel + Anuluj + + + + previewSelect + + Preview impossible + Nie ma możliwości podglądu + + + Sorry, we can't preview this file + Przepraszamy, podgląd pliku jest niedostępny + + + Name + Nazwa + + + Size + Rozmiar + + + Progress + Postęp + + + + search_engine + + Search + Szukaj + + + Status: + Status: + + + Stopped + Zatrzymany + + + Download + Pobierz + + + Search engines... + Wtyczki wyszukiwania... + + + Go to description page + Otwórz stronę z opisem + + + + torrentAdditionDialog + + Unable to decode torrent file: + Problem z odkodowaniem pliku torrent: + + + Choose save path + Wybierz katalog docelowy + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 po pobraniu torrenta) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (aby pobrać torrenta potrzeba jeszcze %1 wolnego miejsca) + + + Empty save path + Niepoprawny katalog docelowy + + + Please enter a save path + Podaj katalog docelowy + + + Save path creation error + Błąd tworzenia katalogu docelowego + + + Could not create the save path + Nie można założyć katalogu docelowego + + + Invalid file selection + Wybrano niepoprawny plik + + + You must select at least one file in the torrent + Musisz wybrać przynajmniej jeden plik z pliku torrent + + + Priority + Priorytet + + + Seeding mode error + Błąd trybu rozsiewania + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Wybrano pomijanie sprawdzania pliku, jednak pliki lokalne prawdopodobnie nie istnieją w aktualnym katalogu pobierań. Należy wyłączyć tą opcję lub zaktualizować katalog zapisu. + + + Rename... + Zmień nazwę... + + + New name: + Nowa nazwa: + + + The file could not be renamed + Nie można zmienić nazwy pliku + + + This name is already in use in this folder. Please use a different name. + Wybrana nazwa jest już używana w tym katalogu. Proszę wybrać inną nazwę. + + + The folder could not be renamed + Nie można zmienić nazwy katalogu + + + Rename the file + Zmień nazwę pliku + + + Unable to decode magnet link: + Nie można odczytać adresu magnet: + + + Magnet Link + Adres magnet + + + Invalid label name + Nieprawidłowa nazwa etykiety + + + Please don't use any special characters in the label name. + Nie należy używać żadnych znaków specjalnych w nazwach etykiet. + + + This file name contains forbidden characters, please choose a different one. + Nazwa pliku zawiera zabronione znaki, proszę wybrać inną nazwę. + + + diff --git a/src/lang/qbittorrent_pt.qm b/src/lang/qbittorrent_pt.qm new file mode 100644 index 0000000000000000000000000000000000000000..25a7469f2372b0dc531b77e6d4364075395f979e GIT binary patch literal 119929 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�=xS*evpyczj*z|3kY~~8gXb?k% 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 + + + + AboutDlg + + About qBittorrent + Sobre qBittorrent + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + About + Sobre + + + Author + Autor + + + Name: + Nome: + + + Country: + País: + + + E-mail: + E-mail: + + + Christophe Dumez + Christophe Dumez + + + France + França + + + chris@qbittorrent.org + chris@qbittorrent.org + + + Translation + Tradução + + + License + Licença + + + Thanks to + Agradecimentos para + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">(new line) +<html><head><meta name="qrichtext" content="1" /><style type="text/css">(new line) +p, li { white-space: pre-wrap; }(new line) +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;">(new line) +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Um cliente BitTorrent avançado programado em C++, baseado no kit de ferramentas Qt4 e libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p>(new line) +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p>(new line) +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent no Freenode</span></p></body></html> + + + + AdvancedSettings + + Property + Propriedade + + + Value + Valor + + + Ignore transfer limits on local network + Ignorar limite de transferência na internet local + + + Include TCP/IP overhead in transfer limits + Incluir sobrecarga TCP/IP no limite de transferência + + + Disk write cache size + Tamanho de cache em disco + + + MiB + MiB + + + Outgoing ports (Min) [0: Disabled] + Portas de saída (Min) [0: Desabilitado] + + + Outgoing ports (Max) [0: Disabled] + Portas de saída (Max) [0: Desabilitado] + + + Recheck torrents on completion + Rechecar torrents em completação + + + Transfer list refresh interval + Intervalo de atualização da lista de transferência + + + ms + milliseconds + ms + + + Resolve peer countries (GeoIP) + Resolver peer dos países (GeoIP) + + + Resolve peer host names + Resolver nomes de peer + + + Maximum number of half-open connections [0: Disabled] + Número máximo de conexões abertas [0:desabilitada] + + + Strict super seeding + Super semeador + + + Network Interface (requires restart) + Interface de rede (requer reinício) + + + Any interface + i.e. Any network interface + Qualquer interface + + + Display program notification baloons + Exibir balões de notificação + + + Display program notification balloons + Mostrar balões de notificação do programa + + + Enable embedded tracker + Ativar tracker embutido + + + Embedded tracker port + Porta do tracker embutido + + + Check for software updates + Verificar atualizações + + + Use system icon theme + Usar tema de ícone do sistema + + + Confirm torrent deletion + Confirmar deletar torrent + + + IP Address to report to trackers (requires restart) + Endereço IP para reportar aos trackers (requer reinicio) + + + Display program on-screen notifications + Exibir notificações do programa na tela + + + Setting + Configuração + + + Value + Value set for this setting + Valor + + + Exchange trackers with other peers + + + + + AutomatedRssDownloader + + Automated RSS Downloader + Baixador de RSS automático + + + Enable the automated RSS downloader + Habilitar o baixador automático de RSS + + + Download rules + Regras de download + + + Rule definition + Definição da regra + + + Must contain: + Deve conter: + + + Must not contain: + Não deve conter: + + + ... + ... + + + Assign label: + Atribuir rótulo: + + + Apply rule to feeds: + Aplicar regra aos feeds: + + + Matching RSS articles + Artigos RSS correspondentes + + + Save to a different directory + Salvar em um diretório diferente + + + Save to: + Salvar em: + + + Import... + Importar... + + + Export... + Exportar... + + + New rule name + Nome da nova regra + + + Please type the name of the new download rule. + Por favor digite o nome da nova regra de download. + + + Rule name conflict + Conflito no nome da regra + + + A rule with this name already exists, please choose another name. + Uma regra com o mesmo nome existe, por favor escolha outro. + + + Are you sure you want to remove the download rule named %1? + Quer mesmo remover a regra de download de nome %1? + + + Are you sure you want to remove the selected download rules? + Quer mesmo remover as regras de download selecionadas? + + + Rule deletion confirmation + Confirmação de exclusão de regra + + + Destination directory + Diretório de destino + + + Invalid action + Ação inválida + + + The list is empty, there is nothing to export. + A lista está vazia, não há nada para exportar. + + + Where would you like to save the list? + Onde gostaria de salvar a lista? + + + Rules list (*.rssrules) + Lista de regras (*.rssrules) + + + I/O Error + Erro de I/O + + + Failed to create the destination file + Falha ao criar o arquivo de destino + + + Please point to the RSS download rules file + Por favor aponte para o arquivo de regras de download RSS + + + Rules list (*.rssrules *.filters) + Lista de regras (*rssrules *filters) + + + Import Error + Erro de importação + + + Failed to import the selected rules file + Falha ao importar o arquivo de regras selecionado + + + Add new rule... + Adicionar nova regra... + + + Delete rule + Deletar regra + + + Rename rule... + Renomear regra... + + + Delete selected rules + Deletar regras selecionadas + + + Rule renaming + Renomeando regra + + + Please type the new rule name + Por favor digite o novo nome da regra + + + Use regular expressions + Usar expressões regulares + + + Regex mode: use Perl-like regular expressions + Modo Regex: Usar expressões regulares estilo Perl + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Modo coringa: você pode usar<ul><li>? para atingir um caracter</li><li>* para atingir zero ou mais de vários caracteres</li><li>Espaços vazios contam como operador AND</li></ul> + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Modo coringa: você pode usar<ul><li>? para atingir um caracter</li><li>* para atingir zero ou mais de vários caracteres</li><li>| é usado como como operador OR</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 atingiu a taxa máxima que você configurou. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent está limitado a porta: TCP/%1 + + + UPnP support [ON] + Suporte UPnP [Ligado] + + + UPnP support [OFF] + Suporte UPnP [desligado] + + + NAT-PMP support [ON] + Suporte NAT-PMP [ligado] + + + NAT-PMP support [OFF] + Suporte NAT-PMP [desligado] + + + DHT support [ON], port: UDP/%1 + Suporte DHT [ON], porta: UDP/%1 + + + DHT support [OFF] + Suporte DHT [Desligado] + + + PeX support [ON] + Suporte PeX [Ligado] + + + Local Peer Discovery [ON] + Peer discovery [ligado] + + + Local Peer Discovery support [OFF] + Peer discovery [desligado] + + + Encryption support [ON] + Suporte a encriptação [Ligado] + + + Encryption support [FORCED] + Suporte a encriptação [FORÇADO] + + + Encryption support [OFF] + Suporte a encriptação [Desligado] + + + Web User Interface Error - Unable to bind Web UI to port %1 + Erro no usuário da interface web - Impossível setar para porta %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' foi removido(a) da lista de transferência e do HD. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' foi removido(a) da lista de transferência. + + + '%1' is not a valid magnet URI. + '%1' não é um URI magnético válido. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' já está na lista de download. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' continuando. (continue rápido) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' adicionado a lista de download. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Incapaz de decodificar arquivo torrent: '%1' + + + This file is either corrupted or this isn't a torrent. + O arquivo está corrompido ou não é um torrent. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>foi bloqueado pelo seu filtro de IP</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>foi banido por corromper partes</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Download recursivo do arquivo %1 embutido no torrent %2 + + + Unable to decode %1 torrent file. + Impossível decodificar %1 do arquivo torrent. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Falha no mapeamento de porta, mensagem: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Portas mapeadas com sucesso, mensagem: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Resumo rápido rejeitado para o torrent %1, tente novamente... + + + Url seed lookup failed for url: %1, message: %2 + Url falhou para: %1, mensagem: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + baixando '%1', por favor espere... + + + Using a disk cache size of %1 MiB + Usando um tamanho de cache de disco de %1 MiB + + + PeX support [OFF] + PeX suporte [Desligado] + + + Restart is required to toggle PeX support + Reinicio requerido para mudar o suporte PeX + + + The Web UI is listening on port %1 + A Web UI é escutado na porta %1 + + + HTTP user agent is %1 + O usuário agente HTTP é %1 + + + Reason: %1 + Motivo: %1 + + + Note: new trackers were added to the existing torrent. + Nota: novos trackers foram adicionados no torrent existente. + + + Note: new URL seeds were added to the existing torrent. + Nota: nova URL de seed foi adicionada ao torrent existente. + + + An I/O error occured, '%1' paused. + Um erro de I/O aconteceu, '%1' foi pausado. + + + Removing torrent %1... + Removendo torrent %1... + + + Pausing torrent %1... + Pausando torrent %1... + + + Error: The torrent %1 does not contain any file. + Erro: O torrent %1 não contém nenhum arquivo. + + + File sizes mismatch for torrent %1, pausing it. + O tamanho do arquivo para o torrent %1 está incorreto, pausando. + + + Torrent name: %1 + Nome do torrent: %1 + + + Torrent size: %1 + Tamanho do torrent: %1 + + + Save path: %1 + Caminho para salvar: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent baixado em %1. + + + Thank you for using qBittorrent. + Obrigado por usar o qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 terminou o download + + + + ConsoleDlg + + General + Gerais + + + Blocked IPs + IPs bloqueados + + + qBittorrent log viewer + Visualizador de log do qBittorrent + + + + CookiesDlg + + Cookies management + Gestão de cookies + + + Key + As in Key/Value pair + Chave + + + Value + As in Key/Value pair + Valor + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Chaves comuns para cookies são: '%1', '%2'. +Você deve buscar essa informação nas preferências do seu navegador. + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + Seu DNS dinâmico foi atualizado com sucesso. + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Erro de DNS dinâmico: O serviço está temporariamente inacessível, tentarei novamente em 30 minutos. + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Erro de DNS dinâmico: o hostname não existe na conta. + + + Dynamic DNS error: Invalid username/password. + Erro de DNS dinâmico: Usuário/Senha inválido(s). + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Erro de DNS dinâmico: qBittorrent está na lista negra por este serviço, por favor envie este bug para http://bugs.qbittorrent.org. + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Erro de DNS dinâmico: %1 foi retornado pelo serviço, por favor envie este bug para http://bugs.qbittorrent.org. + + + Dynamic DNS error: Your username was blocked due to abuse. + Erro de DNS dinâmico: Seu usuário foi bloqueado por motivo de abuso. + + + Dynamic DNS error: supplied domain name is invalid. + Erro de DNS dinâmico: O domínio é inválido. + + + Dynamic DNS error: supplied username is too short. + Erro de DNS dinâmico: Usuário informado é muito pequeno. + + + Dynamic DNS error: supplied password is too short. + Erro de DNS dinâmico: A senha é muito pequena. + + + + DownloadThread + + I/O Error + Erro de I/O + + + The remote host name was not found (invalid hostname) + O host remoto não foi encontrado (host inválido) + + + The operation was canceled + A operação foi cancelada + + + The remote server closed the connection prematurely, before the entire reply was received and processed + O servidor remoto fechou a conexão, antes de responder, receber e processar + + + The connection to the remote server timed out + Atingiu o fim do tempo da conexão com o servidor remoto + + + SSL/TLS handshake failed + SSL/TLS falhou + + + The remote server refused the connection + O servidor remoto recusou a conexão + + + The connection to the proxy server was refused + Conexão com proxy foi recusada + + + The proxy server closed the connection prematurely + Servidor proxy fechou a conexão + + + The proxy host name was not found + O host name do proxy não foi encontrado + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Fim do tempo de conexão com o proxy ou o proxy não respondeu no tempo + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + O proxy requer autenticação mas não aceitou as credenciais oferecidas + + + The access to the remote content was denied (401) + O conteúdo do acesso remoto foi negado (401) + + + The operation requested on the remote content is not permitted + A operação requerida no servidor não foi permitida + + + The remote content was not found at the server (404) + O conteúdo não foi encontrado no servidor (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + O servidor remoto requer autenticação para servir os dados mas as credenciais oferecidas não foram aceitas + + + The Network Access API cannot honor the request because the protocol is not known + O acesso a internet não honrou o pedido pois o protocolo é desconhecido + + + The requested operation is invalid for this protocol + Operação inválida para este protocolo + + + An unknown network-related error was detected + Um desconhecido erro relatado de internet foi detectado + + + An unknown proxy-related error was detected + Um desconhecido erro de proxy relatado foi detectado + + + An unknown error related to the remote content was detected + Um desconhecido erro relacionado ao conteúdo do servidor foi detectado + + + A breakdown in protocol was detected + Um erro no protocolo foi detectado + + + Unknown error + Erro desconhecido + + + + EventManager + + %1/s + e.g. 120 KiB/s + %1/s + + + Working + Trabalhando + + + Updating... + Atualizando... + + + Not working + Sem serviço + + + Not contacted yet + Não contactado ainda + + + this session + esta sessão + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seeded pelo %1 + + + %1 max + e.g. 10 max + %1 máximo + + + + ExecutionLog + + Form + Formulário + + + General + Geral + + + Blocked IPs + IPs bloqueados + + + + FeedDownloader + + RSS Feed downloader + Baixador de conteúdo RSS + + + RSS feed: + RSS feed: + + + Feed name + Nome do Feed + + + Automatically download torrents from this feed + Baixar automaticamente torrents deste feed + + + Download filters + Baixar filtros + + + Filters: + Filtros: + + + Filter settings + Configurações de filtro + + + Matches: + Correspondem: + + + Does not match: + Não correspondem: + + + Destination folder: + Pasta de destino: + + + ... + ... + + + Filter testing + Teste de filtro + + + Torrent title: + Título do torrent: + + + Result: + Resultado: + + + Test + Teste + + + Import... + Importar... + + + Export... + Exportar... + + + Rename filter + Renomear filtro + + + Remove filter + Remover filtro + + + Add filter + Adicionar filtro + + + + FeedDownloaderDlg + + New filter + Novo filtro + + + Please choose a name for this filter + Por favor escolha um nome para este filtro + + + Filter name: + Nome do filtro: + + + Invalid filter name + Nome inválido para o filtro + + + The filter name cannot be left empty. + O nome do filtro não pode ser vazio. + + + This filter name is already in use. + Este nome de filtro já está sendo usado. + + + Filter testing error + Erro ao testar o filtro + + + Please specify a test torrent name. + Por favor especifique um nome para o torrent. + + + matches + assemelha + + + does not match + não assemelha + + + Select file to import + Selecione arquivo a importar + + + Filters Files + Arquivos de filtro + + + Import successful + Importado com sucesso + + + Filters import was successful. + Filtros importados com sucesso. + + + Import failure + Falha ao importar + + + Filters could not be imported due to an I/O error. + Filtros não podem ser importados por um erro de entrada e saída. + + + Select destination file + Seleciona arquivo de destino + + + Export successful + Exportado com sucesso + + + Filters export was successful. + A exportação foi executada com sucesso. + + + Export failure + Falha na exportação + + + Filters could not be exported due to an I/O error. + Os filtros não puderam ser exportados por um erro de entrada e saída. + + + Choose save path + Escolha o caminho de salvamento + + + + FeedList + + Unread + Não lido + + + + FeedListWidget + + RSS feeds + RSS feeds + + + Unread + Não lido + + + + GUI + + Open Torrent Files + Abrir Arquivos Torrent + + + Torrent Files + Arquivos Torrent + + + qBittorrent + qBittorrent + + + Transfers + Transferências + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Velocidade de download: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Velocidade de Upload: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 download finalizado. + + + I/O Error + i.e: Input/Output Error + Erro de Entrada/Saída + + + Search + Busca + + + RSS + RSS + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Erro de I/O no torrent %1. +Motivo: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Erro no download da URL + + + Couldn't download file at url: %1, reason: %2. + Não pude baixar arquivo em: %1, motivo: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Options were saved successfully. + Opções salvas com sucesso. + + + Download completion + Completação de download + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Muitos arquivos estão atualmente sendo transferidos.(new line) +Está certo que quer sair do qBittorrent? + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Limite global de upload + + + Global Download Speed Limit + Limite global de download + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Down: %2/s, Up: %3/s) + + + Recursive download confirmation + Confirmação de download recursivo + + + The torrent %1 contains torrent files, do you want to proceed with their download? + O torrent %1 contém arquivos torrent, continua com este download? + + + Torrent file association + Associação de arquivo torrent + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent não é sua aplicação padrão para arquivos torrent e links magnéticos. +Gostaria de associar o qBittorrent para arquivos torrent e links magnéticos? + + + Transfers (%1) + Transferências (%1) + + + Yes + Sim + + + No + Não + + + Never + Nunca + + + Always + Sempre + + + Exiting qBittorrent + Saindo do qBittorrent + + + Set the password... + Configurar a senha... + + + Password update + Atualiza senha + + + The UI lock password has been successfully updated + A senha de travamento da UI foi atualizada com sucesso + + + UI lock password + Senha de travamento da UI + + + Please type the UI lock password: + Por favor digite sua senha UI: + + + Invalid password + Senha inválida + + + The password is invalid + A senha está inválida + + + A newer version is available + Uma nova versão está disponível + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Uma nova versão do qBittorrent está disponível no Souceforge. +Gostaria de atualizar o qBittorrrent para a versão %1? + + + Impossible to update qBittorrent + Impossível atualizar qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent falhou para atualizar, motivo: %1 + + + + GeoIP + + Australia + Austrália + + + Argentina + Argentina + + + Austria + Áustria + + + United Arab Emirates + Emirados Árabes Unidos + + + Brazil + Brasil + + + Bulgaria + Bulgária + + + Belarus + Belarus + + + Belgium + Bélgica + + + Bosnia + Bósnia + + + Canada + Canadá + + + Czech Republic + República Tcheca + + + China + China + + + Costa Rica + Costa Rica + + + Switzerland + Suíça + + + Germany + Alemanha + + + Denmark + Dinamarca + + + Algeria + Argélia + + + Spain + Espanha + + + Egypt + Egito + + + Finland + Finlândia + + + France + França + + + United Kingdom + Reino Unido + + + Greece + Grécia + + + Georgia + Geórgia + + + Hungary + Hungria + + + Croatia + Croácia + + + Italy + Itália + + + India + Índia + + + Israel + Israel + + + Ireland + Irlanda + + + Iceland + Islândia + + + Indonesia + Indonésia + + + Japan + Japão + + + South Korea + Coréia do Sul + + + Luxembourg + Luxemburgo + + + Malaysia + Malásia + + + Mexico + México + + + Serbia + Sérvia + + + Morocco + Marrocos + + + Netherlands + Holanda + + + Norway + Noruéga + + + New Zealand + Nova Zelândia + + + Portugal + Portugal + + + Poland + Polônia + + + Pakistan + Paquistão + + + Philippines + Filipinas + + + Russia + Rússia + + + Romania + Romênia + + + France (Reunion Island) + França + + + Sweden + Suécia + + + Slovakia + Eslováquia + + + Singapore + Singapura + + + Slovenia + Eslovênia + + + Taiwan + Taiwan + + + Turkey + Turquia + + + Thailand + Tailândia + + + USA + Estados Unidos da América + + + Ukraine + Ucrânia + + + South Africa + Africa do Sul + + + Saudi Arabia + Arábia Saudita + + + + HeadlessLoader + + Information + Informação + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Para controlar o qBittorrent acesse a UI Web em http://localhost:%1 + + + The Web UI administrator user name is: %1 + O nome do usuário administrador da UI Web é: %1 + + + The Web UI administrator password is still the default one: %1 + A senha do usuário administrador da UI Web ainda é a padrão: %1 + + + This is a security risk, please consider changing your password from program preferences. + Este é um risco de segurança, por favor considere mudar sua senha nas preferências do programa. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + Seu endereço IP fo banido após várias tentativas de autenticação. + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - T: %2 + + + + HttpServer + + File + Arquivo + + + Edit + Editar + + + Help + Ajuda + + + Delete from HD + Deletar do HD + + + Download Torrents from their URL or Magnet link + Baixar torrents da URL or Link Magnético + + + Only one link per line + Somente um link por linha + + + Download + Baixar + + + Download local torrent + Baixar torrent local + + + Torrent files were correctly added to download list. + Torrent adicionado corretamente a lista de download. + + + Point to torrent file + Ponto para o arquivo torrent + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Deseja mesmo deletar os torrents selecionados da lista e do HD? + + + Download rate limit must be greater than 0 or disabled. + Taxa de limite de download deve ser maior que 0 ou desabilitado. + + + Upload rate limit must be greater than 0 or disabled. + Taxa de limite de upload deve ser maior que 0 ou desabilitado. + + + Maximum number of connections limit must be greater than 0 or disabled. + O número máximo de conexões deve ser maior que 0 ou desabilitado. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + O número máximo de conexões por torrent deve ser maior que 0 ou desabilitado. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + O número máximo de slots de upload por torrent deve ser maior que 0 ou desabilitado. + + + Unable to save program preferences, qBittorrent is probably unreachable. + Impossível salvar preferências do programa, qBittorrent provavelmente está inatingível. + + + Language + Linguagem + + + The port used for incoming connections must be greater than 1024 and less than 65535. + A porta para conexões de entrada deve ser maior que 1024 e menos que 65535. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + A porta usada para a UI Web deve ser maior que 1024 e menor que 65535. + + + The Web UI username must be at least 3 characters long. + O nome de usuário para a UI Web deve conter mais que 3 caracteres. + + + The Web UI password must be at least 3 characters long. + A senha do usuário da UI Web deve ser maior que 3 caracteres. + + + Downloaded + Is the file downloaded or not? + Baixado + + + Save + Salvar + + + qBittorrent client is not reachable + Cliente qBittorrent não está alcançável + + + HTTP Server + Servidor HTTP + + + Torrent path + Caminho torrent + + + Torrent name + Nome do torrent + + + The following parameters are supported: + Os parâmetros a seguir são suportados: + + + + LegalNotice + + Legal Notice + Noticia legal + + + Legal notice + Noticia legal + + + Cancel + Cancele + + + I Agree + Eu aceito + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent é um programa de compartilhamento de arquivos. Quando você o usa, os dados enviados estarão disponíveis para outros ue fizerem o mesmo upload. Todo conteúdo compartilhado por você é de sua inteira responsabilidade. + +Nenhum outro aviso será dado. + + + Press %1 key to accept and continue... + Pressione a tecla %1 para aceitar e continuar... + + + + LineEdit + + Clear the text + Limpa o texto + + + + MainWindow + + &Edit + &Editar + + + &File + &Arquivo + + + &Help + &Ajuda + + + Preview file + Arquivo de pré-visualização + + + Clear log + Limpar log + + + Decrease priority + Diminuir prioridade + + + Increase priority + Aumentar prioridade + + + &Tools + &Ferramentas + + + &View + &Ver + + + &Add File... + &Adicionar Arquivo... + + + E&xit + S&air + + + &Options... + &Opções... + + + Add &URL... + Adicionar &URL... + + + Torrent &creator + &Criar torrent + + + Set upload limit... + Configurar limite de upload... + + + Set download limit... + Configurar limite de download... + + + Set global download limit... + Configurar limite global de download... + + + Set global upload limit... + Configurar limite global de upload... + + + &Log viewer... + &Visualizador de log... + + + Top &tool bar + Barra de &Ferramentas Início + + + Display top tool bar + Exibir Barra de Ferramentas Início + + + &Speed in title bar + &Velocidade na barra de título + + + Show transfer speed in title bar + Mostrar velocidade de transferência na barra de título + + + Alternative speed limits + Limites de velocidade alternativos + + + &About + &Sobre + + + &Pause + &Pausar + + + &Delete + &Remover + + + P&ause All + P&ausar Todos + + + Visit &Website + Visitar &Website + + + Report a &bug + Relatar um &erro + + + &Documentation + &Documentação + + + &RSS reader + Leitor de &RSS + + + Search &engine + Ferramenta de &busca + + + Log viewer + Visualizador de Log + + + Lock qBittorrent + Travar o qBittorrent + + + Ctrl+L + Ctrl+L + + + Shutdown computer when downloads complete + Desligar computador quando terminar os downloads + + + &Resume + &Resumir + + + R&esume All + R&esume Todos + + + Shutdown qBittorrent when downloads complete + Desligar qBittorrent quando terminar os downloads + + + Exit + Sair + + + Import torrent... + Importar torrent... + + + Donate money + Doar dinheiro + + + If you like qBittorrent, please donate! + Se você curte qBittorrent, por favor faça sua doação! + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + Configurar a senha... + + + Transfers + Transferências + + + Torrent file association + Associação de arquivo torrent + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent não é sua aplicação padrão para arquivos torrent e links magnéticos. +Gostaria de associar o qBittorrent para arquivos torrent e links magnéticos? + + + UI lock password + Senha de travamento da UI + + + Please type the UI lock password: + Por favor digite sua senha UI: + + + Password update + Atualiza senha + + + The UI lock password has been successfully updated + A senha de travamento da UI foi atualizada com sucesso + + + RSS + RSS + + + Search + Busca + + + Transfers (%1) + Transferências (%1) + + + Download completion + Completação de download + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 teve o download finalizado. + + + I/O Error + i.e: Input/Output Error + Erro de I/O + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Ocorreu um erro de I/O no torrent %1. +Motivo: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Confirmação de download recursivo + + + The torrent %1 contains torrent files, do you want to proceed with their download? + O torrent %1 contém arquivos torrent, continua com este download? + + + Yes + Sim + + + No + Não + + + Never + Nunca + + + Url download error + Erro no download da URL + + + Couldn't download file at url: %1, reason: %2. + Não foi possível baixar arquivo no url: %1, motivo: %2. + + + Global Upload Speed Limit + Velocidade limite global de upload + + + Global Download Speed Limit + Velocidade limite global de download + + + Invalid password + Senha inválida + + + The password is invalid + A senha está inválida + + + Exiting qBittorrent + Saindo do qBittorrent + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Muitos arquivos estão atualmente sendo transferidos. +Quer mesmo sair do qBittorrent? + + + Always + Sempre + + + Open Torrent Files + Abrir Arquivos Torrent + + + Torrent Files + Arquivos Torrent + + + Options were saved successfully. + Opções foram salvas com sucesso. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Velocidade de download: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Velocidade de Upload: %1 KiB/s + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Down: %2/s, Up: %3/s) + + + A newer version is available + Uma nova versão está disponível + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Uma nova versão do qBittorrent está disponível no Souceforge. +Gostaria de atualizar o qBittorrrent para a versão %1? + + + Impossible to update qBittorrent + Impossível atualizar qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent falhou para atualizar, motivo: %1 + + + &Add torrent file... + &Adicionar arquivo torrent... + + + Add &link to torrent... + Adicionar &link para torrent... + + + Import existing torrent... + Importar torrent existente... + + + Execution &Log + Execução &Log + + + Execution Log + Execução Log + + + Auto-Shutdown on downloads completion + Desligar automaticamente quando completar os downloads + + + Exit qBittorrent + Sair do qBittorrent + + + Suspend system + Suspender o sistema + + + Shutdown system + Desligar o sistema + + + Disabled + Desabilitado + + + The password should contain at least 3 characters + A senha deve conter ao menos 3 caracteres + + + + PeerAdditionDlg + + Invalid IP + IP inválido + + + The IP you provided is invalid. + O IP informado é inválido. + + + + PeerListDelegate + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + Cliente + + + Progress + i.e: % downloaded + Progresso + + + Down Speed + i.e: Download speed + Velocidade de download + + + Up Speed + i.e: Upload speed + Velocidade de upload + + + Downloaded + i.e: total data downloaded + Baixado + + + Uploaded + i.e: total data uploaded + Subido + + + Ban peer permanently + Banir fonte permanentemente + + + Peer addition + Adição de fonte + + + The peer was added to this torrent. + A fonte foi adicionada para este torrent. + + + The peer could not be added to this torrent. + A fonte não pode ser adicionada a este torrent. + + + Are you sure? -- qBittorrent + Tem certeza? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + Deseja mesmo banir permanentemente a fonte selecionada? + + + &Yes + &Sim + + + &No + &Não + + + Manually banning peer %1... + Manualmente banindo fonte %1... + + + Upload rate limiting + Limitando taxa de upload + + + Download rate limiting + Limitando taxa de download + + + Add a new peer... + Adicionar um novo peer... + + + Limit download rate... + Taxa de limite de download... + + + Limit upload rate... + Taxa de limite de upload... + + + Copy IP + Copiar IP + + + Connection + Conexão + + + + Preferences + + UI + UI + + + Downloads + Downloads + + + Connection + Conexão + + + Bittorrent + Bittorrent + + + Proxy + Proxy + + + Web UI + UI Web + + + Language: + Linguagem: + + + (Requires restart) + (Necessário reiniciar) + + + Visual style: + Estilo visual: + + + Transfer list + Lista de transferência + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Usar linhas alternadas de cor + + + File system + Sistema de arquivos + + + Torrent queueing + Torrent esperando + + + Maximum active downloads: + Máximo de downloads ativos: + + + Maximum active uploads: + Máximo de uploads ativos: + + + Maximum active torrents: + Máximo de torrents ativos: + + + When adding a torrent + Quando adicionar um torrent + + + Display torrent content and some options + Mostrar conteúdo torrent e mais opções + + + Listening port + Escutando porta + + + Port used for incoming connections: + Porta usada para conexões de entrada: + + + Random + Aleatório + + + Enable UPnP port mapping + Habilitar mapeamento de porta UPnP + + + Enable NAT-PMP port mapping + Habilitar mapeamento de porta NAT-PMP + + + Connections limit + Limite de conexões + + + Global maximum number of connections: + Número máximo global de conexões: + + + Maximum number of connections per torrent: + Número máximo de conexões por torrent: + + + Maximum number of upload slots per torrent: + Número máximo de slots de upload por torrent: + + + Upload: + Upload: + + + Download: + Download: + + + KiB/s + KiB/s + + + Bittorrent features + Recursos Bittorrent + + + Enable DHT network (decentralized) + Habilitar DHT network (descentralizado) + + + Use a different port for DHT and Bittorrent + Usar uma porta diferente para DHT e Bittorrent + + + DHT port: + Porta DHT: + + + Enable Peer Exchange / PeX (requires restart) + Habilitar Peer Exchange / PeX (requer reinício) + + + Enable Local Peer Discovery + Habilitar Local Peer Discovery + + + Enabled + Habilitado + + + Forced + Forçado + + + Disabled + Desabilitado + + + Type: + Tipo: + + + (None) + (Nenhum) + + + HTTP + HTTP + + + Port: + Porta: + + + Authentication + Autenticação + + + Username: + Nome de usuário: + + + Password: + Senha: + + + SOCKS5 + SOCKS5 + + + HTTP Server + Servidor HTTP + + + Filter path (.dat, .p2p, .p2b): + Caminho do filtro (.dat, .p2p, .p2b): + + + HTTP Communications (trackers, Web seeds, search engine) + Comunicações HTTP (trackers, Web seeds, mecanismo de busca) + + + Host: + Servidor: + + + Peer Communications + Comunicações de Peer + + + SOCKS4 + SOCKS4 + + + Speed + Velocidade + + + Global speed limits + Limite global de velocidade + + + Alternative global speed limits + Limite alternativo de velocidade global + + + to + time1 to time2 + para + + + Every day + Todo dia + + + Week days + Dias da semana + + + Week ends + Fins de semana + + + Advanced + Avançado + + + Copy .torrent files to: + Copiar arquivos .torrent para: + + + Remove folder + Remover pasta + + + No action + Sem ação + + + Options + Opções + + + Visual Appearance + Aparência Visual + + + Action on double-click + Ação do duplo clique + + + Downloading torrents: + Baixando torrents: + + + Start / Stop + Iniciar / Parar + + + Open destination folder + Abrir pasta de destino + + + Completed torrents: + Torrents completos: + + + Desktop + Área de trabalho + + + Show splash screen on start up + Mostrar imagem de início ao ligar + + + Start qBittorrent minimized + Iniciar qBittorrent minimizado + + + Show qBittorrent icon in notification area + Mostrar ícone na bandeja + + + Minimize qBittorrent to notification area + Minimizar qBittorrent na área de notificação + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Fechar qBittorrent para área de notificação + + + Do not start the download automatically + The torrent will be added to download list in pause state + Não iniciar downloads automaticamente + + + Save files to location: + Salvar arquivos na pasta: + + + Append the label of the torrent to the save path + Acrescentar o rótulo do torrent para o caminho de salvamento + + + Pre-allocate disk space for all files + Pré-alocar espaço em disco para todos os arquivos + + + Keep incomplete torrents in: + Manter torrents incompletos em: + + + Append .!qB extension to incomplete files' names + Acrescentar extensão .!qB para nomes de arquivos incompletos + + + Automatically add torrents from: + Adicionar automaticamente torrents de: + + + Add folder... + Adicionar pasta... + + + IP Filtering + Filtro de IP + + + Schedule the use of alternative speed limits + Programar o uso de limite de velocidades alternativas + + + from + from (time1 to time2) + de + + + When: + Quando: + + + Look for peers on your local network + Buscar por peers na rede local + + + Protocol encryption: + Protocolo de encriptação: + + + Enable Web User Interface (Remote control) + Habilitar interface de usuário de rede (Controle Remoto) + + + Share ratio limiting + Limitando taxa de compartilhamento + + + Seed torrents until their ratio reaches + Compartilhar torrents até que sua taxa de compartilhamento atinja + + + then + então + + + Pause them + Pause + + + Remove them + Remove + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Trocar peers com clientes compatíveis com qBittorrent (µTorrent, Vuze, ...) + + + Email notification upon download completion + Notificação por email quando completar o download + + + Destination email: + Email de destino: + + + SMTP server: + Servidor SMTP: + + + Run an external program on torrent completion + Rodar um programa externo quando completar o torrent + + + Use %f to pass the torrent path in parameters + Use %f para passar o caminho do torrent em parâmetros + + + Proxy server + Servidor proxy + + + BitTorrent + BitTorrent + + + Start / Stop Torrent + Iniciar / Parar Torrent + + + Use UPnP / NAT-PMP port forwarding from my router + User UPnP / NAT-PMP redirecionamento de porta do meu roteador + + + Privacy + Privacidade + + + Enable DHT (decentralized network) to find more peers + Habilitar DHT (rede decentralizada) para encontrar mais peers + + + Use a different port for DHT and BitTorrent + Usar uma porta diferente para DHT e BitTorrent + + + Enable Peer Exchange (PeX) to find more peers + Habilitar Peer Exchange (PeX) para encontrar mais peers + + + Enable Local Peer Discovery to find more peers + Habilitar Local Peer Discovery para encontrar mais peers + + + Encryption mode: + Modo de encriptação: + + + Prefer encryption + Encriptação escolhida + + + Require encryption + Encriptação requerida + + + Disable encryption + Desabilitar encriptação + + + User Interface + Interface de usuário + + + Reload the filter + Recarregar o filtro + + + Behavior + Comportamento + + + Language + Linguagem + + + Power Management + Gestão de Energia + + + Inhibit system sleep when torrents are active + Sistema de espera inibe quando torrents estão activos + + + Bypass authentication for localhost + Desvio de autenticação para localhost + + + Ask for program exit confirmation + Solicite confirmação para fechar o programa + + + Use monochrome system tray icon (requires restart) + Use o ícone da bandeja do sistema monocromático (requer reinicialização) + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Os parâmetros a seguir são suportados:(new line) +<ul>(new line) +<li>%f: Caminho do Torrent</li>(new line) +<li>%n: Nome do Torrent</li>(new line) +</ul> + + + Tray icon style: + Estilo do icone da bandeja: + + + Normal + Normal + + + Monochrome (Dark theme) + Monocromático (Dark theme) + + + Monochrome (Light theme) + Monocromático (Light theme) + + + This server requires a secure connection (SSL) + Este servidor espera por uma conexão segura (SSL) + + + User Interface Language: + Linguagem da interface de usuário: + + + Transfer List + Lista de transferência + + + Show qBittorrent in notification area + Mostrar qBittorrent na área de notificação + + + Hard Disk + Disco Rígido + + + Listening Port + Escutando Porta + + + Connections Limits + Limites de Conexão + + + Proxy Server + Servidor Proxy + + + Torrent Queueing + Torrents na espera + + + Share Ratio Limiting + Taxa limite de compartilhamento + + + Use UPnP / NAT-PMP to forward the port from my router + Use UPnP / NAT-PMP para redirecionar a porta do meu roteador + + + Update my dynamic domain name + Atualize meu nome de domínio dinâmico + + + Service: + Serviço: + + + Register + Registro + + + Domain name: + Nome de domínio: + + + Global Rate Limits + Limite Global + + + Apply rate limit to uTP connections + Aplicar taxa limite para conexões uTP + + + Apply rate limit to transport overhead + Aplicar taxa limite para o transporte fora da cabeça + + + Alternative Global Rate Limits + Taxa limite global alternativa + + + Schedule the use of alternative rate limits + Agende para usar taxas limite alternativas + + + Enable bandwidth management (uTP) + Habilitar manutenção de largura de banda (uTP) + + + Otherwise, the proxy server is only used for tracker connections + Então, o servidor proxy é somente usado para conexões de tracker + + + Use proxy for peer connections + Usar proxy para conexões de peer + + + Append .!qB extension to incomplete files + Adicionar extensão .!qB para arquivos incompletos + + + Use HTTPS instead of HTTP + Usar HTTPS ao invez de HTTP + + + Import SSL Certificate + Importar certificado SSL + + + Import SSL Key + Importar chave SSL + + + Certificate: + Certificado: + + + Key: + Chave: + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Informações sobre certificados</a> + + + + PreviewSelect + + Name + Nome + + + Size + Tamanho + + + Progress + Progresso + + + Preview impossible + Pré-visualização impossível + + + Sorry, we can't preview this file + Desculpe, não é possível pré-visualizar esse arquivo + + + + ProgramUpdater + + Could not create the file %1 + Não pude criar o arquivo %1 + + + Failed to download the update at %1 + %1 is an URL + Falha para baixar a atualização em %1 + + + + PropListDelegate + + Normal + Normal (priority) + Normal + + + High + High (priority) + Alta + + + Maximum + Maximum (priority) + Máxima + + + Not downloaded + Não baixado + + + Mixed + Mixed (priorities + Misto + + + + PropTabBar + + General + Geral + + + Trackers + Rastreadores + + + Peers + Peers + + + URL Seeds + URL semeadores + + + Files + Arquivos + + + HTTP Sources + Fontes HTTP + + + Content + Conteúdo + + + + PropertiesWidget + + Save path: + Caminho de salvamento: + + + Torrent hash: + Mistura do Torrent: + + + Comment: + Comentário: + + + Share ratio: + Taxa de Compartilhamento: + + + General + Gerais + + + Trackers + Rastreadores + + + URL seeds + URL fonte + + + Files + Arquivos + + + Priority + Prioridade + + + New url seed + New HTTP source + Nova url de compartilhador + + + New url seed: + Nova url de compartilhador: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + Essa url de compartilhador já está na lista. + + + Choose save path + Escolha um caminho de salvamento + + + Save path creation error + Erro ao criar caminho de salvamento + + + Could not create the save path + Não foi possível criar caminho de salvamento + + + Downloaded: + Baixado: + + + Transfer + Transferência + + + Uploaded: + Subido: + + + Wasted: + Gasto: + + + UP limit: + Limite de UP: + + + DL limit: + Limite de DL: + + + Time elapsed: + Tempo passado: + + + Connections: + Conexões: + + + Information + Informação + + + Created on: + Criado em: + + + Peers + Fontes + + + Normal + Normal + + + Maximum + Máximo + + + High + Alto + + + this session + esta sessão + + + %1 max + e.g. 10 max + %1 máximo + + + Availability: + Disponível: + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seeded pelo %1 + + + Rename... + Renomear... + + + New name: + Novo nome: + + + The file could not be renamed + O arquivo não pode ser renomeado + + + This name is already in use in this folder. Please use a different name. + Este nome já está sendo utilizado nessa pasta. Por favor use um nome diferente. + + + The folder could not be renamed + A pasta não pode ser renomeada + + + Rename the file + Renomeie o arquivo + + + This file name contains forbidden characters, please choose a different one. + O arquivo contem caracteres desconhecidos, por favor use um nome diferente. + + + I/O Error + Erro de entrada e saída + + + This file does not exist yet. + Este arquivo não existe. + + + This folder does not exist yet. + Esta pasta não existe. + + + Reannounce in: + Reanunciar em: + + + Select All + Seleciona todos + + + Select None + Selecionar nenhum + + + Do not download + Não baixar + + + Pieces size: + Tamanho dos pedaços: + + + Time active: + Time (duration) the torrent is active (not paused) + Tempo ativo: + + + Torrent content: + Conteúdo do torrent: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1 atingiu a taxa máxima que você configurou. + + + Removing torrent %1... + Removendo torrent %1... + + + Pausing torrent %1... + Pausando torrent %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent está limitado a porta: TCP/%1 + + + UPnP support [ON] + Suporte UPnP [Ligado] + + + UPnP support [OFF] + Suporte UPnP [desligado] + + + NAT-PMP support [ON] + Suporte NAT-PMP [ligado] + + + NAT-PMP support [OFF] + Suporte NAT-PMP [desligado] + + + HTTP user agent is %1 + O usuário agente HTTP é %1 + + + Using a disk cache size of %1 MiB + Usando um tamanho de cache de disco de %1 MiB + + + DHT support [ON], port: UDP/%1 + Suporte DHT [ON], porta: UDP/%1 + + + DHT support [OFF] + Suporte DHT [Desligado] + + + PeX support [ON] + Suporte PeX [Ligado] + + + PeX support [OFF] + PeX suporte [Desligado] + + + Restart is required to toggle PeX support + Reinicio requerido para mudar o suporte PeX + + + Local Peer Discovery [ON] + Peer discovery [ligado] + + + Local Peer Discovery support [OFF] + Peer discovery [desligado] + + + Encryption support [ON] + Suporte a encriptação [Ligado] + + + Encryption support [FORCED] + Suporte a encriptação [FORÇADO] + + + Encryption support [OFF] + Suporte a encriptação [Desligado] + + + Embedded Tracker [ON] + Tracker embutido [ligado] + + + Failed to start the embedded tracker! + Falha para iniciar o tracker embutido! + + + Embedded Tracker [OFF] + Tracker embutido [desligado] + + + The Web UI is listening on port %1 + A Web UI é escutado na porta %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Erro no usuário da interface web - Impossível setar para porta %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' foi removido(a) da lista de transferência e do HD. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' foi removido(a) da lista de transferência. + + + '%1' is not a valid magnet URI. + '%1' não é um URI magnético válido. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' já está na lista de download. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' continuando. (continue rápido) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' adicionado a lista de download. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Incapaz de decodificar arquivo torrent: '%1' + + + This file is either corrupted or this isn't a torrent. + O arquivo está corrompido ou não é um torrent. + + + Error: The torrent %1 does not contain any file. + Erro: O torrent %1 não contém nenhum arquivo. + + + Note: new trackers were added to the existing torrent. + Nota: novos trackers foram adicionados no torrent existente. + + + Note: new URL seeds were added to the existing torrent. + Nota: nova URL de seed foi adicionada ao torrent existente. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>foi bloqueado pelo seu filtro de IP</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>foi banido por corromper partes</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Download recursivo do arquivo %1 embutido no torrent %2 + + + Unable to decode %1 torrent file. + Impossível decodificar %1 do arquivo torrent. + + + Torrent name: %1 + Nome do torrent: %1 + + + Torrent size: %1 + Tamanho do torrent: %1 + + + Save path: %1 + Caminho para salvar: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent baixado em %1. + + + Thank you for using qBittorrent. + Obrigado por usar o qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 terminou o download + + + An I/O error occured, '%1' paused. + Um erro de I/O aconteceu, '%1' foi pausado. + + + Reason: %1 + Motivo: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Falha no mapeamento de porta, mensagem: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Portas mapeadas com sucesso, mensagem: %1 + + + File sizes mismatch for torrent %1, pausing it. + O tamanho do arquivo para o torrent %1 está incorreto, pausando. + + + Fast resume data was rejected for torrent %1, checking again... + Resumo rápido rejeitado para o torrent %1, tente novamente... + + + Url seed lookup failed for url: %1, message: %2 + Url falhou para: %1, mensagem: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + baixando '%1', por favor espere... + + + The network interface defined is invalid: %1 + A interface de rede definida é inválida: %1 + + + Trying any other network interface available instead. + Tentando outra interface de rede disponível. + + + Listening on IP address %1 on network interface %2... + Escutando no endereço IP %1 na interface %2... + + + Failed to listen on network interface %1 + Falha ao escutar na interface de rede %1 + + + UPnP / NAT-PMP support [ON] + Suporte a UPnp / NAT-PMP [ON] + + + UPnP / NAT-PMP support [OFF] + Suporte a UPnp / NAT-PMP [OFF] + + + Local Peer Discovery support [ON] + Suporte a Local Peer Discovery [ON] + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Analisado com sucesso o filtro de IP enviado: %1 regras foram aplicadas. + + + Error: Failed to parse the provided IP filter. + Erro: Falha ao analisar o filtro de IP. + + + Reporting IP address %1 to trackers... + Reportando endereço IP %1 aos trackers... + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + O computador entrará em modo de espera a não ser que você cancele durante os próximos 15 segundos... + + + The computer will now be switched off unless you cancel within the next 15 seconds... + O computador irá se desligar a não ser que você cancele durante os próximos 15 segundos... + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent irá sair a não ser que você cancele durante os próximos 15 segundos... + + + + RSS + + Search + Busca + + + Delete + Apagar + + + Rename + Renomear + + + Refresh RSS streams + Atualizar RSS streams + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(duplo-clique para baixar)</span></p></body></html> + + + Download torrent + Baixar torrent + + + Open news URL + Abrir novas URL + + + Copy feed URL + Copiar URL do feed + + + New subscription + Nova inscrição + + + Mark items read + Marcar ítems lidos + + + Update all + Atualizar todos + + + Update all feeds + Atualizar todos feeds + + + RSS feeds + RSS feeds + + + Update + Atualiza + + + Feed URL + URL do feed + + + Article title + Título do artigo + + + Rename... + Renomear... + + + New subscription... + Nova inscrição... + + + RSS feed downloader... + Baixador de feed RSS... + + + New folder... + Nova pasta... + + + Manage cookies... + Administrar cookies... + + + Settings... + Configurações... + + + RSS Downloader... + Baixador RSS... + + + + RSSImp + + Please type a rss stream url + Digite uma url de stream rss + + + Stream URL: + Stream URL: + + + Are you sure? -- qBittorrent + Tem certeza? -- qBittorrent + + + &Yes + &Sim + + + &No + &Não + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + Este rss feed já está na lista. + + + Date: + Data: + + + Author: + Autor: + + + Please choose a folder name + Por favor escolha um nome de pasta + + + Folder name: + Nome da pasta: + + + New folder + Nova pasta + + + Are you sure you want to delete these elements from the list? + Está certo de que deseja deletar esses elementos da lista ? + + + Are you sure you want to delete this element from the list? + Deseja realmente deletar esse ítem da lista? + + + Please choose a new name for this RSS feed + Por favor escolha um novo nome para este feed RSS + + + New feed name: + Novo nome do feed: + + + Name already in use + Novo já está em uso + + + This name is already used by another item, please choose another one. + Este nome já está sendo usado por outro ítem, por favor escolha outro. + + + Overwrite attempt + Atenção sobescrevendo + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Você não pode sobescrever o ítem %1. + + + Unread + Não lido + + + + RssArticle + + No description available + Nenhuma descrição disponível + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + Baixando automaticamente o torrent %1 do RSS feed %2... + + + + RssItem + + No description available + Nenhuma descrição disponível + + + + RssSettings + + RSS Reader Settings + Configurações de Leitor de RSS + + + RSS feeds refresh interval: + Intervalo de atualização de feeds RSS: + + + minutes + minutos + + + Maximum number of articles per feed: + Número máximo de artigos por feed: + + + + RssSettingsDlg + + RSS Reader Settings + Configurações de Leitor de RSS + + + RSS feeds refresh interval: + Intervalo de atualização de feeds RSS: + + + minutes + minutos + + + Maximum number of articles per feed: + Número máximo de artigos por feed: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Baixando automaticamente o torrent %1 do RSS feed %2... + + + + ScanFoldersModel + + Watched Folder + Pasta visualizada + + + Download here + Baixar aqui + + + + SearchCategories + + All categories + Todas categorias + + + Movies + Filmes + + + TV shows + Shows de TV + + + Music + Música + + + Games + Jogos + + + Anime + Anime + + + Software + Programa + + + Pictures + Imagens + + + Books + Livros + + + + SearchEngine + + Empty search pattern + Padrão de busca vazio + + + Please type a search pattern first + Por favor digite um padrão de busca primeiro + + + Results + Resultados + + + Searching... + Buscando... + + + Cut + Corta + + + Copy + Copia + + + Paste + Cola + + + Clear field + Limpa campo + + + Clear completion history + Limpar lista dos completados + + + Search Engine + Mecanismo de Busca + + + Search has finished + Busca finalizada + + + An error occured during search... + Um erro ocorreu durante a busca... + + + Search aborted + Busca abortada + + + Search returned no results + A busca não retornou resultados + + + Results + i.e: Search results + Resultados + + + Unknown + Desconhecido + + + Search + Busca + + + Download error + Erro no download + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + A instalação do Python não pode ser baixada, razão: %1. +Por favor instale manualmente. + + + Missing Python Interpreter + Faltando interpretador Python + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x é requerido para você poder usar a busca mas não parece estar instalado. +Gostaria de instalar agora? + + + Confirmation + Confirmação + + + Are you sure you want to clear the history? + Deseja realmente limpar o histórico? + + + + SearchTab + + Name + i.e: file name + Nome + + + Size + i.e: file size + Tamanho + + + Seeders + i.e: Number of full sources + Compartilhadores completos + + + Leechers + i.e: Number of partial sources + Compartilhadores parciais + + + Search engine + Mecanismo de busca + + + + ShutdownConfirmDlg + + Shutdown confirmation + Confirmação de desligamento + + + + SpeedLimitDialog + + KiB/s + KiB/s + + + + StatusBar + + Connection status: + Estado da conexão: + + + No direct connections. This may indicate network configuration problems. + Sem conexões diretas. Talvez tenha algo errado em sua configuração. + + + DHT: %1 nodes + DHT: %1 nos + + + Connection Status: + Estado da conexão: + + + Online + Online + + + Global Download Speed Limit + Limite de Velocidade Global de Download + + + Global Upload Speed Limit + Limite de Velocidade Global de Upload + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - T: %2 + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + D: %1 B/s - T: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + U: %1 B/s - T: %2 + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Offline. Isto acontece quando o qBittorrent falha para escutar na porta selecionada para conexões de entrada. + + + Click to disable alternative speed limits + Clique para desabilitar limite alternativo + + + Click to enable alternative speed limits + Clique para habilitar limite alternativo + + + qBittorrent needs to be restarted + qBittorrent precisa ser reiniciado + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent foi atualizado e precisa ser reiniciado para que as mudanças sejam aplicadas. + + + Click to switch to alternative speed limits + Clique aqui para mudar para os limites de velocidade alternativa + + + Click to switch to regular speed limits + Clique aqui para alternar para regular os limites de velocidade + + + %1/s + Per second + %1/s + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + Selecione uma pasta para adicionar ao torrent + + + Select a file to add to the torrent + Selecione um arquivo para adicionar ao torrent + + + Please type an announce URL + Digite uma url anunciada + + + Announce URL: + Tracker URL + Url anunciada: + + + Please type a web seed url + Digite uma url de compartilhador web + + + Web seed URL: + Url de compartilhador web: + + + No input path set + Nenhum caminho de entrada selecionado + + + Please type an input path first + Digite primeiro um caminho de entrada + + + Select destination torrent file + Selecione o arquivo torrent de destino + + + Torrent Files + Arquivos Torrent + + + Torrent creation + Criação de torrent + + + Torrent creation was unsuccessful, reason: %1 + A criação do torrent não foi possível, motivo: %1 + + + Created torrent file is invalid. It won't be added to download list. + Torrent criado é inválido. Não será adicionado a lista de download. + + + Torrent was created successfully: + Torrent foi criado com sucesso: + + + + TorrentFilesModel + + Name + Nome + + + Size + Tamanho + + + Progress + Progresso + + + Priority + Prioridade + + + + TorrentImportDlg + + Torrent Import + Importar torrent + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Este assistente vai ajudá-lo a compartilhar um torrent que você baixou com o qBittorrent . + + + Torrent file to import: + Arquivo torrent para importar: + + + ... + ... + + + Content location: + Local do conteúdo: + + + Skip the data checking stage and start seeding immediately + Pular estágio de checagem de dados e começar a compartilhar imediatamente + + + Import + Importar + + + Torrent file to import + Arquivo torrent para importar + + + Torrent files (*.torrent) + Arquivos torrent (*.torrent) + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 arquivos + + + Please provide the location of %1 + %1 is a file name + Por favor forneça a localização de %1 + + + Please point to the location of the torrent: %1 + Por favor, aponte para a localização do torrent: %1 + + + Invalid torrent file + Arquivo torrent inválido + + + This is not a valid torrent file. + Este não é um arquivo torrent válido. + + + + TorrentModel + + Name + i.e: torrent name + Nome + + + Size + i.e: torrent size + Tamanho + + + Done + % Done + Feito + + + Status + Torrent status (e.g. downloading, seeding, paused) + Estado + + + Seeds + i.e. full sources (often untranslated) + Seeds + + + Peers + i.e. partial sources (often untranslated) + Peers + + + Down Speed + i.e: Download speed + Velocidade de download + + + Up Speed + i.e: Upload speed + Velocidade de upload + + + Ratio + Share ratio + Taxa + + + ETA + i.e: Estimated Time of Arrival / Time left + ETA + + + Label + Etiqueta + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Adicionado em + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Completado em + + + Tracker + Tracker + + + Down Limit + i.e: Download limit + Limite de download + + + Up Limit + i.e: Upload limit + Limite de upload + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Total baixado + + + Amount left + Amount of data left to download (e.g. in MB) + Total faltando + + + Time Active + Time (duration) the torrent is active (not paused) + Tempo Ativo + + + + TrackerList + + URL + URL + + + Status + Estado + + + Peers + Fontes + + + Message + Mensagem + + + [DHT] + [DHT] + + + Working + Trabalhando + + + Disabled + Desabilitado + + + This torrent is private + Este torrent é privado + + + Updating... + Atualizando... + + + Not working + Sem serviço + + + Not contacted yet + Não contactado ainda + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Add a new tracker... + Adicionar novo tracker... + + + Remove tracker + Remover tracker + + + Force reannounce + Força reanuncio + + + + TrackersAdditionDlg + + Trackers addition dialog + Diálogo de adição de Trackers + + + List of trackers to add (one per line): + Lista Trackers para adicionar (um por linha): + + + µTorrent compatible list URL: + URL da lista compatível com µTorrent: + + + I/O Error + Erro de entrada e saída + + + Error while trying to open the downloaded file. + Erro ao tentar abrir o arquivo baixado. + + + No change + Sem mudanças + + + No additional trackers were found. + Não foram encontrados Trackers adicionais. + + + Download error + Erro no download + + + The trackers list could not be downloaded, reason: %1 + A lista de trackers não pode ser baixada, razão: %1 + + + + TransferListDelegate + + Downloading + Baixando + + + Paused + Pausado + + + Queued + i.e. torrent is queued + Espera + + + Seeding + Torrent is complete and in upload-only mode + Enviando + + + Stalled + Torrent is waiting for download to begin + Estacionado + + + Checking + Torrent local data is being checked + Checando + + + /s + /second (.i.e per second) + /s + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seeded pelo %1 + + + + TransferListFiltersWidget + + All + Tudo + + + Downloading + Baixando + + + Completed + Completado + + + Active + Ativo + + + Inactive + Inativo + + + All labels + Todas etiquetas + + + Unlabeled + Sem etiqueta + + + Remove label + Remover etiqueta + + + New Label + Nova etiqueta + + + Label: + Etiqueta: + + + Invalid label name + Nome de etiqueta inválido + + + Please don't use any special characters in the label name. + Por favor não use caracteres especiais no nome da etiqueta. + + + Paused + Pausado + + + Add label... + Adicionar etiqueta... + + + Resume torrents + Resumir torrents + + + Pause torrents + Pausar torrents + + + Delete torrents + Remover torrents + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + ETA + + + Column visibility + Visibilidade da coluna + + + Open destination folder + Abrir pasta de destino + + + Force recheck + Forçar re-checagem + + + Copy magnet link + Copiar link magnético + + + Down Speed + i.e: Download speed + Velocidade de download + + + Up Speed + i.e: Upload speed + Velocidade de upload + + + Name + i.e: torrent name + Nome + + + Size + i.e: torrent size + Tamanho + + + Done + % Done + Feito + + + Status + Torrent status (e.g. downloading, seeding, paused) + Estado + + + Seeds + i.e. full sources (often untranslated) + Seeds + + + Peers + i.e. partial sources (often untranslated) + Peers + + + Ratio + Share ratio + Taxa + + + Torrent Download Speed Limiting + Limitando Velocidade de Download de Torrent + + + Torrent Upload Speed Limiting + Limitando Velocidade de Upload de Torrent + + + Super seeding mode + Modo super compartilhador + + + Download in sequential order + Download em ordem sequencial + + + Download first and last piece first + Baixar primeiro a primeira e a última parte + + + Label + Etiqueta + + + New Label + Nova etiqueta + + + Label: + Etiqueta: + + + New... + New label... + Nova... + + + Reset + Reset label + Resetar + + + Rename + Renomear + + + New name: + Novo nome: + + + Rename... + Renomear... + + + Invalid label name + Nome de etiqueta inválido + + + Please don't use any special characters in the label name. + Por favor não use caracteres especiais no nome da etiqueta. + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Adicionado em + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Completado em + + + Down Limit + i.e: Download limit + Limite de download + + + Up Limit + i.e: Upload limit + Limite de upload + + + Choose save path + Escolha caminho de salvamento + + + Save path creation error + Erro ao criar caminho de salvamento + + + Could not create the save path + Não foi possível criar caminho de salvamento + + + Set location... + Definir local... + + + Preview file... + Arquivo de pré-exibição... + + + Limit upload rate... + Limite de taxa de upload... + + + Limit download rate... + Limite de taxa de download... + + + Move up + i.e. move up in the queue + Mover para cima + + + Move down + i.e. Move down in the queue + Mover para baixo + + + Move to top + i.e. Move to top of the queue + Mover para o topo + + + Move to bottom + i.e. Move to bottom of the queue + Mover para último + + + Priority + Prioridade + + + Resume + Resume/start the torrent + Resumir + + + Pause + Pause the torrent + Pausar + + + Delete + Delete the torrent + Apagar + + + Limit share ratio... + Taxa de limite de compartilhamento... + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + Torrent Upload/Download limite + + + Use global ratio limit + Usar taxa de limite global + + + buttonGroup + botãoGrupo + + + Set no ratio limit + Não configurar taxa de limite + + + Set ratio limit to + Configurar limite para + + + + UsageDisplay + + Usage: + Uso: + + + displays program version + exibir versão do programa + + + disable splash screen + desabilitar tela de inicio + + + displays this help message + exibir este mensagem de ajuda + + + changes the webui port (current: %1) + mudar a porta do webui (atual: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [arquivos ou urls]: baixar os torrents passados pelo usuário (opcional) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + Gostaria de agradecer às seguintes pessoas por voluntariamente terem traduzido o qBittorrent: + + + Please contact me if you would like to translate qBittorrent into your own language. + Por favor contate-me se você deseja traduzir o qBittorrent no seu idioma. + + + + addPeerDialog + + Peer addition + Adição de fonte + + + IP + IP + + + Port + Porta + + + + addTorrentDialog + + Torrent addition dialog + Dialogo de adicionar torrent + + + Save path: + Caminho de salvamento: + + + ... + ... + + + Torrent content: + Conteúdo do torrent: + + + Add to download list in paused state + Adicionar a lista de download em pausa + + + Add + Adicionar + + + Cancel + Cancelar + + + Normal + Normal + + + High + Alto + + + Maximum + Máximo + + + Torrent size: + Tamanho do torrent: + + + Unknown + Desconhecido + + + Free disk space: + Espaço livre em disco: + + + Download in sequential order (slower but good for previewing) + Baixar em ordem de sequência (mais lento porém melhor para visualizar) + + + Skip file checking and start seeding immediately + Passar checagem de arquivo e começar a compartilhar imediatamente + + + Label: + Etiqueta: + + + Select All + Seleciona todos + + + Select None + Seleciona nenhum + + + Do not download + Não baixar + + + + authentication + + Tracker authentication + Autenticação de tracker + + + Tracker: + Tracker: + + + Login + Login + + + Username: + Usuário: + + + Password: + Senha: + + + Log in + Logar + + + Cancel + Cancelar + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + Confirmação de exclusão - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + Deseja realmente deletar os torrents selecionados da lista de transferência? + + + Remember choice + Lembrar escolha + + + Also delete the files on the hard disk + Deletar também arquivos do disco + + + + createTorrentDialog + + Cancel + Cancelar + + + Torrent Creation Tool + Ferramenta de Criação de Torrent + + + Torrent file creation + Criando arquivo Torrent + + + Announce urls (trackers): + Urls (trackers): + + + Comment (optional): + Comentário (opcional): + + + Web seeds urls (optional): + Urls de compartilhadores web (opcional): + + + File or folder to add to the torrent: + Arquivo ou pasta para adicionar ao torrent: + + + Piece size: + Tamanho: + + + 32 KiB + 32kb + + + 64 KiB + 64kb + + + 128 KiB + 128kb + + + 256 KiB + 256kb + + + 512 KiB + 512kb + + + 1 MiB + 1mb + + + 2 MiB + 2mb + + + 4 MiB + 4mb + + + Private (won't be distributed on DHT network if enabled) + Privado (não distribuir em DHT se habilitado) + + + Start seeding after creation + Iniciar compartilhamento depois de criar + + + Create and save... + Criar e salvar... + + + Progress: + Progresso: + + + Add file + Adicionar arquivo + + + Add folder + Adicionar pasta + + + Tracker URLs: + Tracker URLs: + + + Web seeds urls: + Web seeds urls: + + + Comment: + Comentário: + + + Auto + + + + + createtorrent + + Select destination torrent file + Selecione o arquivo torrent de destino + + + Torrent Files + Arquivos Torrent + + + No input path set + Nenhum caminho de entrada selecionado + + + Please type an input path first + Digite primeiro um caminho de entrada + + + Torrent creation + Criação de torrent + + + Torrent was created successfully: + Torrent foi criado com sucesso: + + + Select a folder to add to the torrent + Selecione uma pasta para adicionar ao torrent + + + Please type an announce URL + Digite uma url anunciada + + + Torrent creation was unsuccessful, reason: %1 + A criação do torrent não foi possível, motivo: %1 + + + Announce URL: + Tracker URL + Url anunciada: + + + Please type a web seed url + Digite uma url de compartilhador web + + + Web seed URL: + Url de compartilhador web: + + + Select a file to add to the torrent + Selecione um arquivo para adicionar ao torrent + + + Created torrent file is invalid. It won't be added to download list. + Torrent criado é inválido. Não será adicionado a lista de download. + + + + downloadFromURL + + Download Torrents from URLs + Baixar torrents de URLs + + + Only one URL per line + Somente uma URL por linha + + + Download + Baixar + + + Cancel + Cancelar + + + Download from urls + Baixar de URLs + + + No URL entered + Nenhuma URL inserida + + + Please type at least one URL. + Por favor digite uma URL. + + + Add torrent links + Adicionar links torrent + + + Both HTTP and Magnet links are supported + Ambos HTTP e links magnéticos são suportados + + + + downloadThread + + I/O Error + Erro de entrada e saída + + + The remote host name was not found (invalid hostname) + O host remoto não foi encontrado (host inválido) + + + The operation was canceled + A operação foi cancelada + + + The remote server closed the connection prematurely, before the entire reply was received and processed + O servidor remoto fechou a conexão, antes de responder, receber e processar + + + The connection to the remote server timed out + Atingiu o fim do tempo da conexão com o servidor remoto + + + SSL/TLS handshake failed + SSL/TLS falhou + + + The remote server refused the connection + O servidor remoto recusou a conexão + + + The connection to the proxy server was refused + Conexão com proxy foi recusada + + + The proxy server closed the connection prematurely + Servidor proxy fechou a conexão + + + The proxy host name was not found + O host name do proxy não foi encontrado + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Fim do tempo de conexão com o proxy ou o proxy não respondeu no tempo + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + O proxy requer autenticação mas não aceitou as credenciais oferecidas + + + The access to the remote content was denied (401) + O conteúdo do acesso remoto foi negado (401) + + + The operation requested on the remote content is not permitted + A operação requerida no servidor não foi permitida + + + The remote content was not found at the server (404) + O conteúdo não foi encontrado no servidor (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + O servidor remoto requer autenticação para servir os dados mas as credenciais oferecidas não foram aceitas + + + The Network Access API cannot honor the request because the protocol is not known + O acesso a internet não honrou o pedido pois o protocolo é desconhecido + + + The requested operation is invalid for this protocol + Operação inválida para este protocolo + + + An unknown network-related error was detected + Um desconhecido erro relatado de internet foi detectado + + + An unknown proxy-related error was detected + Um desconhecido erro de proxy relatado foi detectado + + + An unknown error related to the remote content was detected + Um desconhecido erro relacionado ao conteúdo do servidor foi detectado + + + A breakdown in protocol was detected + Um erro no protocolo foi detectado + + + Unknown error + Erro desconhecido + + + + engineSelect + + Search plugins + Plugins de busca + + + Installed search engines: + Plugins de busca instalados: + + + Name + Nome + + + Url + Url + + + Enabled + Habilitado + + + Install a new one + Instalar um novo + + + Check for updates + Verificar atualizações + + + Close + Fechar + + + Enable + Habilitar + + + Disable + Desabilitar + + + Uninstall + Desinstalar + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Você pode pegar novos mecanismos de busca aqui: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + engineSelectDlg + + Uninstall warning + Aviso de desinstalação + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Muitos plugins não podem ser desinstalados por serem padrão do qBittorrent. + Apenas aqueles que você instalou podem ser desinstalados. +Portanto os plugins foram desabilitados. + + + Uninstall success + Desinstalado com sucesso + + + Select search plugins + Selecionar plugins de busca + + + qBittorrent search plugins + Plugins de busca qBittorrent + + + Search plugin install + Instalação de plugin de busca + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Uma versão mais recente de plugin de busca %1 já está instalado. + + + Search plugin update + Atualização de plugin de busca + + + Sorry, update server is temporarily unavailable. + Desculpe, servidor de atualizações está temporariamente indisponível. + + + All your plugins are already up to date. + Todos os plugins já estão atuais. + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 esse aí não pôde ser atualizado, vai ficar o véio. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Plugin de busca %1 não pode ser instalado. + + + All selected plugins were uninstalled successfully + Plugins selecionados desinstalados com sucesso + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + Plugin de busca %1 atualizado com sucesso. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Plugin de busca %1 instalado com sucesso. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Sinto muito mas a instalação do plugin de busca %1 falhou. + + + New search engine plugin URL + Url de novo plugin de busca + + + URL: + Url: + + + Yes + Sim + + + No + Não + + + + misc + + B + bytes + B + + + KiB + kibibytes (1024 bytes) + Kib + + + MiB + mebibytes (1024 kibibytes) + MiB + + + GiB + gibibytes (1024 mibibytes) + GiB + + + TiB + tebibytes (1024 gibibytes) + TiB + + + Unknown + Desconhecido + + + Unknown + Unknown (size) + Desconhecido + + + < 1m + < 1 minute + < 1 minuto + + + %1m + e.g: 10minutes + %1m + + + %1h %2m + e.g: 3hours 5minutes + %1h %2m + + + %1d %2h + e.g: 2days 10hours + %1d %2h + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBIttorrent irá desligar seu computador agora porque os downloads terminaram. + + + + options_imp + + Choose a save directory + Selecione um diretório de salvamento + + + Choose an ip filter file + Escolha um arquivo de filtro de ip + + + Filters + Filtros + + + Choose export directory + Escolha diretório de exportação + + + Add directory to scan + Adicione diretório para escanear + + + Folder is already being watched. + Pasta já está sendo monitorada. + + + Folder does not exist. + Essa pasta não existe. + + + Folder is not readable. + A pasta não tem suporte a leitura. + + + Failure + Falhou + + + Failed to add Scan Folder '%1': %2 + Falhou para adicionar pasta a ser escaneada '%1': %2 + + + Parsing error + Análise de Erro + + + Failed to parse the provided IP filter + Falha ao analisar o filtro de IP enviado + + + Succesfully refreshed + Atualizado com sucesso + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Analisado com sucesso o filtro de IP : %1 regras foram aplicadas. + + + Successfully refreshed + Atualizado com sucesso + + + Invalid key + + + + This is not a valid SSL key. + + + + Invalid certificate + + + + This is not a valid SSL certificate. + + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + + pluginSourceDlg + + Plugin source + Fonte do plugin + + + Search plugin source: + Busca de plugin de busca: + + + Local file + Arquivo local + + + Web link + Link da net + + + + preview + + Preview selection + Seleção de pré-visualização + + + File preview + Pré-visualização de arquivo + + + The following files support previewing, <br>please select one of them: + Os seguintes arquivos suportam pré-visualização, <br>por favor selecione um deles: + + + Preview + Pré-visualização + + + Cancel + Cancelar + + + + previewSelect + + Preview impossible + Pré-visualização impossível + + + Sorry, we can't preview this file + Arquivo sem possível pré-visualização + + + Name + Nome + + + Size + Tamanho + + + Progress + Progresso + + + + search_engine + + Search + Busca + + + Status: + Estado: + + + Stopped + Parado + + + Download + Download + + + Search engines... + Máquinas de busca... + + + Go to description page + Ir para a página de descrição + + + + torrentAdditionDialog + + Unable to decode torrent file: + Incapaz de decodificar o arquivo torrent: + + + Choose save path + Escolha um caminho de salvamento + + + Empty save path + Caminho de salvamento vazio + + + Please enter a save path + Por favor digite um caminho de salvamento + + + Save path creation error + Erro ao criar caminho de salvamento + + + Could not create the save path + Não foi possível criar caminho de salvamento + + + Invalid file selection + Seleção de arquivo inválida + + + You must select at least one file in the torrent + Você deve selecionar um arquivo no torrent + + + Priority + Prioridade + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 depois de baixar o torrent) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 mais é requerido para baixar) + + + Seeding mode error + Modo de compartilhamento errado + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Você escolheu não checar. Entretanto, arquivos locais não parecem existir na pasta atual de destino. +Por favor desabilite este recurso ou atualize o caminho de salvamento. + + + Rename... + Renomear... + + + New name: + Novo nome: + + + The file could not be renamed + O arquivo não pode ser renomeado + + + This name is already in use in this folder. Please use a different name. + Este nome já está em uso. Por favor use um nome diferente. + + + The folder could not be renamed + Esta pasta não pode ser renomeada + + + Rename the file + Renomeie o arquivo + + + Unable to decode magnet link: + Impossível decodificar o link magnético: + + + Magnet Link + Link Magnético + + + Invalid label name + Nome de etiqueta inválido + + + Please don't use any special characters in the label name. + Por favor não use caracteres especiais no nome da etiqueta. + + + This file name contains forbidden characters, please choose a different one. + Este nome de arquivo contém caracteres proibidos, por favor escolha um diferente. + + + diff --git a/src/lang/qbittorrent_pt_BR.qm b/src/lang/qbittorrent_pt_BR.qm new file mode 100644 index 0000000000000000000000000000000000000000..25a7469f2372b0dc531b77e6d4364075395f979e GIT binary patch literal 119929 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�=xS*evpyczj*z|3kY~~8gXb?k% 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 + + + + AboutDlg + + About qBittorrent + Sobre qBittorrent + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + About + Sobre + + + Author + Autor + + + Name: + Nome: + + + Country: + País: + + + E-mail: + E-mail: + + + Christophe Dumez + Christophe Dumez + + + France + França + + + chris@qbittorrent.org + chris@qbittorrent.org + + + Translation + Tradução + + + License + Licença + + + Thanks to + Agradecimentos para + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">(new line) +<html><head><meta name="qrichtext" content="1" /><style type="text/css">(new line) +p, li { white-space: pre-wrap; }(new line) +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;">(new line) +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Um cliente BitTorrent avançado programado em C++, baseado no kit de ferramentas Qt4 e libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p>(new line) +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p>(new line) +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent no Freenode</span></p></body></html> + + + + AdvancedSettings + + Property + Propriedade + + + Value + Valor + + + Ignore transfer limits on local network + Ignorar limite de transferência na internet local + + + Include TCP/IP overhead in transfer limits + Incluir sobrecarga TCP/IP no limite de transferência + + + Disk write cache size + Tamanho de cache em disco + + + MiB + MiB + + + Outgoing ports (Min) [0: Disabled] + Portas de saída (Min) [0: Desabilitado] + + + Outgoing ports (Max) [0: Disabled] + Portas de saída (Max) [0: Desabilitado] + + + Recheck torrents on completion + Rechecar torrents em completação + + + Transfer list refresh interval + Intervalo de atualização da lista de transferência + + + ms + milliseconds + ms + + + Resolve peer countries (GeoIP) + Resolver peer dos países (GeoIP) + + + Resolve peer host names + Resolver nomes de peer + + + Maximum number of half-open connections [0: Disabled] + Número máximo de conexões abertas [0:desabilitada] + + + Strict super seeding + Super semeador + + + Network Interface (requires restart) + Interface de rede (requer reinício) + + + Any interface + i.e. Any network interface + Qualquer interface + + + Display program notification baloons + Exibir balões de notificação + + + Display program notification balloons + Mostrar balões de notificação do programa + + + Enable embedded tracker + Ativar tracker embutido + + + Embedded tracker port + Porta do tracker embutido + + + Check for software updates + Verificar atualizações + + + Use system icon theme + Usar tema de ícone do sistema + + + Confirm torrent deletion + Confirmar deletar torrent + + + IP Address to report to trackers (requires restart) + Endereço IP para reportar aos trackers (requer reinicio) + + + Display program on-screen notifications + Exibir notificações do programa na tela + + + Setting + Configuração + + + Value + Value set for this setting + Valor + + + Exchange trackers with other peers + + + + + AutomatedRssDownloader + + Automated RSS Downloader + Baixador de RSS automático + + + Enable the automated RSS downloader + Habilitar o baixador automático de RSS + + + Download rules + Regras de download + + + Rule definition + Definição da regra + + + Must contain: + Deve conter: + + + Must not contain: + Não deve conter: + + + ... + ... + + + Assign label: + Atribuir rótulo: + + + Apply rule to feeds: + Aplicar regra aos feeds: + + + Matching RSS articles + Artigos RSS correspondentes + + + Save to a different directory + Salvar em um diretório diferente + + + Save to: + Salvar em: + + + Import... + Importar... + + + Export... + Exportar... + + + New rule name + Nome da nova regra + + + Please type the name of the new download rule. + Por favor digite o nome da nova regra de download. + + + Rule name conflict + Conflito no nome da regra + + + A rule with this name already exists, please choose another name. + Uma regra com o mesmo nome existe, por favor escolha outro. + + + Are you sure you want to remove the download rule named %1? + Quer mesmo remover a regra de download de nome %1? + + + Are you sure you want to remove the selected download rules? + Quer mesmo remover as regras de download selecionadas? + + + Rule deletion confirmation + Confirmação de exclusão de regra + + + Destination directory + Diretório de destino + + + Invalid action + Ação inválida + + + The list is empty, there is nothing to export. + A lista está vazia, não há nada para exportar. + + + Where would you like to save the list? + Onde gostaria de salvar a lista? + + + Rules list (*.rssrules) + Lista de regras (*.rssrules) + + + I/O Error + Erro de I/O + + + Failed to create the destination file + Falha ao criar o arquivo de destino + + + Please point to the RSS download rules file + Por favor aponte para o arquivo de regras de download RSS + + + Rules list (*.rssrules *.filters) + Lista de regras (*rssrules *filters) + + + Import Error + Erro de importação + + + Failed to import the selected rules file + Falha ao importar o arquivo de regras selecionado + + + Add new rule... + Adicionar nova regra... + + + Delete rule + Deletar regra + + + Rename rule... + Renomear regra... + + + Delete selected rules + Deletar regras selecionadas + + + Rule renaming + Renomeando regra + + + Please type the new rule name + Por favor digite o novo nome da regra + + + Use regular expressions + Usar expressões regulares + + + Regex mode: use Perl-like regular expressions + Modo Regex: Usar expressões regulares estilo Perl + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Modo coringa: você pode usar<ul><li>? para atingir um caracter</li><li>* para atingir zero ou mais de vários caracteres</li><li>Espaços vazios contam como operador AND</li></ul> + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Modo coringa: você pode usar<ul><li>? para atingir um caracter</li><li>* para atingir zero ou mais de vários caracteres</li><li>| é usado como como operador OR</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 atingiu a taxa máxima que você configurou. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent está limitado a porta: TCP/%1 + + + UPnP support [ON] + Suporte UPnP [Ligado] + + + UPnP support [OFF] + Suporte UPnP [desligado] + + + NAT-PMP support [ON] + Suporte NAT-PMP [ligado] + + + NAT-PMP support [OFF] + Suporte NAT-PMP [desligado] + + + DHT support [ON], port: UDP/%1 + Suporte DHT [ON], porta: UDP/%1 + + + DHT support [OFF] + Suporte DHT [Desligado] + + + PeX support [ON] + Suporte PeX [Ligado] + + + Local Peer Discovery [ON] + Peer discovery [ligado] + + + Local Peer Discovery support [OFF] + Peer discovery [desligado] + + + Encryption support [ON] + Suporte a encriptação [Ligado] + + + Encryption support [FORCED] + Suporte a encriptação [FORÇADO] + + + Encryption support [OFF] + Suporte a encriptação [Desligado] + + + Web User Interface Error - Unable to bind Web UI to port %1 + Erro no usuário da interface web - Impossível setar para porta %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' foi removido(a) da lista de transferência e do HD. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' foi removido(a) da lista de transferência. + + + '%1' is not a valid magnet URI. + '%1' não é um URI magnético válido. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' já está na lista de download. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' continuando. (continue rápido) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' adicionado a lista de download. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Incapaz de decodificar arquivo torrent: '%1' + + + This file is either corrupted or this isn't a torrent. + O arquivo está corrompido ou não é um torrent. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>foi bloqueado pelo seu filtro de IP</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>foi banido por corromper partes</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Download recursivo do arquivo %1 embutido no torrent %2 + + + Unable to decode %1 torrent file. + Impossível decodificar %1 do arquivo torrent. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Falha no mapeamento de porta, mensagem: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Portas mapeadas com sucesso, mensagem: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Resumo rápido rejeitado para o torrent %1, tente novamente... + + + Url seed lookup failed for url: %1, message: %2 + Url falhou para: %1, mensagem: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + baixando '%1', por favor espere... + + + Using a disk cache size of %1 MiB + Usando um tamanho de cache de disco de %1 MiB + + + PeX support [OFF] + PeX suporte [Desligado] + + + Restart is required to toggle PeX support + Reinicio requerido para mudar o suporte PeX + + + The Web UI is listening on port %1 + A Web UI é escutado na porta %1 + + + HTTP user agent is %1 + O usuário agente HTTP é %1 + + + Reason: %1 + Motivo: %1 + + + Note: new trackers were added to the existing torrent. + Nota: novos trackers foram adicionados no torrent existente. + + + Note: new URL seeds were added to the existing torrent. + Nota: nova URL de seed foi adicionada ao torrent existente. + + + An I/O error occured, '%1' paused. + Um erro de I/O aconteceu, '%1' foi pausado. + + + Removing torrent %1... + Removendo torrent %1... + + + Pausing torrent %1... + Pausando torrent %1... + + + Error: The torrent %1 does not contain any file. + Erro: O torrent %1 não contém nenhum arquivo. + + + File sizes mismatch for torrent %1, pausing it. + O tamanho do arquivo para o torrent %1 está incorreto, pausando. + + + Torrent name: %1 + Nome do torrent: %1 + + + Torrent size: %1 + Tamanho do torrent: %1 + + + Save path: %1 + Caminho para salvar: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent baixado em %1. + + + Thank you for using qBittorrent. + Obrigado por usar o qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 terminou o download + + + + ConsoleDlg + + General + Gerais + + + Blocked IPs + IPs bloqueados + + + qBittorrent log viewer + Visualizador de log do qBittorrent + + + + CookiesDlg + + Cookies management + Gestão de cookies + + + Key + As in Key/Value pair + Chave + + + Value + As in Key/Value pair + Valor + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Chaves comuns para cookies são: '%1', '%2'. +Você deve buscar essa informação nas preferências do seu navegador. + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + Seu DNS dinâmico foi atualizado com sucesso. + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Erro de DNS dinâmico: O serviço está temporariamente inacessível, tentarei novamente em 30 minutos. + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Erro de DNS dinâmico: o hostname não existe na conta. + + + Dynamic DNS error: Invalid username/password. + Erro de DNS dinâmico: Usuário/Senha inválido(s). + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Erro de DNS dinâmico: qBittorrent está na lista negra por este serviço, por favor envie este bug para http://bugs.qbittorrent.org. + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Erro de DNS dinâmico: %1 foi retornado pelo serviço, por favor envie este bug para http://bugs.qbittorrent.org. + + + Dynamic DNS error: Your username was blocked due to abuse. + Erro de DNS dinâmico: Seu usuário foi bloqueado por motivo de abuso. + + + Dynamic DNS error: supplied domain name is invalid. + Erro de DNS dinâmico: O domínio é inválido. + + + Dynamic DNS error: supplied username is too short. + Erro de DNS dinâmico: Usuário informado é muito pequeno. + + + Dynamic DNS error: supplied password is too short. + Erro de DNS dinâmico: A senha é muito pequena. + + + + DownloadThread + + I/O Error + Erro de I/O + + + The remote host name was not found (invalid hostname) + O host remoto não foi encontrado (host inválido) + + + The operation was canceled + A operação foi cancelada + + + The remote server closed the connection prematurely, before the entire reply was received and processed + O servidor remoto fechou a conexão, antes de responder, receber e processar + + + The connection to the remote server timed out + Atingiu o fim do tempo da conexão com o servidor remoto + + + SSL/TLS handshake failed + SSL/TLS falhou + + + The remote server refused the connection + O servidor remoto recusou a conexão + + + The connection to the proxy server was refused + Conexão com proxy foi recusada + + + The proxy server closed the connection prematurely + Servidor proxy fechou a conexão + + + The proxy host name was not found + O host name do proxy não foi encontrado + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Fim do tempo de conexão com o proxy ou o proxy não respondeu no tempo + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + O proxy requer autenticação mas não aceitou as credenciais oferecidas + + + The access to the remote content was denied (401) + O conteúdo do acesso remoto foi negado (401) + + + The operation requested on the remote content is not permitted + A operação requerida no servidor não foi permitida + + + The remote content was not found at the server (404) + O conteúdo não foi encontrado no servidor (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + O servidor remoto requer autenticação para servir os dados mas as credenciais oferecidas não foram aceitas + + + The Network Access API cannot honor the request because the protocol is not known + O acesso a internet não honrou o pedido pois o protocolo é desconhecido + + + The requested operation is invalid for this protocol + Operação inválida para este protocolo + + + An unknown network-related error was detected + Um desconhecido erro relatado de internet foi detectado + + + An unknown proxy-related error was detected + Um desconhecido erro de proxy relatado foi detectado + + + An unknown error related to the remote content was detected + Um desconhecido erro relacionado ao conteúdo do servidor foi detectado + + + A breakdown in protocol was detected + Um erro no protocolo foi detectado + + + Unknown error + Erro desconhecido + + + + EventManager + + %1/s + e.g. 120 KiB/s + %1/s + + + Working + Trabalhando + + + Updating... + Atualizando... + + + Not working + Sem serviço + + + Not contacted yet + Não contactado ainda + + + this session + esta sessão + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seeded pelo %1 + + + %1 max + e.g. 10 max + %1 máximo + + + + ExecutionLog + + Form + Formulário + + + General + Geral + + + Blocked IPs + IPs bloqueados + + + + FeedDownloader + + RSS Feed downloader + Baixador de conteúdo RSS + + + RSS feed: + RSS feed: + + + Feed name + Nome do Feed + + + Automatically download torrents from this feed + Baixar automaticamente torrents deste feed + + + Download filters + Baixar filtros + + + Filters: + Filtros: + + + Filter settings + Configurações de filtro + + + Matches: + Correspondem: + + + Does not match: + Não correspondem: + + + Destination folder: + Pasta de destino: + + + ... + ... + + + Filter testing + Teste de filtro + + + Torrent title: + Título do torrent: + + + Result: + Resultado: + + + Test + Teste + + + Import... + Importar... + + + Export... + Exportar... + + + Rename filter + Renomear filtro + + + Remove filter + Remover filtro + + + Add filter + Adicionar filtro + + + + FeedDownloaderDlg + + New filter + Novo filtro + + + Please choose a name for this filter + Por favor escolha um nome para este filtro + + + Filter name: + Nome do filtro: + + + Invalid filter name + Nome inválido para o filtro + + + The filter name cannot be left empty. + O nome do filtro não pode ser vazio. + + + This filter name is already in use. + Este nome de filtro já está sendo usado. + + + Filter testing error + Erro ao testar o filtro + + + Please specify a test torrent name. + Por favor especifique um nome para o torrent. + + + matches + assemelha + + + does not match + não assemelha + + + Select file to import + Selecione arquivo a importar + + + Filters Files + Arquivos de filtro + + + Import successful + Importado com sucesso + + + Filters import was successful. + Filtros importados com sucesso. + + + Import failure + Falha ao importar + + + Filters could not be imported due to an I/O error. + Filtros não podem ser importados por um erro de entrada e saída. + + + Select destination file + Seleciona arquivo de destino + + + Export successful + Exportado com sucesso + + + Filters export was successful. + A exportação foi executada com sucesso. + + + Export failure + Falha na exportação + + + Filters could not be exported due to an I/O error. + Os filtros não puderam ser exportados por um erro de entrada e saída. + + + Choose save path + Escolha o caminho de salvamento + + + + FeedList + + Unread + Não lido + + + + FeedListWidget + + RSS feeds + RSS feeds + + + Unread + Não lido + + + + GUI + + Open Torrent Files + Abrir Arquivos Torrent + + + Torrent Files + Arquivos Torrent + + + qBittorrent + qBittorrent + + + Transfers + Transferências + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Velocidade de download: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Velocidade de Upload: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 download finalizado. + + + I/O Error + i.e: Input/Output Error + Erro de Entrada/Saída + + + Search + Busca + + + RSS + RSS + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Erro de I/O no torrent %1. +Motivo: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Erro no download da URL + + + Couldn't download file at url: %1, reason: %2. + Não pude baixar arquivo em: %1, motivo: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Options were saved successfully. + Opções salvas com sucesso. + + + Download completion + Completação de download + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Muitos arquivos estão atualmente sendo transferidos.(new line) +Está certo que quer sair do qBittorrent? + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Limite global de upload + + + Global Download Speed Limit + Limite global de download + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Down: %2/s, Up: %3/s) + + + Recursive download confirmation + Confirmação de download recursivo + + + The torrent %1 contains torrent files, do you want to proceed with their download? + O torrent %1 contém arquivos torrent, continua com este download? + + + Torrent file association + Associação de arquivo torrent + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent não é sua aplicação padrão para arquivos torrent e links magnéticos. +Gostaria de associar o qBittorrent para arquivos torrent e links magnéticos? + + + Transfers (%1) + Transferências (%1) + + + Yes + Sim + + + No + Não + + + Never + Nunca + + + Always + Sempre + + + Exiting qBittorrent + Saindo do qBittorrent + + + Set the password... + Configurar a senha... + + + Password update + Atualiza senha + + + The UI lock password has been successfully updated + A senha de travamento da UI foi atualizada com sucesso + + + UI lock password + Senha de travamento da UI + + + Please type the UI lock password: + Por favor digite sua senha UI: + + + Invalid password + Senha inválida + + + The password is invalid + A senha está inválida + + + A newer version is available + Uma nova versão está disponível + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Uma nova versão do qBittorrent está disponível no Souceforge. +Gostaria de atualizar o qBittorrrent para a versão %1? + + + Impossible to update qBittorrent + Impossível atualizar qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent falhou para atualizar, motivo: %1 + + + + GeoIP + + Australia + Austrália + + + Argentina + Argentina + + + Austria + Áustria + + + United Arab Emirates + Emirados Árabes Unidos + + + Brazil + Brasil + + + Bulgaria + Bulgária + + + Belarus + Belarus + + + Belgium + Bélgica + + + Bosnia + Bósnia + + + Canada + Canadá + + + Czech Republic + República Tcheca + + + China + China + + + Costa Rica + Costa Rica + + + Switzerland + Suíça + + + Germany + Alemanha + + + Denmark + Dinamarca + + + Algeria + Argélia + + + Spain + Espanha + + + Egypt + Egito + + + Finland + Finlândia + + + France + França + + + United Kingdom + Reino Unido + + + Greece + Grécia + + + Georgia + Geórgia + + + Hungary + Hungria + + + Croatia + Croácia + + + Italy + Itália + + + India + Índia + + + Israel + Israel + + + Ireland + Irlanda + + + Iceland + Islândia + + + Indonesia + Indonésia + + + Japan + Japão + + + South Korea + Coréia do Sul + + + Luxembourg + Luxemburgo + + + Malaysia + Malásia + + + Mexico + México + + + Serbia + Sérvia + + + Morocco + Marrocos + + + Netherlands + Holanda + + + Norway + Noruéga + + + New Zealand + Nova Zelândia + + + Portugal + Portugal + + + Poland + Polônia + + + Pakistan + Paquistão + + + Philippines + Filipinas + + + Russia + Rússia + + + Romania + Romênia + + + France (Reunion Island) + França + + + Sweden + Suécia + + + Slovakia + Eslováquia + + + Singapore + Singapura + + + Slovenia + Eslovênia + + + Taiwan + Taiwan + + + Turkey + Turquia + + + Thailand + Tailândia + + + USA + Estados Unidos da América + + + Ukraine + Ucrânia + + + South Africa + Africa do Sul + + + Saudi Arabia + Arábia Saudita + + + + HeadlessLoader + + Information + Informação + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Para controlar o qBittorrent acesse a UI Web em http://localhost:%1 + + + The Web UI administrator user name is: %1 + O nome do usuário administrador da UI Web é: %1 + + + The Web UI administrator password is still the default one: %1 + A senha do usuário administrador da UI Web ainda é a padrão: %1 + + + This is a security risk, please consider changing your password from program preferences. + Este é um risco de segurança, por favor considere mudar sua senha nas preferências do programa. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + Seu endereço IP fo banido após várias tentativas de autenticação. + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - T: %2 + + + + HttpServer + + File + Arquivo + + + Edit + Editar + + + Help + Ajuda + + + Delete from HD + Deletar do HD + + + Download Torrents from their URL or Magnet link + Baixar torrents da URL or Link Magnético + + + Only one link per line + Somente um link por linha + + + Download + Baixar + + + Download local torrent + Baixar torrent local + + + Torrent files were correctly added to download list. + Torrent adicionado corretamente a lista de download. + + + Point to torrent file + Ponto para o arquivo torrent + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Deseja mesmo deletar os torrents selecionados da lista e do HD? + + + Download rate limit must be greater than 0 or disabled. + Taxa de limite de download deve ser maior que 0 ou desabilitado. + + + Upload rate limit must be greater than 0 or disabled. + Taxa de limite de upload deve ser maior que 0 ou desabilitado. + + + Maximum number of connections limit must be greater than 0 or disabled. + O número máximo de conexões deve ser maior que 0 ou desabilitado. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + O número máximo de conexões por torrent deve ser maior que 0 ou desabilitado. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + O número máximo de slots de upload por torrent deve ser maior que 0 ou desabilitado. + + + Unable to save program preferences, qBittorrent is probably unreachable. + Impossível salvar preferências do programa, qBittorrent provavelmente está inatingível. + + + Language + Linguagem + + + The port used for incoming connections must be greater than 1024 and less than 65535. + A porta para conexões de entrada deve ser maior que 1024 e menos que 65535. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + A porta usada para a UI Web deve ser maior que 1024 e menor que 65535. + + + The Web UI username must be at least 3 characters long. + O nome de usuário para a UI Web deve conter mais que 3 caracteres. + + + The Web UI password must be at least 3 characters long. + A senha do usuário da UI Web deve ser maior que 3 caracteres. + + + Downloaded + Is the file downloaded or not? + Baixado + + + Save + Salvar + + + qBittorrent client is not reachable + Cliente qBittorrent não está alcançável + + + HTTP Server + Servidor HTTP + + + Torrent path + Caminho torrent + + + Torrent name + Nome do torrent + + + The following parameters are supported: + Os parâmetros a seguir são suportados: + + + + LegalNotice + + Legal Notice + Noticia legal + + + Legal notice + Noticia legal + + + Cancel + Cancele + + + I Agree + Eu aceito + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent é um programa de compartilhamento de arquivos. Quando você o usa, os dados enviados estarão disponíveis para outros ue fizerem o mesmo upload. Todo conteúdo compartilhado por você é de sua inteira responsabilidade. + +Nenhum outro aviso será dado. + + + Press %1 key to accept and continue... + Pressione a tecla %1 para aceitar e continuar... + + + + LineEdit + + Clear the text + Limpa o texto + + + + MainWindow + + &Edit + &Editar + + + &File + &Arquivo + + + &Help + &Ajuda + + + Preview file + Arquivo de pré-visualização + + + Clear log + Limpar log + + + Decrease priority + Diminuir prioridade + + + Increase priority + Aumentar prioridade + + + &Tools + &Ferramentas + + + &View + &Ver + + + &Add File... + &Adicionar Arquivo... + + + E&xit + S&air + + + &Options... + &Opções... + + + Add &URL... + Adicionar &URL... + + + Torrent &creator + &Criar torrent + + + Set upload limit... + Configurar limite de upload... + + + Set download limit... + Configurar limite de download... + + + Set global download limit... + Configurar limite global de download... + + + Set global upload limit... + Configurar limite global de upload... + + + &Log viewer... + &Visualizador de log... + + + Top &tool bar + Barra de &Ferramentas Início + + + Display top tool bar + Exibir Barra de Ferramentas Início + + + &Speed in title bar + &Velocidade na barra de título + + + Show transfer speed in title bar + Mostrar velocidade de transferência na barra de título + + + Alternative speed limits + Limites de velocidade alternativos + + + &About + &Sobre + + + &Pause + &Pausar + + + &Delete + &Remover + + + P&ause All + P&ausar Todos + + + Visit &Website + Visitar &Website + + + Report a &bug + Relatar um &erro + + + &Documentation + &Documentação + + + &RSS reader + Leitor de &RSS + + + Search &engine + Ferramenta de &busca + + + Log viewer + Visualizador de Log + + + Lock qBittorrent + Travar o qBittorrent + + + Ctrl+L + Ctrl+L + + + Shutdown computer when downloads complete + Desligar computador quando terminar os downloads + + + &Resume + &Resumir + + + R&esume All + R&esume Todos + + + Shutdown qBittorrent when downloads complete + Desligar qBittorrent quando terminar os downloads + + + Exit + Sair + + + Import torrent... + Importar torrent... + + + Donate money + Doar dinheiro + + + If you like qBittorrent, please donate! + Se você curte qBittorrent, por favor faça sua doação! + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + Configurar a senha... + + + Transfers + Transferências + + + Torrent file association + Associação de arquivo torrent + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent não é sua aplicação padrão para arquivos torrent e links magnéticos. +Gostaria de associar o qBittorrent para arquivos torrent e links magnéticos? + + + UI lock password + Senha de travamento da UI + + + Please type the UI lock password: + Por favor digite sua senha UI: + + + Password update + Atualiza senha + + + The UI lock password has been successfully updated + A senha de travamento da UI foi atualizada com sucesso + + + RSS + RSS + + + Search + Busca + + + Transfers (%1) + Transferências (%1) + + + Download completion + Completação de download + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 teve o download finalizado. + + + I/O Error + i.e: Input/Output Error + Erro de I/O + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Ocorreu um erro de I/O no torrent %1. +Motivo: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Confirmação de download recursivo + + + The torrent %1 contains torrent files, do you want to proceed with their download? + O torrent %1 contém arquivos torrent, continua com este download? + + + Yes + Sim + + + No + Não + + + Never + Nunca + + + Url download error + Erro no download da URL + + + Couldn't download file at url: %1, reason: %2. + Não foi possível baixar arquivo no url: %1, motivo: %2. + + + Global Upload Speed Limit + Velocidade limite global de upload + + + Global Download Speed Limit + Velocidade limite global de download + + + Invalid password + Senha inválida + + + The password is invalid + A senha está inválida + + + Exiting qBittorrent + Saindo do qBittorrent + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Muitos arquivos estão atualmente sendo transferidos. +Quer mesmo sair do qBittorrent? + + + Always + Sempre + + + Open Torrent Files + Abrir Arquivos Torrent + + + Torrent Files + Arquivos Torrent + + + Options were saved successfully. + Opções foram salvas com sucesso. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Velocidade de download: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Velocidade de Upload: %1 KiB/s + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Down: %2/s, Up: %3/s) + + + A newer version is available + Uma nova versão está disponível + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Uma nova versão do qBittorrent está disponível no Souceforge. +Gostaria de atualizar o qBittorrrent para a versão %1? + + + Impossible to update qBittorrent + Impossível atualizar qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent falhou para atualizar, motivo: %1 + + + &Add torrent file... + &Adicionar arquivo torrent... + + + Add &link to torrent... + Adicionar &link para torrent... + + + Import existing torrent... + Importar torrent existente... + + + Execution &Log + Execução &Log + + + Execution Log + Execução Log + + + Auto-Shutdown on downloads completion + Desligar automaticamente quando completar os downloads + + + Exit qBittorrent + Sair do qBittorrent + + + Suspend system + Suspender o sistema + + + Shutdown system + Desligar o sistema + + + Disabled + Desabilitado + + + The password should contain at least 3 characters + A senha deve conter ao menos 3 caracteres + + + + PeerAdditionDlg + + Invalid IP + IP inválido + + + The IP you provided is invalid. + O IP informado é inválido. + + + + PeerListDelegate + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + Cliente + + + Progress + i.e: % downloaded + Progresso + + + Down Speed + i.e: Download speed + Velocidade de download + + + Up Speed + i.e: Upload speed + Velocidade de upload + + + Downloaded + i.e: total data downloaded + Baixado + + + Uploaded + i.e: total data uploaded + Subido + + + Ban peer permanently + Banir fonte permanentemente + + + Peer addition + Adição de fonte + + + The peer was added to this torrent. + A fonte foi adicionada para este torrent. + + + The peer could not be added to this torrent. + A fonte não pode ser adicionada a este torrent. + + + Are you sure? -- qBittorrent + Tem certeza? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + Deseja mesmo banir permanentemente a fonte selecionada? + + + &Yes + &Sim + + + &No + &Não + + + Manually banning peer %1... + Manualmente banindo fonte %1... + + + Upload rate limiting + Limitando taxa de upload + + + Download rate limiting + Limitando taxa de download + + + Add a new peer... + Adicionar um novo peer... + + + Limit download rate... + Taxa de limite de download... + + + Limit upload rate... + Taxa de limite de upload... + + + Copy IP + Copiar IP + + + Connection + Conexão + + + + Preferences + + UI + UI + + + Downloads + Downloads + + + Connection + Conexão + + + Bittorrent + Bittorrent + + + Proxy + Proxy + + + Web UI + UI Web + + + Language: + Linguagem: + + + (Requires restart) + (Necessário reiniciar) + + + Visual style: + Estilo visual: + + + Transfer list + Lista de transferência + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Usar linhas alternadas de cor + + + File system + Sistema de arquivos + + + Torrent queueing + Torrent esperando + + + Maximum active downloads: + Máximo de downloads ativos: + + + Maximum active uploads: + Máximo de uploads ativos: + + + Maximum active torrents: + Máximo de torrents ativos: + + + When adding a torrent + Quando adicionar um torrent + + + Display torrent content and some options + Mostrar conteúdo torrent e mais opções + + + Listening port + Escutando porta + + + Port used for incoming connections: + Porta usada para conexões de entrada: + + + Random + Aleatório + + + Enable UPnP port mapping + Habilitar mapeamento de porta UPnP + + + Enable NAT-PMP port mapping + Habilitar mapeamento de porta NAT-PMP + + + Connections limit + Limite de conexões + + + Global maximum number of connections: + Número máximo global de conexões: + + + Maximum number of connections per torrent: + Número máximo de conexões por torrent: + + + Maximum number of upload slots per torrent: + Número máximo de slots de upload por torrent: + + + Upload: + Upload: + + + Download: + Download: + + + KiB/s + KiB/s + + + Bittorrent features + Recursos Bittorrent + + + Enable DHT network (decentralized) + Habilitar DHT network (descentralizado) + + + Use a different port for DHT and Bittorrent + Usar uma porta diferente para DHT e Bittorrent + + + DHT port: + Porta DHT: + + + Enable Peer Exchange / PeX (requires restart) + Habilitar Peer Exchange / PeX (requer reinício) + + + Enable Local Peer Discovery + Habilitar Local Peer Discovery + + + Enabled + Habilitado + + + Forced + Forçado + + + Disabled + Desabilitado + + + Type: + Tipo: + + + (None) + (Nenhum) + + + HTTP + HTTP + + + Port: + Porta: + + + Authentication + Autenticação + + + Username: + Nome de usuário: + + + Password: + Senha: + + + SOCKS5 + SOCKS5 + + + HTTP Server + Servidor HTTP + + + Filter path (.dat, .p2p, .p2b): + Caminho do filtro (.dat, .p2p, .p2b): + + + HTTP Communications (trackers, Web seeds, search engine) + Comunicações HTTP (trackers, Web seeds, mecanismo de busca) + + + Host: + Servidor: + + + Peer Communications + Comunicações de Peer + + + SOCKS4 + SOCKS4 + + + Speed + Velocidade + + + Global speed limits + Limite global de velocidade + + + Alternative global speed limits + Limite alternativo de velocidade global + + + to + time1 to time2 + para + + + Every day + Todo dia + + + Week days + Dias da semana + + + Week ends + Fins de semana + + + Advanced + Avançado + + + Copy .torrent files to: + Copiar arquivos .torrent para: + + + Remove folder + Remover pasta + + + No action + Sem ação + + + Options + Opções + + + Visual Appearance + Aparência Visual + + + Action on double-click + Ação do duplo clique + + + Downloading torrents: + Baixando torrents: + + + Start / Stop + Iniciar / Parar + + + Open destination folder + Abrir pasta de destino + + + Completed torrents: + Torrents completos: + + + Desktop + Área de trabalho + + + Show splash screen on start up + Mostrar imagem de início ao ligar + + + Start qBittorrent minimized + Iniciar qBittorrent minimizado + + + Show qBittorrent icon in notification area + Mostrar ícone na bandeja + + + Minimize qBittorrent to notification area + Minimizar qBittorrent na área de notificação + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Fechar qBittorrent para área de notificação + + + Do not start the download automatically + The torrent will be added to download list in pause state + Não iniciar downloads automaticamente + + + Save files to location: + Salvar arquivos na pasta: + + + Append the label of the torrent to the save path + Acrescentar o rótulo do torrent para o caminho de salvamento + + + Pre-allocate disk space for all files + Pré-alocar espaço em disco para todos os arquivos + + + Keep incomplete torrents in: + Manter torrents incompletos em: + + + Append .!qB extension to incomplete files' names + Acrescentar extensão .!qB para nomes de arquivos incompletos + + + Automatically add torrents from: + Adicionar automaticamente torrents de: + + + Add folder... + Adicionar pasta... + + + IP Filtering + Filtro de IP + + + Schedule the use of alternative speed limits + Programar o uso de limite de velocidades alternativas + + + from + from (time1 to time2) + de + + + When: + Quando: + + + Look for peers on your local network + Buscar por peers na rede local + + + Protocol encryption: + Protocolo de encriptação: + + + Enable Web User Interface (Remote control) + Habilitar interface de usuário de rede (Controle Remoto) + + + Share ratio limiting + Limitando taxa de compartilhamento + + + Seed torrents until their ratio reaches + Compartilhar torrents até que sua taxa de compartilhamento atinja + + + then + então + + + Pause them + Pause + + + Remove them + Remove + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Trocar peers com clientes compatíveis com qBittorrent (µTorrent, Vuze, ...) + + + Email notification upon download completion + Notificação por email quando completar o download + + + Destination email: + Email de destino: + + + SMTP server: + Servidor SMTP: + + + Run an external program on torrent completion + Rodar um programa externo quando completar o torrent + + + Use %f to pass the torrent path in parameters + Use %f para passar o caminho do torrent em parâmetros + + + Proxy server + Servidor proxy + + + BitTorrent + BitTorrent + + + Start / Stop Torrent + Iniciar / Parar Torrent + + + Use UPnP / NAT-PMP port forwarding from my router + User UPnP / NAT-PMP redirecionamento de porta do meu roteador + + + Privacy + Privacidade + + + Enable DHT (decentralized network) to find more peers + Habilitar DHT (rede decentralizada) para encontrar mais peers + + + Use a different port for DHT and BitTorrent + Usar uma porta diferente para DHT e BitTorrent + + + Enable Peer Exchange (PeX) to find more peers + Habilitar Peer Exchange (PeX) para encontrar mais peers + + + Enable Local Peer Discovery to find more peers + Habilitar Local Peer Discovery para encontrar mais peers + + + Encryption mode: + Modo de encriptação: + + + Prefer encryption + Encriptação escolhida + + + Require encryption + Encriptação requerida + + + Disable encryption + Desabilitar encriptação + + + User Interface + Interface de usuário + + + Reload the filter + Recarregar o filtro + + + Behavior + Comportamento + + + Language + Linguagem + + + Power Management + Gestão de Energia + + + Inhibit system sleep when torrents are active + Sistema de espera inibe quando torrents estão activos + + + Bypass authentication for localhost + Desvio de autenticação para localhost + + + Ask for program exit confirmation + Solicite confirmação para fechar o programa + + + Use monochrome system tray icon (requires restart) + Use o ícone da bandeja do sistema monocromático (requer reinicialização) + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Os parâmetros a seguir são suportados:(new line) +<ul>(new line) +<li>%f: Caminho do Torrent</li>(new line) +<li>%n: Nome do Torrent</li>(new line) +</ul> + + + Tray icon style: + Estilo do icone da bandeja: + + + Normal + Normal + + + Monochrome (Dark theme) + Monocromático (Dark theme) + + + Monochrome (Light theme) + Monocromático (Light theme) + + + This server requires a secure connection (SSL) + Este servidor espera por uma conexão segura (SSL) + + + User Interface Language: + Linguagem da interface de usuário: + + + Transfer List + Lista de transferência + + + Show qBittorrent in notification area + Mostrar qBittorrent na área de notificação + + + Hard Disk + Disco Rígido + + + Listening Port + Escutando Porta + + + Connections Limits + Limites de Conexão + + + Proxy Server + Servidor Proxy + + + Torrent Queueing + Torrents na espera + + + Share Ratio Limiting + Taxa limite de compartilhamento + + + Use UPnP / NAT-PMP to forward the port from my router + Use UPnP / NAT-PMP para redirecionar a porta do meu roteador + + + Update my dynamic domain name + Atualize meu nome de domínio dinâmico + + + Service: + Serviço: + + + Register + Registro + + + Domain name: + Nome de domínio: + + + Global Rate Limits + Limite Global + + + Apply rate limit to uTP connections + Aplicar taxa limite para conexões uTP + + + Apply rate limit to transport overhead + Aplicar taxa limite para o transporte fora da cabeça + + + Alternative Global Rate Limits + Taxa limite global alternativa + + + Schedule the use of alternative rate limits + Agende para usar taxas limite alternativas + + + Enable bandwidth management (uTP) + Habilitar manutenção de largura de banda (uTP) + + + Otherwise, the proxy server is only used for tracker connections + Então, o servidor proxy é somente usado para conexões de tracker + + + Use proxy for peer connections + Usar proxy para conexões de peer + + + Append .!qB extension to incomplete files + Adicionar extensão .!qB para arquivos incompletos + + + Use HTTPS instead of HTTP + Usar HTTPS ao invez de HTTP + + + Import SSL Certificate + Importar certificado SSL + + + Import SSL Key + Importar chave SSL + + + Certificate: + Certificado: + + + Key: + Chave: + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Informações sobre certificados</a> + + + + PreviewSelect + + Name + Nome + + + Size + Tamanho + + + Progress + Progresso + + + Preview impossible + Pré-visualização impossível + + + Sorry, we can't preview this file + Desculpe, não é possível pré-visualizar esse arquivo + + + + ProgramUpdater + + Could not create the file %1 + Não pude criar o arquivo %1 + + + Failed to download the update at %1 + %1 is an URL + Falha para baixar a atualização em %1 + + + + PropListDelegate + + Normal + Normal (priority) + Normal + + + High + High (priority) + Alta + + + Maximum + Maximum (priority) + Máxima + + + Not downloaded + Não baixado + + + Mixed + Mixed (priorities + Misto + + + + PropTabBar + + General + Geral + + + Trackers + Rastreadores + + + Peers + Peers + + + URL Seeds + URL semeadores + + + Files + Arquivos + + + HTTP Sources + Fontes HTTP + + + Content + Conteúdo + + + + PropertiesWidget + + Save path: + Caminho de salvamento: + + + Torrent hash: + Mistura do Torrent: + + + Comment: + Comentário: + + + Share ratio: + Taxa de Compartilhamento: + + + General + Gerais + + + Trackers + Rastreadores + + + URL seeds + URL fonte + + + Files + Arquivos + + + Priority + Prioridade + + + New url seed + New HTTP source + Nova url de compartilhador + + + New url seed: + Nova url de compartilhador: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + Essa url de compartilhador já está na lista. + + + Choose save path + Escolha um caminho de salvamento + + + Save path creation error + Erro ao criar caminho de salvamento + + + Could not create the save path + Não foi possível criar caminho de salvamento + + + Downloaded: + Baixado: + + + Transfer + Transferência + + + Uploaded: + Subido: + + + Wasted: + Gasto: + + + UP limit: + Limite de UP: + + + DL limit: + Limite de DL: + + + Time elapsed: + Tempo passado: + + + Connections: + Conexões: + + + Information + Informação + + + Created on: + Criado em: + + + Peers + Fontes + + + Normal + Normal + + + Maximum + Máximo + + + High + Alto + + + this session + esta sessão + + + %1 max + e.g. 10 max + %1 máximo + + + Availability: + Disponível: + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seeded pelo %1 + + + Rename... + Renomear... + + + New name: + Novo nome: + + + The file could not be renamed + O arquivo não pode ser renomeado + + + This name is already in use in this folder. Please use a different name. + Este nome já está sendo utilizado nessa pasta. Por favor use um nome diferente. + + + The folder could not be renamed + A pasta não pode ser renomeada + + + Rename the file + Renomeie o arquivo + + + This file name contains forbidden characters, please choose a different one. + O arquivo contem caracteres desconhecidos, por favor use um nome diferente. + + + I/O Error + Erro de entrada e saída + + + This file does not exist yet. + Este arquivo não existe. + + + This folder does not exist yet. + Esta pasta não existe. + + + Reannounce in: + Reanunciar em: + + + Select All + Seleciona todos + + + Select None + Selecionar nenhum + + + Do not download + Não baixar + + + Pieces size: + Tamanho dos pedaços: + + + Time active: + Time (duration) the torrent is active (not paused) + Tempo ativo: + + + Torrent content: + Conteúdo do torrent: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1 atingiu a taxa máxima que você configurou. + + + Removing torrent %1... + Removendo torrent %1... + + + Pausing torrent %1... + Pausando torrent %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent está limitado a porta: TCP/%1 + + + UPnP support [ON] + Suporte UPnP [Ligado] + + + UPnP support [OFF] + Suporte UPnP [desligado] + + + NAT-PMP support [ON] + Suporte NAT-PMP [ligado] + + + NAT-PMP support [OFF] + Suporte NAT-PMP [desligado] + + + HTTP user agent is %1 + O usuário agente HTTP é %1 + + + Using a disk cache size of %1 MiB + Usando um tamanho de cache de disco de %1 MiB + + + DHT support [ON], port: UDP/%1 + Suporte DHT [ON], porta: UDP/%1 + + + DHT support [OFF] + Suporte DHT [Desligado] + + + PeX support [ON] + Suporte PeX [Ligado] + + + PeX support [OFF] + PeX suporte [Desligado] + + + Restart is required to toggle PeX support + Reinicio requerido para mudar o suporte PeX + + + Local Peer Discovery [ON] + Peer discovery [ligado] + + + Local Peer Discovery support [OFF] + Peer discovery [desligado] + + + Encryption support [ON] + Suporte a encriptação [Ligado] + + + Encryption support [FORCED] + Suporte a encriptação [FORÇADO] + + + Encryption support [OFF] + Suporte a encriptação [Desligado] + + + Embedded Tracker [ON] + Tracker embutido [ligado] + + + Failed to start the embedded tracker! + Falha para iniciar o tracker embutido! + + + Embedded Tracker [OFF] + Tracker embutido [desligado] + + + The Web UI is listening on port %1 + A Web UI é escutado na porta %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Erro no usuário da interface web - Impossível setar para porta %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' foi removido(a) da lista de transferência e do HD. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' foi removido(a) da lista de transferência. + + + '%1' is not a valid magnet URI. + '%1' não é um URI magnético válido. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' já está na lista de download. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' continuando. (continue rápido) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' adicionado a lista de download. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Incapaz de decodificar arquivo torrent: '%1' + + + This file is either corrupted or this isn't a torrent. + O arquivo está corrompido ou não é um torrent. + + + Error: The torrent %1 does not contain any file. + Erro: O torrent %1 não contém nenhum arquivo. + + + Note: new trackers were added to the existing torrent. + Nota: novos trackers foram adicionados no torrent existente. + + + Note: new URL seeds were added to the existing torrent. + Nota: nova URL de seed foi adicionada ao torrent existente. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>foi bloqueado pelo seu filtro de IP</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>foi banido por corromper partes</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Download recursivo do arquivo %1 embutido no torrent %2 + + + Unable to decode %1 torrent file. + Impossível decodificar %1 do arquivo torrent. + + + Torrent name: %1 + Nome do torrent: %1 + + + Torrent size: %1 + Tamanho do torrent: %1 + + + Save path: %1 + Caminho para salvar: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent baixado em %1. + + + Thank you for using qBittorrent. + Obrigado por usar o qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 terminou o download + + + An I/O error occured, '%1' paused. + Um erro de I/O aconteceu, '%1' foi pausado. + + + Reason: %1 + Motivo: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Falha no mapeamento de porta, mensagem: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Portas mapeadas com sucesso, mensagem: %1 + + + File sizes mismatch for torrent %1, pausing it. + O tamanho do arquivo para o torrent %1 está incorreto, pausando. + + + Fast resume data was rejected for torrent %1, checking again... + Resumo rápido rejeitado para o torrent %1, tente novamente... + + + Url seed lookup failed for url: %1, message: %2 + Url falhou para: %1, mensagem: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + baixando '%1', por favor espere... + + + The network interface defined is invalid: %1 + A interface de rede definida é inválida: %1 + + + Trying any other network interface available instead. + Tentando outra interface de rede disponível. + + + Listening on IP address %1 on network interface %2... + Escutando no endereço IP %1 na interface %2... + + + Failed to listen on network interface %1 + Falha ao escutar na interface de rede %1 + + + UPnP / NAT-PMP support [ON] + Suporte a UPnp / NAT-PMP [ON] + + + UPnP / NAT-PMP support [OFF] + Suporte a UPnp / NAT-PMP [OFF] + + + Local Peer Discovery support [ON] + Suporte a Local Peer Discovery [ON] + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Analisado com sucesso o filtro de IP enviado: %1 regras foram aplicadas. + + + Error: Failed to parse the provided IP filter. + Erro: Falha ao analisar o filtro de IP. + + + Reporting IP address %1 to trackers... + Reportando endereço IP %1 aos trackers... + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + O computador entrará em modo de espera a não ser que você cancele durante os próximos 15 segundos... + + + The computer will now be switched off unless you cancel within the next 15 seconds... + O computador irá se desligar a não ser que você cancele durante os próximos 15 segundos... + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent irá sair a não ser que você cancele durante os próximos 15 segundos... + + + + RSS + + Search + Busca + + + Delete + Apagar + + + Rename + Renomear + + + Refresh RSS streams + Atualizar RSS streams + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(duplo-clique para baixar)</span></p></body></html> + + + Download torrent + Baixar torrent + + + Open news URL + Abrir novas URL + + + Copy feed URL + Copiar URL do feed + + + New subscription + Nova inscrição + + + Mark items read + Marcar ítems lidos + + + Update all + Atualizar todos + + + Update all feeds + Atualizar todos feeds + + + RSS feeds + RSS feeds + + + Update + Atualiza + + + Feed URL + URL do feed + + + Article title + Título do artigo + + + Rename... + Renomear... + + + New subscription... + Nova inscrição... + + + RSS feed downloader... + Baixador de feed RSS... + + + New folder... + Nova pasta... + + + Manage cookies... + Administrar cookies... + + + Settings... + Configurações... + + + RSS Downloader... + Baixador RSS... + + + + RSSImp + + Please type a rss stream url + Digite uma url de stream rss + + + Stream URL: + Stream URL: + + + Are you sure? -- qBittorrent + Tem certeza? -- qBittorrent + + + &Yes + &Sim + + + &No + &Não + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + Este rss feed já está na lista. + + + Date: + Data: + + + Author: + Autor: + + + Please choose a folder name + Por favor escolha um nome de pasta + + + Folder name: + Nome da pasta: + + + New folder + Nova pasta + + + Are you sure you want to delete these elements from the list? + Está certo de que deseja deletar esses elementos da lista ? + + + Are you sure you want to delete this element from the list? + Deseja realmente deletar esse ítem da lista? + + + Please choose a new name for this RSS feed + Por favor escolha um novo nome para este feed RSS + + + New feed name: + Novo nome do feed: + + + Name already in use + Novo já está em uso + + + This name is already used by another item, please choose another one. + Este nome já está sendo usado por outro ítem, por favor escolha outro. + + + Overwrite attempt + Atenção sobescrevendo + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Você não pode sobescrever o ítem %1. + + + Unread + Não lido + + + + RssArticle + + No description available + Nenhuma descrição disponível + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + Baixando automaticamente o torrent %1 do RSS feed %2... + + + + RssItem + + No description available + Nenhuma descrição disponível + + + + RssSettings + + RSS Reader Settings + Configurações de Leitor de RSS + + + RSS feeds refresh interval: + Intervalo de atualização de feeds RSS: + + + minutes + minutos + + + Maximum number of articles per feed: + Número máximo de artigos por feed: + + + + RssSettingsDlg + + RSS Reader Settings + Configurações de Leitor de RSS + + + RSS feeds refresh interval: + Intervalo de atualização de feeds RSS: + + + minutes + minutos + + + Maximum number of articles per feed: + Número máximo de artigos por feed: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Baixando automaticamente o torrent %1 do RSS feed %2... + + + + ScanFoldersModel + + Watched Folder + Pasta visualizada + + + Download here + Baixar aqui + + + + SearchCategories + + All categories + Todas categorias + + + Movies + Filmes + + + TV shows + Shows de TV + + + Music + Música + + + Games + Jogos + + + Anime + Anime + + + Software + Programa + + + Pictures + Imagens + + + Books + Livros + + + + SearchEngine + + Empty search pattern + Padrão de busca vazio + + + Please type a search pattern first + Por favor digite um padrão de busca primeiro + + + Results + Resultados + + + Searching... + Buscando... + + + Cut + Corta + + + Copy + Copia + + + Paste + Cola + + + Clear field + Limpa campo + + + Clear completion history + Limpar lista dos completados + + + Search Engine + Mecanismo de Busca + + + Search has finished + Busca finalizada + + + An error occured during search... + Um erro ocorreu durante a busca... + + + Search aborted + Busca abortada + + + Search returned no results + A busca não retornou resultados + + + Results + i.e: Search results + Resultados + + + Unknown + Desconhecido + + + Search + Busca + + + Download error + Erro no download + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + A instalação do Python não pode ser baixada, razão: %1. +Por favor instale manualmente. + + + Missing Python Interpreter + Faltando interpretador Python + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x é requerido para você poder usar a busca mas não parece estar instalado. +Gostaria de instalar agora? + + + Confirmation + Confirmação + + + Are you sure you want to clear the history? + Deseja realmente limpar o histórico? + + + + SearchTab + + Name + i.e: file name + Nome + + + Size + i.e: file size + Tamanho + + + Seeders + i.e: Number of full sources + Compartilhadores completos + + + Leechers + i.e: Number of partial sources + Compartilhadores parciais + + + Search engine + Mecanismo de busca + + + + ShutdownConfirmDlg + + Shutdown confirmation + Confirmação de desligamento + + + + SpeedLimitDialog + + KiB/s + KiB/s + + + + StatusBar + + Connection status: + Estado da conexão: + + + No direct connections. This may indicate network configuration problems. + Sem conexões diretas. Talvez tenha algo errado em sua configuração. + + + DHT: %1 nodes + DHT: %1 nos + + + Connection Status: + Estado da conexão: + + + Online + Online + + + Global Download Speed Limit + Limite de Velocidade Global de Download + + + Global Upload Speed Limit + Limite de Velocidade Global de Upload + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - T: %2 + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + D: %1 B/s - T: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + U: %1 B/s - T: %2 + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Offline. Isto acontece quando o qBittorrent falha para escutar na porta selecionada para conexões de entrada. + + + Click to disable alternative speed limits + Clique para desabilitar limite alternativo + + + Click to enable alternative speed limits + Clique para habilitar limite alternativo + + + qBittorrent needs to be restarted + qBittorrent precisa ser reiniciado + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent foi atualizado e precisa ser reiniciado para que as mudanças sejam aplicadas. + + + Click to switch to alternative speed limits + Clique aqui para mudar para os limites de velocidade alternativa + + + Click to switch to regular speed limits + Clique aqui para alternar para regular os limites de velocidade + + + %1/s + Per second + %1/s + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + Selecione uma pasta para adicionar ao torrent + + + Select a file to add to the torrent + Selecione um arquivo para adicionar ao torrent + + + Please type an announce URL + Digite uma url anunciada + + + Announce URL: + Tracker URL + Url anunciada: + + + Please type a web seed url + Digite uma url de compartilhador web + + + Web seed URL: + Url de compartilhador web: + + + No input path set + Nenhum caminho de entrada selecionado + + + Please type an input path first + Digite primeiro um caminho de entrada + + + Select destination torrent file + Selecione o arquivo torrent de destino + + + Torrent Files + Arquivos Torrent + + + Torrent creation + Criação de torrent + + + Torrent creation was unsuccessful, reason: %1 + A criação do torrent não foi possível, motivo: %1 + + + Created torrent file is invalid. It won't be added to download list. + Torrent criado é inválido. Não será adicionado a lista de download. + + + Torrent was created successfully: + Torrent foi criado com sucesso: + + + + TorrentFilesModel + + Name + Nome + + + Size + Tamanho + + + Progress + Progresso + + + Priority + Prioridade + + + + TorrentImportDlg + + Torrent Import + Importar torrent + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Este assistente vai ajudá-lo a compartilhar um torrent que você baixou com o qBittorrent . + + + Torrent file to import: + Arquivo torrent para importar: + + + ... + ... + + + Content location: + Local do conteúdo: + + + Skip the data checking stage and start seeding immediately + Pular estágio de checagem de dados e começar a compartilhar imediatamente + + + Import + Importar + + + Torrent file to import + Arquivo torrent para importar + + + Torrent files (*.torrent) + Arquivos torrent (*.torrent) + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 arquivos + + + Please provide the location of %1 + %1 is a file name + Por favor forneça a localização de %1 + + + Please point to the location of the torrent: %1 + Por favor, aponte para a localização do torrent: %1 + + + Invalid torrent file + Arquivo torrent inválido + + + This is not a valid torrent file. + Este não é um arquivo torrent válido. + + + + TorrentModel + + Name + i.e: torrent name + Nome + + + Size + i.e: torrent size + Tamanho + + + Done + % Done + Feito + + + Status + Torrent status (e.g. downloading, seeding, paused) + Estado + + + Seeds + i.e. full sources (often untranslated) + Seeds + + + Peers + i.e. partial sources (often untranslated) + Peers + + + Down Speed + i.e: Download speed + Velocidade de download + + + Up Speed + i.e: Upload speed + Velocidade de upload + + + Ratio + Share ratio + Taxa + + + ETA + i.e: Estimated Time of Arrival / Time left + ETA + + + Label + Etiqueta + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Adicionado em + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Completado em + + + Tracker + Tracker + + + Down Limit + i.e: Download limit + Limite de download + + + Up Limit + i.e: Upload limit + Limite de upload + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Total baixado + + + Amount left + Amount of data left to download (e.g. in MB) + Total faltando + + + Time Active + Time (duration) the torrent is active (not paused) + Tempo Ativo + + + + TrackerList + + URL + URL + + + Status + Estado + + + Peers + Fontes + + + Message + Mensagem + + + [DHT] + [DHT] + + + Working + Trabalhando + + + Disabled + Desabilitado + + + This torrent is private + Este torrent é privado + + + Updating... + Atualizando... + + + Not working + Sem serviço + + + Not contacted yet + Não contactado ainda + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Add a new tracker... + Adicionar novo tracker... + + + Remove tracker + Remover tracker + + + Force reannounce + Força reanuncio + + + + TrackersAdditionDlg + + Trackers addition dialog + Diálogo de adição de Trackers + + + List of trackers to add (one per line): + Lista Trackers para adicionar (um por linha): + + + µTorrent compatible list URL: + URL da lista compatível com µTorrent: + + + I/O Error + Erro de entrada e saída + + + Error while trying to open the downloaded file. + Erro ao tentar abrir o arquivo baixado. + + + No change + Sem mudanças + + + No additional trackers were found. + Não foram encontrados Trackers adicionais. + + + Download error + Erro no download + + + The trackers list could not be downloaded, reason: %1 + A lista de trackers não pode ser baixada, razão: %1 + + + + TransferListDelegate + + Downloading + Baixando + + + Paused + Pausado + + + Queued + i.e. torrent is queued + Espera + + + Seeding + Torrent is complete and in upload-only mode + Enviando + + + Stalled + Torrent is waiting for download to begin + Estacionado + + + Checking + Torrent local data is being checked + Checando + + + /s + /second (.i.e per second) + /s + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seeded pelo %1 + + + + TransferListFiltersWidget + + All + Tudo + + + Downloading + Baixando + + + Completed + Completado + + + Active + Ativo + + + Inactive + Inativo + + + All labels + Todas etiquetas + + + Unlabeled + Sem etiqueta + + + Remove label + Remover etiqueta + + + New Label + Nova etiqueta + + + Label: + Etiqueta: + + + Invalid label name + Nome de etiqueta inválido + + + Please don't use any special characters in the label name. + Por favor não use caracteres especiais no nome da etiqueta. + + + Paused + Pausado + + + Add label... + Adicionar etiqueta... + + + Resume torrents + Resumir torrents + + + Pause torrents + Pausar torrents + + + Delete torrents + Remover torrents + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + ETA + + + Column visibility + Visibilidade da coluna + + + Open destination folder + Abrir pasta de destino + + + Force recheck + Forçar re-checagem + + + Copy magnet link + Copiar link magnético + + + Down Speed + i.e: Download speed + Velocidade de download + + + Up Speed + i.e: Upload speed + Velocidade de upload + + + Name + i.e: torrent name + Nome + + + Size + i.e: torrent size + Tamanho + + + Done + % Done + Feito + + + Status + Torrent status (e.g. downloading, seeding, paused) + Estado + + + Seeds + i.e. full sources (often untranslated) + Seeds + + + Peers + i.e. partial sources (often untranslated) + Peers + + + Ratio + Share ratio + Taxa + + + Torrent Download Speed Limiting + Limitando Velocidade de Download de Torrent + + + Torrent Upload Speed Limiting + Limitando Velocidade de Upload de Torrent + + + Super seeding mode + Modo super compartilhador + + + Download in sequential order + Download em ordem sequencial + + + Download first and last piece first + Baixar primeiro a primeira e a última parte + + + Label + Etiqueta + + + New Label + Nova etiqueta + + + Label: + Etiqueta: + + + New... + New label... + Nova... + + + Reset + Reset label + Resetar + + + Rename + Renomear + + + New name: + Novo nome: + + + Rename... + Renomear... + + + Invalid label name + Nome de etiqueta inválido + + + Please don't use any special characters in the label name. + Por favor não use caracteres especiais no nome da etiqueta. + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Adicionado em + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Completado em + + + Down Limit + i.e: Download limit + Limite de download + + + Up Limit + i.e: Upload limit + Limite de upload + + + Choose save path + Escolha caminho de salvamento + + + Save path creation error + Erro ao criar caminho de salvamento + + + Could not create the save path + Não foi possível criar caminho de salvamento + + + Set location... + Definir local... + + + Preview file... + Arquivo de pré-exibição... + + + Limit upload rate... + Limite de taxa de upload... + + + Limit download rate... + Limite de taxa de download... + + + Move up + i.e. move up in the queue + Mover para cima + + + Move down + i.e. Move down in the queue + Mover para baixo + + + Move to top + i.e. Move to top of the queue + Mover para o topo + + + Move to bottom + i.e. Move to bottom of the queue + Mover para último + + + Priority + Prioridade + + + Resume + Resume/start the torrent + Resumir + + + Pause + Pause the torrent + Pausar + + + Delete + Delete the torrent + Apagar + + + Limit share ratio... + Taxa de limite de compartilhamento... + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + Torrent Upload/Download limite + + + Use global ratio limit + Usar taxa de limite global + + + buttonGroup + botãoGrupo + + + Set no ratio limit + Não configurar taxa de limite + + + Set ratio limit to + Configurar limite para + + + + UsageDisplay + + Usage: + Uso: + + + displays program version + exibir versão do programa + + + disable splash screen + desabilitar tela de inicio + + + displays this help message + exibir este mensagem de ajuda + + + changes the webui port (current: %1) + mudar a porta do webui (atual: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [arquivos ou urls]: baixar os torrents passados pelo usuário (opcional) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + Gostaria de agradecer às seguintes pessoas por voluntariamente terem traduzido o qBittorrent: + + + Please contact me if you would like to translate qBittorrent into your own language. + Por favor contate-me se você deseja traduzir o qBittorrent no seu idioma. + + + + addPeerDialog + + Peer addition + Adição de fonte + + + IP + IP + + + Port + Porta + + + + addTorrentDialog + + Torrent addition dialog + Dialogo de adicionar torrent + + + Save path: + Caminho de salvamento: + + + ... + ... + + + Torrent content: + Conteúdo do torrent: + + + Add to download list in paused state + Adicionar a lista de download em pausa + + + Add + Adicionar + + + Cancel + Cancelar + + + Normal + Normal + + + High + Alto + + + Maximum + Máximo + + + Torrent size: + Tamanho do torrent: + + + Unknown + Desconhecido + + + Free disk space: + Espaço livre em disco: + + + Download in sequential order (slower but good for previewing) + Baixar em ordem de sequência (mais lento porém melhor para visualizar) + + + Skip file checking and start seeding immediately + Passar checagem de arquivo e começar a compartilhar imediatamente + + + Label: + Etiqueta: + + + Select All + Seleciona todos + + + Select None + Seleciona nenhum + + + Do not download + Não baixar + + + + authentication + + Tracker authentication + Autenticação de tracker + + + Tracker: + Tracker: + + + Login + Login + + + Username: + Usuário: + + + Password: + Senha: + + + Log in + Logar + + + Cancel + Cancelar + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + Confirmação de exclusão - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + Deseja realmente deletar os torrents selecionados da lista de transferência? + + + Remember choice + Lembrar escolha + + + Also delete the files on the hard disk + Deletar também arquivos do disco + + + + createTorrentDialog + + Cancel + Cancelar + + + Torrent Creation Tool + Ferramenta de Criação de Torrent + + + Torrent file creation + Criando arquivo Torrent + + + Announce urls (trackers): + Urls (trackers): + + + Comment (optional): + Comentário (opcional): + + + Web seeds urls (optional): + Urls de compartilhadores web (opcional): + + + File or folder to add to the torrent: + Arquivo ou pasta para adicionar ao torrent: + + + Piece size: + Tamanho: + + + 32 KiB + 32kb + + + 64 KiB + 64kb + + + 128 KiB + 128kb + + + 256 KiB + 256kb + + + 512 KiB + 512kb + + + 1 MiB + 1mb + + + 2 MiB + 2mb + + + 4 MiB + 4mb + + + Private (won't be distributed on DHT network if enabled) + Privado (não distribuir em DHT se habilitado) + + + Start seeding after creation + Iniciar compartilhamento depois de criar + + + Create and save... + Criar e salvar... + + + Progress: + Progresso: + + + Add file + Adicionar arquivo + + + Add folder + Adicionar pasta + + + Tracker URLs: + Tracker URLs: + + + Web seeds urls: + Web seeds urls: + + + Comment: + Comentário: + + + Auto + + + + + createtorrent + + Select destination torrent file + Selecione o arquivo torrent de destino + + + Torrent Files + Arquivos Torrent + + + No input path set + Nenhum caminho de entrada selecionado + + + Please type an input path first + Digite primeiro um caminho de entrada + + + Torrent creation + Criação de torrent + + + Torrent was created successfully: + Torrent foi criado com sucesso: + + + Select a folder to add to the torrent + Selecione uma pasta para adicionar ao torrent + + + Please type an announce URL + Digite uma url anunciada + + + Torrent creation was unsuccessful, reason: %1 + A criação do torrent não foi possível, motivo: %1 + + + Announce URL: + Tracker URL + Url anunciada: + + + Please type a web seed url + Digite uma url de compartilhador web + + + Web seed URL: + Url de compartilhador web: + + + Select a file to add to the torrent + Selecione um arquivo para adicionar ao torrent + + + Created torrent file is invalid. It won't be added to download list. + Torrent criado é inválido. Não será adicionado a lista de download. + + + + downloadFromURL + + Download Torrents from URLs + Baixar torrents de URLs + + + Only one URL per line + Somente uma URL por linha + + + Download + Baixar + + + Cancel + Cancelar + + + Download from urls + Baixar de URLs + + + No URL entered + Nenhuma URL inserida + + + Please type at least one URL. + Por favor digite uma URL. + + + Add torrent links + Adicionar links torrent + + + Both HTTP and Magnet links are supported + Ambos HTTP e links magnéticos são suportados + + + + downloadThread + + I/O Error + Erro de entrada e saída + + + The remote host name was not found (invalid hostname) + O host remoto não foi encontrado (host inválido) + + + The operation was canceled + A operação foi cancelada + + + The remote server closed the connection prematurely, before the entire reply was received and processed + O servidor remoto fechou a conexão, antes de responder, receber e processar + + + The connection to the remote server timed out + Atingiu o fim do tempo da conexão com o servidor remoto + + + SSL/TLS handshake failed + SSL/TLS falhou + + + The remote server refused the connection + O servidor remoto recusou a conexão + + + The connection to the proxy server was refused + Conexão com proxy foi recusada + + + The proxy server closed the connection prematurely + Servidor proxy fechou a conexão + + + The proxy host name was not found + O host name do proxy não foi encontrado + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Fim do tempo de conexão com o proxy ou o proxy não respondeu no tempo + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + O proxy requer autenticação mas não aceitou as credenciais oferecidas + + + The access to the remote content was denied (401) + O conteúdo do acesso remoto foi negado (401) + + + The operation requested on the remote content is not permitted + A operação requerida no servidor não foi permitida + + + The remote content was not found at the server (404) + O conteúdo não foi encontrado no servidor (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + O servidor remoto requer autenticação para servir os dados mas as credenciais oferecidas não foram aceitas + + + The Network Access API cannot honor the request because the protocol is not known + O acesso a internet não honrou o pedido pois o protocolo é desconhecido + + + The requested operation is invalid for this protocol + Operação inválida para este protocolo + + + An unknown network-related error was detected + Um desconhecido erro relatado de internet foi detectado + + + An unknown proxy-related error was detected + Um desconhecido erro de proxy relatado foi detectado + + + An unknown error related to the remote content was detected + Um desconhecido erro relacionado ao conteúdo do servidor foi detectado + + + A breakdown in protocol was detected + Um erro no protocolo foi detectado + + + Unknown error + Erro desconhecido + + + + engineSelect + + Search plugins + Plugins de busca + + + Installed search engines: + Plugins de busca instalados: + + + Name + Nome + + + Url + Url + + + Enabled + Habilitado + + + Install a new one + Instalar um novo + + + Check for updates + Verificar atualizações + + + Close + Fechar + + + Enable + Habilitar + + + Disable + Desabilitar + + + Uninstall + Desinstalar + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Você pode pegar novos mecanismos de busca aqui: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + engineSelectDlg + + Uninstall warning + Aviso de desinstalação + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Muitos plugins não podem ser desinstalados por serem padrão do qBittorrent. + Apenas aqueles que você instalou podem ser desinstalados. +Portanto os plugins foram desabilitados. + + + Uninstall success + Desinstalado com sucesso + + + Select search plugins + Selecionar plugins de busca + + + qBittorrent search plugins + Plugins de busca qBittorrent + + + Search plugin install + Instalação de plugin de busca + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Uma versão mais recente de plugin de busca %1 já está instalado. + + + Search plugin update + Atualização de plugin de busca + + + Sorry, update server is temporarily unavailable. + Desculpe, servidor de atualizações está temporariamente indisponível. + + + All your plugins are already up to date. + Todos os plugins já estão atuais. + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 esse aí não pôde ser atualizado, vai ficar o véio. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Plugin de busca %1 não pode ser instalado. + + + All selected plugins were uninstalled successfully + Plugins selecionados desinstalados com sucesso + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + Plugin de busca %1 atualizado com sucesso. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Plugin de busca %1 instalado com sucesso. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Sinto muito mas a instalação do plugin de busca %1 falhou. + + + New search engine plugin URL + Url de novo plugin de busca + + + URL: + Url: + + + Yes + Sim + + + No + Não + + + + misc + + B + bytes + B + + + KiB + kibibytes (1024 bytes) + Kib + + + MiB + mebibytes (1024 kibibytes) + MiB + + + GiB + gibibytes (1024 mibibytes) + GiB + + + TiB + tebibytes (1024 gibibytes) + TiB + + + Unknown + Desconhecido + + + Unknown + Unknown (size) + Desconhecido + + + < 1m + < 1 minute + < 1 minuto + + + %1m + e.g: 10minutes + %1m + + + %1h %2m + e.g: 3hours 5minutes + %1h %2m + + + %1d %2h + e.g: 2days 10hours + %1d %2h + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBIttorrent irá desligar seu computador agora porque os downloads terminaram. + + + + options_imp + + Choose a save directory + Selecione um diretório de salvamento + + + Choose an ip filter file + Escolha um arquivo de filtro de ip + + + Filters + Filtros + + + Choose export directory + Escolha diretório de exportação + + + Add directory to scan + Adicione diretório para escanear + + + Folder is already being watched. + Pasta já está sendo monitorada. + + + Folder does not exist. + Essa pasta não existe. + + + Folder is not readable. + A pasta não tem suporte a leitura. + + + Failure + Falhou + + + Failed to add Scan Folder '%1': %2 + Falhou para adicionar pasta a ser escaneada '%1': %2 + + + Parsing error + Análise de Erro + + + Failed to parse the provided IP filter + Falha ao analisar o filtro de IP enviado + + + Succesfully refreshed + Atualizado com sucesso + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Analisado com sucesso o filtro de IP : %1 regras foram aplicadas. + + + Successfully refreshed + Atualizado com sucesso + + + Invalid key + + + + This is not a valid SSL key. + + + + Invalid certificate + + + + This is not a valid SSL certificate. + + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + + pluginSourceDlg + + Plugin source + Fonte do plugin + + + Search plugin source: + Busca de plugin de busca: + + + Local file + Arquivo local + + + Web link + Link da net + + + + preview + + Preview selection + Seleção de pré-visualização + + + File preview + Pré-visualização de arquivo + + + The following files support previewing, <br>please select one of them: + Os seguintes arquivos suportam pré-visualização, <br>por favor selecione um deles: + + + Preview + Pré-visualização + + + Cancel + Cancelar + + + + previewSelect + + Preview impossible + Pré-visualização impossível + + + Sorry, we can't preview this file + Arquivo sem possível pré-visualização + + + Name + Nome + + + Size + Tamanho + + + Progress + Progresso + + + + search_engine + + Search + Busca + + + Status: + Estado: + + + Stopped + Parado + + + Download + Download + + + Search engines... + Máquinas de busca... + + + Go to description page + Ir para a página de descrição + + + + torrentAdditionDialog + + Unable to decode torrent file: + Incapaz de decodificar o arquivo torrent: + + + Choose save path + Escolha um caminho de salvamento + + + Empty save path + Caminho de salvamento vazio + + + Please enter a save path + Por favor digite um caminho de salvamento + + + Save path creation error + Erro ao criar caminho de salvamento + + + Could not create the save path + Não foi possível criar caminho de salvamento + + + Invalid file selection + Seleção de arquivo inválida + + + You must select at least one file in the torrent + Você deve selecionar um arquivo no torrent + + + Priority + Prioridade + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 depois de baixar o torrent) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 mais é requerido para baixar) + + + Seeding mode error + Modo de compartilhamento errado + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Você escolheu não checar. Entretanto, arquivos locais não parecem existir na pasta atual de destino. +Por favor desabilite este recurso ou atualize o caminho de salvamento. + + + Rename... + Renomear... + + + New name: + Novo nome: + + + The file could not be renamed + O arquivo não pode ser renomeado + + + This name is already in use in this folder. Please use a different name. + Este nome já está em uso. Por favor use um nome diferente. + + + The folder could not be renamed + Esta pasta não pode ser renomeada + + + Rename the file + Renomeie o arquivo + + + Unable to decode magnet link: + Impossível decodificar o link magnético: + + + Magnet Link + Link Magnético + + + Invalid label name + Nome de etiqueta inválido + + + Please don't use any special characters in the label name. + Por favor não use caracteres especiais no nome da etiqueta. + + + This file name contains forbidden characters, please choose a different one. + Este nome de arquivo contém caracteres proibidos, por favor escolha um diferente. + + + diff --git a/src/lang/qbittorrent_ro.qm b/src/lang/qbittorrent_ro.qm new file mode 100644 index 0000000000000000000000000000000000000000..ba020e157bcc53f7de58aa04dfc26dd9ccab68a7 GIT binary patch literal 63830 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 literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_ro.ts b/src/lang/qbittorrent_ro.ts new file mode 100644 index 000000000..44c7f678d --- /dev/null +++ b/src/lang/qbittorrent_ro.ts @@ -0,0 +1,5098 @@ + + + + + AboutDlg + + About qBittorrent + Despre qBittorrent + + + About + Despre + + + Author + Autor + + + Name: + Nume: + + + Country: + Ţara: + + + E-mail: + E-Mail: + + + Christophe Dumez + Christophe Dumez + + + France + Franţa + + + Translation + Translare + + + License + Licensă + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + chris@qbittorrent.org + chris@qbittorrent.org + + + Thanks to + Mulţumesc lui + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + + AdvancedSettings + + Ignore transfer limits on local network + + + + Disk write cache size + + + + MiB + + + + Outgoing ports (Min) [0: Disabled] + + + + Outgoing ports (Max) [0: Disabled] + + + + Recheck torrents on completion + + + + Transfer list refresh interval + + + + ms + milliseconds + + + + Resolve peer countries (GeoIP) + + + + Resolve peer host names + + + + Maximum number of half-open connections [0: Disabled] + + + + Strict super seeding + + + + Network Interface (requires restart) + + + + Any interface + i.e. Any network interface + + + + Enable embedded tracker + + + + Embedded tracker port + + + + Check for software updates + + + + Use system icon theme + + + + Confirm torrent deletion + + + + IP Address to report to trackers (requires restart) + + + + Setting + + + + Value + Value set for this setting + + + + Display program on-screen notifications + + + + Exchange trackers with other peers + + + + + AutomatedRssDownloader + + Automated RSS Downloader + + + + Enable the automated RSS downloader + + + + Download rules + + + + Rule definition + + + + Must contain: + + + + Must not contain: + + + + ... + ... + + + Assign label: + + + + Apply rule to feeds: + + + + Matching RSS articles + + + + Save to a different directory + + + + Save to: + + + + Import... + Import... + + + Export... + Export... + + + New rule name + + + + Please type the name of the new download rule. + + + + Rule name conflict + + + + A rule with this name already exists, please choose another name. + + + + Are you sure you want to remove the download rule named %1? + + + + Are you sure you want to remove the selected download rules? + + + + Rule deletion confirmation + + + + Destination directory + + + + Invalid action + + + + The list is empty, there is nothing to export. + + + + Where would you like to save the list? + + + + Rules list (*.rssrules) + + + + I/O Error + + + + Failed to create the destination file + + + + Please point to the RSS download rules file + + + + Rules list (*.rssrules *.filters) + + + + Import Error + + + + Failed to import the selected rules file + + + + Add new rule... + + + + Delete rule + + + + Rename rule... + + + + Delete selected rules + + + + Rule renaming + + + + Please type the new rule name + + + + Use regular expressions + + + + Regex mode: use Perl-like regular expressions + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 a ajuns la rata maximă setată. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent utilizează portul : TCP/%1 + + + UPnP support [ON] + Suport UPnP[Activat] + + + UPnP support [OFF] + suport de UPnP[Dezactivat] + + + NAT-PMP support [ON] + suport NAT-PMP[Activat] + + + NAT-PMP support [OFF] + suport NAT-PMP[Dezactivat] + + + DHT support [ON], port: UDP/%1 + DHT activat, portul : UDP/%1 + + + DHT support [OFF] + Suport DHT[Dezactivat] + + + PeX support [ON] + Suport PeX[Activat] + + + Local Peer Discovery [ON] + Căutare peer locali[Activat] + + + Local Peer Discovery support [OFF] + Căutarea peer locali[Dezactivat] + + + Encryption support [ON] + Suport de codificate[Activat] + + + Encryption support [FORCED] + Suport de codificare[Forţat] + + + Encryption support [OFF] + Suport de codificare [Dezactivat] + + + Web User Interface Error - Unable to bind Web UI to port %1 + Eroare în interfața Web - Nu pot conecta interfața Web cu portul %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' a fost șters din lista de transferuri și de pe hard disk. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' a fost șters din lista de transferuri. + + + '%1' is not a valid magnet URI. + '%1' nu este valid URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' este de acum in lista de descărcare. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' resumat. (resumare rapidă) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' adăugat la lista de descărcare. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Nu pot decodifica torrent-ul : '%1' + + + This file is either corrupted or this isn't a torrent. + Acest fişier este deteriorat sau nu este torrent. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>a fost blocat conform IP filtrului</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>a fost banat din cauza fragmentelor eronate</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Descarcă recursiv fișierul %1 din torrentul %2 + + + Unable to decode %1 torrent file. + Nu pot citi torrentul %1. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port mapping failure, message: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port mapping successful, message: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Resumarea rapidă a fost respinsă pentru torrent-ul %1, verific încă o dată... + + + Url seed lookup failed for url: %1, message: %2 + Conectarea la seed a eşuat pentru : %1, mesajul : %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Descarc '%1', vă rugăm să aşteptaţi... + + + Using a disk cache size of %1 MiB + Utilizez cache de pe disk la %1 MiB + + + PeX support [OFF] + Suport PeX [Oprit] + + + Restart is required to toggle PeX support + Restartarea este necesară pentru a activa suport PeX + + + The Web UI is listening on port %1 + Interfața Web este activă pe portul %1 + + + HTTP user agent is %1 + HTTP agentul este %1 + + + + ConsoleDlg + + General + General + + + Blocked IPs + IP-uri blocate + + + + CookiesDlg + + Cookies management + + + + Key + As in Key/Value pair + + + + Value + As in Key/Value pair + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + + + + Dynamic DNS error: Invalid username/password. + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + + + + Dynamic DNS error: Your username was blocked due to abuse. + + + + Dynamic DNS error: supplied domain name is invalid. + + + + Dynamic DNS error: supplied username is too short. + + + + Dynamic DNS error: supplied password is too short. + + + + + DownloadThread + + I/O Error + + + + The remote host name was not found (invalid hostname) + Numele host-ului nu a fost găsit(nume invalid) + + + The operation was canceled + Operțiunea a fost anulată + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Serverul a închis conectarea înainte ca să recepționez și proceses răspunsul + + + The connection to the remote server timed out + Timpul de conectare la server a expirat + + + SSL/TLS handshake failed + Conectarea SSL/TLS eșuată + + + The remote server refused the connection + Serverul refuză conectarea + + + The connection to the proxy server was refused + Conectarea prin proxy server refuzată + + + The proxy server closed the connection prematurely + Serverul proxy a închis conectarea pre deverme + + + The proxy host name was not found + Numele serverului proxy nu este găsit + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Timpul de conectare la proxy a expirat + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + The proxy requires authentication in order to honour the request but did not accept any credentials offered + + + The access to the remote content was denied (401) + The access to the remote content was denied (401) + + + The operation requested on the remote content is not permitted + The operation requested on the remote content is not permitted + + + The remote content was not found at the server (404) + The remote content was not found at the server (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + The remote server requires authentication to serve the content but the credentials provided were not accepted + + + The Network Access API cannot honor the request because the protocol is not known + The Network Access API cannot honor the request because the protocol is not known + + + The requested operation is invalid for this protocol + The requested operation is invalid for this protocol + + + An unknown network-related error was detected + An unknown network-related error was detected + + + An unknown proxy-related error was detected + An unknown proxy-related error was detected + + + An unknown error related to the remote content was detected + An unknown error related to the remote content was detected + + + A breakdown in protocol was detected + A breakdown in protocol was detected + + + Unknown error + Eroare necunoscută + + + + EventManager + + %1/s + e.g. 120 KiB/s + %1/s + + + Working + Lucrează + + + Updating... + Reînnoire... + + + Not working + Nu lucrează + + + Not contacted yet + Nu a fost contactat + + + this session + sesiunea aceasta + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Sedat pentru %1 + + + %1 max + e.g. 10 max + %1 max + + + + ExecutionLog + + General + General + + + Blocked IPs + IP-uri blocate + + + + FeedDownloader + + RSS Feed downloader + RSS Feed download-er + + + RSS feed: + Feed RSS: + + + Feed name + Numele la Feed + + + Automatically download torrents from this feed + Automat descarcă torrente din acest feed + + + Download filters + Filtre de descărcare + + + Filters: + Filtre: + + + Filter settings + Stările filtrului + + + Matches: + Coincidențe: + + + Does not match: + Nu coincide: + + + Destination folder: + Directoriul destinație: + + + ... + ... + + + Filter testing + Setările filtrului + + + Torrent title: + Titlul torrent-ului: + + + Result: + Rezultat: + + + Test + Test + + + Import... + Import... + + + Export... + Export... + + + Rename filter + Redenumirea filtrului + + + Remove filter + Șterge filtrul + + + Add filter + Adaugă filtrul + + + + FeedDownloaderDlg + + New filter + Nou filtru + + + Please choose a name for this filter + Alegeți un nume pentru acest filtru + + + Filter name: + Numele filtrului: + + + Invalid filter name + Numele filtrului invalid + + + The filter name cannot be left empty. + Numele filtrului nu poate fi vid. + + + This filter name is already in use. + Nume de filtru existent. + + + Filter testing error + Filtrul testare eroare + + + Please specify a test torrent name. + Specificați un nume de test a torrent-ului. + + + matches + coincidenț + + + does not match + nu coincide + + + Select file to import + Alegeți fișier pentru import + + + Filters Files + Filtrează Fișiere + + + Import successful + Import cu success + + + Filters import was successful. + Importul filtrelor a fost cu success. + + + Import failure + Importează failure + + + Filters could not be imported due to an I/O error. + Filtrele nu pot fi importate din cauza erorilor I/O. + + + Select destination file + Selectează fișierul de destinație + + + Export successful + Export cu success + + + Filters export was successful. + Exportul filtrelor a fost cu success. + + + Export failure + Export eșuat + + + Filters could not be exported due to an I/O error. + Filtrele nu pot fi exportate din cauza erorilor I/O. + + + Choose save path + Alegeţi calea de salvare + + + + FeedList + + Unread + Necitit + + + + FeedListWidget + + RSS feeds + RSS feed-uri + + + Unread + + + + + GUI + + Open Torrent Files + Deschide Fişiere Torrent + + + Torrent Files + Fişiere Torrent + + + qBittorrent + qBittorrent + + + Transfers + Transferuri + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Viteza DL: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Viteza IP: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 a fost terminat de descărcat. + + + I/O Error + i.e: Input/Output Error + Eroare de intrare/eşire + + + Search + Caută + + + RSS + RSS + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Eroare de intrare/ieșire pentru torrent-ul %1. +Motivul : %2 + + + Url download error + Eroare la descărcare URL + + + Couldn't download file at url: %1, reason: %2. + Nu pot descărca fisierul de pe url: %1, motivul: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Options were saved successfully. + Opţiunile salvate cu success. + + + Download completion + Descărcarea completată + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Unele fișiere sunt transferate acum. +Sunteți siguri că doriți să închideți qBittorrent? + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Limita de upload globală + + + Global Download Speed Limit + Limita de download globală + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Down: %2/s, Up: %3/s) + + + Yes + Da + + + No + Ny + + + Never + Niciodată + + + + GeoIP + + France + Franţa + + + + HeadlessLoader + + Information + Informație + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Pentru a controla qBittorrent, acesați interfața Web prin http://localhost:%1 + + + The Web UI administrator user name is: %1 + Numele administratorului interfeței web este: %1 + + + The Web UI administrator password is still the default one: %1 + Parola de acces a administratorului prin interfața Web este implicită : %1 + + + This is a security risk, please consider changing your password from program preferences. + Aceasta este un risc de securitate, schimbati parola de acces din preferințe. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - T: %2 + + + + HttpServer + + File + Fișier + + + Edit + Editare + + + Help + Ajutor + + + Delete from HD + Șterge de pe Hard Disc + + + Download Torrents from their URL or Magnet link + Descarcă fișierele torrent din URL sau link Magnet + + + Only one link per line + Numai un link pe linie + + + Download + Descarcă + + + Download local torrent + Descarcă torrent-ul local + + + Torrent files were correctly added to download list. + Fișierele torrent care sunt correct adăugate la lista de descărcare. + + + Point to torrent file + Arată fișierul torrent + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Doriți să ștergeți torrent-urile selectate de pe hard disk ? + + + Download rate limit must be greater than 0 or disabled. + Limita de descărcare trebuie să fie mai mare ca 0 sau deactivată. + + + Upload rate limit must be greater than 0 or disabled. + Upload rate limit must be greater than 0 or disabled. + + + Maximum number of connections limit must be greater than 0 or disabled. + Maximum number of connections limit must be greater than 0 or disabled. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Maximum number of connections per torrent limit must be greater than 0 or disabled. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + + + Unable to save program preferences, qBittorrent is probably unreachable. + Unable to save program preferences, qBittorrent is probably unreachable. + + + Language + Limba + + + The port used for incoming connections must be greater than 1024 and less than 65535. + The port used for incoming connections must be greater than 1024 and less than 65535. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + The port used for the Web UI must be greater than 1024 and less than 65535. + + + The Web UI username must be at least 3 characters long. + The Web UI username must be at least 3 characters long. + + + The Web UI password must be at least 3 characters long. + The Web UI password must be at least 3 characters long. + + + Downloaded + Is the file downloaded or not? + Descărcat + + + Save + + + + qBittorrent client is not reachable + + + + HTTP Server + HTTP Server + + + Torrent path + + + + Torrent name + + + + The following parameters are supported: + + + + + LegalNotice + + Legal Notice + Notă legală + + + Legal notice + Notă legală + + + Cancel + Anulare + + + I Agree + Acceptare + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + + + + Press %1 key to accept and continue... + + + + + LineEdit + + Clear the text + + + + + MainWindow + + &Edit + &Editare + + + &File + &Fişier + + + &Help + &Ajutor + + + Preview file + Preview fişier + + + Clear log + Curăţă log-ul + + + Decrease priority + Decrementează prioritatea + + + Increase priority + Incrementează prioritatea + + + &Tools + + + + &View + + + + &Options... + + + + Torrent &creator + + + + Set upload limit... + + + + Set download limit... + + + + Set global download limit... + + + + Set global upload limit... + + + + Top &tool bar + + + + Display top tool bar + + + + &Speed in title bar + + + + Show transfer speed in title bar + + + + Alternative speed limits + + + + &About + + + + &Pause + + + + &Delete + + + + P&ause All + + + + Visit &Website + + + + Report a &bug + + + + &Documentation + + + + &RSS reader + + + + Search &engine + + + + Lock qBittorrent + + + + Ctrl+L + + + + &Resume + + + + R&esume All + + + + Exit + + + + Import torrent... + + + + Donate money + + + + If you like qBittorrent, please donate! + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + + + + Transfers + Transferuri + + + Torrent file association + + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + + + + UI lock password + + + + Please type the UI lock password: + + + + Password update + + + + The UI lock password has been successfully updated + + + + RSS + RSS + + + Search + Caută + + + Transfers (%1) + + + + Download completion + Descărcarea completată + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 a fost terminat de descărcat. + + + I/O Error + i.e: Input/Output Error + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Eroare de intrare/ieșire pentru torrent-ul %1. +Motivul : %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + + + + The torrent %1 contains torrent files, do you want to proceed with their download? + + + + Yes + Da + + + No + Ny + + + Never + Niciodată + + + Url download error + Eroare la descărcare URL + + + Couldn't download file at url: %1, reason: %2. + Nu pot descărca fisierul de pe url: %1, motivul: %2. + + + Global Upload Speed Limit + + + + Global Download Speed Limit + + + + Invalid password + + + + The password is invalid + + + + Exiting qBittorrent + + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Unele fișiere sunt transferate acum. +Sunteți siguri că doriți să închideți qBittorrent? + + + Always + + + + Open Torrent Files + Deschide Fişiere Torrent + + + Torrent Files + Fişiere Torrent + + + Options were saved successfully. + Opţiunile salvate cu success. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Viteza DL: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Viteza IP: %1 KiB/s + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Down: %2/s, Up: %3/s) + + + A newer version is available + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + + + + Impossible to update qBittorrent + + + + qBittorrent failed to update, reason: %1 + + + + &Add torrent file... + + + + Add &link to torrent... + + + + Import existing torrent... + + + + Execution &Log + + + + Execution Log + + + + Auto-Shutdown on downloads completion + + + + Exit qBittorrent + + + + Suspend system + + + + Shutdown system + + + + Disabled + + + + The password should contain at least 3 characters + + + + + PeerAdditionDlg + + Invalid IP + IP greşit + + + The IP you provided is invalid. + IP-ul introdus este greșit. + + + + PeerListDelegate + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + Client + + + Progress + i.e: % downloaded + Progress + + + Down Speed + i.e: Download speed + Viteza de descărcare + + + Up Speed + i.e: Upload speed + VIteza de încărcare + + + Downloaded + i.e: total data downloaded + Descărcat + + + Uploaded + i.e: total data uploaded + Încărcat + + + Ban peer permanently + Banează peer-ul permanent + + + Peer addition + Adăugă peer + + + The peer was added to this torrent. + Peer a fost adăugat la torrent. + + + The peer could not be added to this torrent. + Peer-ul nu poate fi adăugat la acest torrent. + + + Are you sure? -- qBittorrent + Sunteţi siguri? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + Sunteți siguri că doriți să banați peer-ii selectați ? + + + &Yes + &Yes + + + &No + &No + + + Manually banning peer %1... + Manual banez peer-ul %1... + + + Upload rate limiting + Reînnoiește rata de încărcare + + + Download rate limiting + Reînnoiește rata de descărcare + + + Add a new peer... + + + + Limit download rate... + + + + Limit upload rate... + + + + Copy IP + + + + Connection + Conectare + + + + Preferences + + UI + User Interface + UI + + + Downloads + Descărcări + + + Connection + Conectare + + + Bittorrent + Bittorrent + + + Proxy + Proxy + + + Web UI + Interfață Web + + + Language: + Limbă: + + + (Requires restart) + (Necesită restartare) + + + Visual style: + Stilul vizual: + + + Transfer list + Transfer list + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Use alternating row colors + + + File system + Sistem de fișiere + + + Torrent queueing + Torrent queueing + + + Maximum active downloads: + Numărul maxim de download-uri active: + + + Maximum active uploads: + Numărul maxim de încărcări active: + + + Maximum active torrents: + Numărul maxim de torrente active: + + + When adding a torrent + When adding a torrent + + + Display torrent content and some options + Afișează conținutul torrent-ului și unele opțiuni + + + Listening port + Portul ascultat + + + Port used for incoming connections: + Port used for incoming connections: + + + Random + Aleator + + + Enable UPnP port mapping + Activează maparea UPnP a porturilor + + + Enable NAT-PMP port mapping + Enable NAT-PMP port mapping + + + Connections limit + Limită de conectări + + + Global maximum number of connections: + Global maximum number of connections: + + + Maximum number of connections per torrent: + Maximum number of connections per torrent: + + + Maximum number of upload slots per torrent: + Maximum number of upload slots per torrent: + + + Upload: + Upload: + + + Download: + Download: + + + KiB/s + KiB/s + + + Bittorrent features + Bittorrent features + + + Enable DHT network (decentralized) + Enable DHT network (decentralized) + + + Use a different port for DHT and Bittorrent + Use a different port for DHT and Bittorrent + + + DHT port: + Portul DHT: + + + Enable Peer Exchange / PeX (requires restart) + Enable Peer Exchange / PeX (requires restart) + + + Enable Local Peer Discovery + Enable Local Peer Discovery + + + Enabled + Enabled + + + Forced + Forced + + + Disabled + Disabled + + + Type: + Type: + + + (None) + (None) + + + HTTP + HTTP + + + Port: + Port: + + + Authentication + Authentication + + + Username: + Username: + + + Password: + Password: + + + SOCKS5 + SOCKS5 + + + HTTP Server + HTTP Server + + + Filter path (.dat, .p2p, .p2b): + Filter path (.dat, .p2p, .p2b): + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP Communications (trackers, Web seeds, search engine) + + + Host: + Host: + + + Peer Communications + Peer Communications + + + SOCKS4 + SOCKS4 + + + Speed + + + + to + time1 to time2 + la + + + Every day + + + + Week days + + + + Week ends + + + + Advanced + + + + Copy .torrent files to: + + + + Remove folder + + + + No action + + + + Options + Opţiuni + + + Action on double-click + + + + Downloading torrents: + + + + Open destination folder + Deschide directoriul destinaţie + + + Completed torrents: + + + + Desktop + + + + Show splash screen on start up + + + + Start qBittorrent minimized + + + + Minimize qBittorrent to notification area + + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + + + + Do not start the download automatically + The torrent will be added to download list in pause state + + + + Save files to location: + + + + Append the label of the torrent to the save path + + + + Pre-allocate disk space for all files + + + + Keep incomplete torrents in: + + + + Automatically add torrents from: + + + + Add folder... + + + + IP Filtering + + + + from + from (time1 to time2) + + + + When: + + + + Look for peers on your local network + + + + Enable Web User Interface (Remote control) + + + + Seed torrents until their ratio reaches + + + + then + + + + Pause them + + + + Remove them + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + + + + Email notification upon download completion + + + + Destination email: + + + + SMTP server: + + + + Run an external program on torrent completion + + + + BitTorrent + + + + Start / Stop Torrent + + + + Use UPnP / NAT-PMP port forwarding from my router + + + + Privacy + + + + Enable DHT (decentralized network) to find more peers + + + + Use a different port for DHT and BitTorrent + + + + Enable Peer Exchange (PeX) to find more peers + + + + Enable Local Peer Discovery to find more peers + + + + Encryption mode: + + + + Prefer encryption + + + + Require encryption + + + + Disable encryption + + + + Reload the filter + + + + Behavior + + + + Language + Limba + + + Power Management + + + + Inhibit system sleep when torrents are active + + + + Bypass authentication for localhost + + + + Ask for program exit confirmation + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + + + + Tray icon style: + + + + Normal + Normal + + + Monochrome (Dark theme) + + + + Monochrome (Light theme) + + + + This server requires a secure connection (SSL) + + + + User Interface Language: + + + + Transfer List + + + + Show qBittorrent in notification area + + + + Hard Disk + + + + Listening Port + + + + Connections Limits + + + + Proxy Server + + + + Torrent Queueing + + + + Share Ratio Limiting + + + + Use UPnP / NAT-PMP to forward the port from my router + + + + Update my dynamic domain name + + + + Service: + + + + Register + + + + Domain name: + + + + Global Rate Limits + + + + Apply rate limit to uTP connections + + + + Apply rate limit to transport overhead + + + + Alternative Global Rate Limits + + + + Schedule the use of alternative rate limits + + + + Enable bandwidth management (uTP) + + + + Otherwise, the proxy server is only used for tracker connections + + + + Use proxy for peer connections + + + + Append .!qB extension to incomplete files + + + + Use HTTPS instead of HTTP + + + + Import SSL Certificate + + + + Import SSL Key + + + + Certificate: + + + + Key: + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + PreviewSelect + + Name + Nume + + + Size + Capacitate + + + Progress + Progress + + + Preview impossible + Preview imposibil + + + Sorry, we can't preview this file + Nu putem face preview pentru acest fişier + + + + PropListDelegate + + Normal + Normal (priority) + Normal + + + High + High (priority) + Înaltă + + + Maximum + Maximum (priority) + Maximală + + + Not downloaded + + + + Mixed + Mixed (priorities + + + + + PropTabBar + + General + General + + + Trackers + Trackeri + + + Peers + Peer-i + + + Files + Fișiere + + + HTTP Sources + + + + Content + + + + + PropertiesWidget + + Save path: + Calea de salvare: + + + Torrent hash: + Hash-ul torrentului: + + + Comment: + Comentarii: + + + Share ratio: + Raţia de Share: + + + General + General + + + Trackers + Trackeri + + + URL seeds + URL-uri de sedare + + + Files + Fișiere + + + Priority + Prioritate + + + New url seed + New HTTP source + Nou URL de sedări + + + New url seed: + Nou URL de sedări: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + Acest URL este deacum în listă. + + + Choose save path + Alegeţi calea de salvare + + + Save path creation error + Salvează calea care crează erori + + + Could not create the save path + Nu pot crea calea de salvare + + + Downloaded: + Descărcat: + + + Transfer + Transferat + + + Uploaded: + Încăcrat: + + + Wasted: + Pierdut: + + + UP limit: + UP limită: + + + DL limit: + DW limită: + + + Time elapsed: + Timpul estimat: + + + Connections: + Conectări: + + + Information + Informație + + + Created on: + Creat pe: + + + Peers + Peer-i + + + Normal + Normal + + + Maximum + Maximum + + + High + Mare + + + this session + sesiunea această + + + %1 max + e.g. 10 max + %1 max + + + Availability: + Disponibilitatea: + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seed-eri pentru %1 + + + Rename... + Redenumește... + + + New name: + Nume nou: + + + The file could not be renamed + Fișierul nu poate fi redenumit + + + This name is already in use in this folder. Please use a different name. + This name is already in use in this folder. Please use a different name. + + + The folder could not be renamed + The folder could not be renamed + + + Rename the file + Redenumește fișierul + + + This file name contains forbidden characters, please choose a different one. + This file name contains forbidden characters, please choose a different one. + + + I/O Error + I/O Error + + + This file does not exist yet. + This file does not exist yet. + + + This folder does not exist yet. + This folder does not exist yet. + + + Reannounce in: + + + + Select All + + + + Select None + + + + Do not download + + + + Pieces size: + + + + Time active: + Time (duration) the torrent is active (not paused) + + + + Torrent content: + Conţinutul torrent-ului: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1 a ajuns la rata maximă setată. + + + Removing torrent %1... + + + + Pausing torrent %1... + + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent utilizează portul : TCP/%1 + + + UPnP support [ON] + Suport UPnP[Activat] + + + UPnP support [OFF] + suport de UPnP[Dezactivat] + + + NAT-PMP support [ON] + suport NAT-PMP[Activat] + + + NAT-PMP support [OFF] + suport NAT-PMP[Dezactivat] + + + HTTP user agent is %1 + HTTP agentul este %1 + + + Using a disk cache size of %1 MiB + Utilizez cache de pe disk la %1 MiB + + + DHT support [ON], port: UDP/%1 + DHT activat, portul : UDP/%1 + + + DHT support [OFF] + Suport DHT[Dezactivat] + + + PeX support [ON] + Suport PeX[Activat] + + + PeX support [OFF] + Suport PeX [Oprit] + + + Restart is required to toggle PeX support + Restartarea este necesară pentru a activa suport PeX + + + Local Peer Discovery [ON] + Căutare peer locali[Activat] + + + Local Peer Discovery support [OFF] + Căutarea peer locali[Dezactivat] + + + Encryption support [ON] + Suport de codificate[Activat] + + + Encryption support [FORCED] + Suport de codificare[Forţat] + + + Encryption support [OFF] + Suport de codificare [Dezactivat] + + + Embedded Tracker [ON] + + + + Failed to start the embedded tracker! + + + + Embedded Tracker [OFF] + + + + The Web UI is listening on port %1 + Interfața Web este activă pe portul %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Eroare în interfața Web - Nu pot conecta interfața Web cu portul %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' a fost șters din lista de transferuri și de pe hard disk. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' a fost șters din lista de transferuri. + + + '%1' is not a valid magnet URI. + '%1' nu este valid URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' este de acum in lista de descărcare. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' resumat. (resumare rapidă) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' adăugat la lista de descărcare. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Nu pot decodifica torrent-ul : '%1' + + + This file is either corrupted or this isn't a torrent. + Acest fişier este deteriorat sau nu este torrent. + + + Error: The torrent %1 does not contain any file. + + + + Note: new trackers were added to the existing torrent. + + + + Note: new URL seeds were added to the existing torrent. + + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>a fost blocat conform IP filtrului</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>a fost banat din cauza fragmentelor eronate</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Descarcă recursiv fișierul %1 din torrentul %2 + + + Unable to decode %1 torrent file. + Nu pot citi torrentul %1. + + + Torrent name: %1 + + + + Torrent size: %1 + + + + Save path: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + + + + Thank you for using qBittorrent. + + + + [qBittorrent] %1 has finished downloading + + + + An I/O error occured, '%1' paused. + + + + Reason: %1 + + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port mapping failure, message: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port mapping successful, message: %1 + + + File sizes mismatch for torrent %1, pausing it. + + + + Fast resume data was rejected for torrent %1, checking again... + Resumarea rapidă a fost respinsă pentru torrent-ul %1, verific încă o dată... + + + Url seed lookup failed for url: %1, message: %2 + Conectarea la seed a eşuat pentru : %1, mesajul : %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Descarc '%1', vă rugăm să aşteptaţi... + + + The network interface defined is invalid: %1 + + + + Trying any other network interface available instead. + + + + Listening on IP address %1 on network interface %2... + + + + Failed to listen on network interface %1 + + + + UPnP / NAT-PMP support [ON] + + + + UPnP / NAT-PMP support [OFF] + + + + Local Peer Discovery support [ON] + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + + + + Error: Failed to parse the provided IP filter. + + + + Reporting IP address %1 to trackers... + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + + + + + RSS + + Search + Caută + + + Delete + Şterge + + + Rename + Redenumeşte + + + Refresh RSS streams + Reînnoieşte firul RSS + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + + + Download torrent + Descarcă torrent-ul + + + Open news URL + Deschide noutățile URL + + + Copy feed URL + Copie URL feed-ul + + + New subscription + Noua subsriere + + + Mark items read + Marchează itemii citiți + + + Update all + Reînnoiește toate + + + Update all feeds + Reînnoiește toate feed-urile + + + RSS feeds + RSS feed-uri + + + Update + Reînnoiește + + + Feed URL + Feed URL + + + Article title + TItlul articolului + + + Rename... + Redenumește... + + + New subscription... + + + + New folder... + + + + Manage cookies... + + + + Settings... + + + + RSS Downloader... + + + + + RSSImp + + Please type a rss stream url + Introduceţi adresa URL la RSS fir + + + Stream URL: + Adresa URL: + + + Are you sure? -- qBittorrent + Sunteţi siguri? -- qBittorrent + + + &Yes + &Yes + + + &No + &No + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + Acest RSS este deacum în listă. + + + Date: + Data: + + + Author: + Autor: + + + Please choose a folder name + Vă rugăm să alegeți altă denumire a directoriului + + + Folder name: + Denumirea folder-ului: + + + New folder + Nou directoriu + + + Are you sure you want to delete these elements from the list? + Doriti sa ștergeți aceste elemente? + + + Are you sure you want to delete this element from the list? + Sunteti siguri că doriti sa stergeti elementele selectate din listă? + + + Please choose a new name for this RSS feed + Alegeți alt nume pentru această listă RSS + + + New feed name: + Nou nume: + + + Name already in use + Numele este deacum utilizat + + + This name is already used by another item, please choose another one. + Numele este utilizat, alegeți altul. + + + Overwrite attempt + Încercare de rescriere + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Nu puteți rescri itemul %1. + + + Unread + Recitit + + + + RssArticle + + No description available + Descrierea nu este disponobilă + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + Automat descarcă torrentul %1 din lista RSS %2... + + + + RssItem + + No description available + Descrierea nu este disponobilă + + + + RssSettingsDlg + + RSS Reader Settings + + + + RSS feeds refresh interval: + + + + minutes + + + + Maximum number of articles per feed: + + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Automat descarcă torrentul %1 din lista RSS %2... + + + + ScanFoldersModel + + Watched Folder + + + + Download here + + + + + SearchCategories + + All categories + Toate categoriile + + + Movies + Filme + + + TV shows + TV show-uri + + + Music + Muzică + + + Games + Jocuri + + + Anime + Anime + + + Software + Soft + + + Pictures + Fotografii + + + Books + Cărți + + + + SearchEngine + + Empty search pattern + Şablonul de căutat este vid + + + Please type a search pattern first + Vă rugăm să completaţi şablonul de căutare + + + Results + Rezultate + + + Searching... + Căutare... + + + Cut + Tăiere + + + Copy + Copiere + + + Paste + Pune + + + Clear field + Ștergerea cîmpului + + + Clear completion history + Șterge istoria de completare + + + Search Engine + Motor de Căutare + + + Search has finished + Căutarea a fost terminată + + + An error occured during search... + Eroare în timpul căutării... + + + Search aborted + Cautarea abordată + + + Search returned no results + Cautarea nu a returnat rezultate + + + Results + i.e: Search results + Rezultate + + + Unknown + Necunoscut + + + Search + Caută + + + Download error + Eroare de descărcare + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + + + + Missing Python Interpreter + + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + + + + Confirmation + + + + Are you sure you want to clear the history? + + + + + SearchTab + + Name + i.e: file name + Nume + + + Size + i.e: file size + Capacitate + + + Seeders + i.e: Number of full sources + Seederi + + + Leechers + i.e: Number of partial sources + Leecheri + + + Search engine + Motorul de căutare + + + + ShutdownConfirmDlg + + Shutdown confirmation + + + + + SpeedLimitDialog + + KiB/s + KiB/s + + + + StatusBar + + Connection status: + Starea conectării: + + + No direct connections. This may indicate network configuration problems. + Nu sunt connectări directe. Aceasta poate indica la probleme cu rețeaua. + + + DHT: %1 nodes + DHT: %1 noduri + + + Connection Status: + Starea conectării: + + + Online + Conectat + + + Global Download Speed Limit + Limita globală de descărcare + + + Global Upload Speed Limit + Limita globală de încărcare + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + D: %1/s - T: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + U: %1/s - T: %2 + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + D: %1 B/s - T: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + U: %1 B/s - T: %2 + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + + + qBittorrent needs to be restarted + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + + + + Click to switch to alternative speed limits + + + + Click to switch to regular speed limits + + + + %1/s + Per second + %1/s + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + Seletaţi directoriul pentru a fi adăugat în torrent fişier + + + Select a file to add to the torrent + Selectaţi un fişier pentru al adăuga la torrent + + + Please type an announce URL + Introduceţi URL-ul de anunţare + + + Announce URL: + Tracker URL + URL-ul de anunţare: + + + Please type a web seed url + Introduceţi URL-ul de web seed + + + Web seed URL: + Web seed URL: + + + No input path set + Nu sunt selectate fişiere de intrare + + + Please type an input path first + Vă rugăm să arătaţi calea de intrare + + + Select destination torrent file + Selectează fişierul de destinare + + + Torrent Files + Fişiere Torrent + + + Torrent creation + Crearea torentului + + + Torrent creation was unsuccessful, reason: %1 + Crearea torrent-ului a eşuat, motivul: %1 + + + Created torrent file is invalid. It won't be added to download list. + Fişierul torrent creat este deteriorat. El nu va fi adăugat în lista de download-uri. + + + Torrent was created successfully: + Torrentul a fost creat cu success: + + + + TorrentFilesModel + + Name + Nume + + + Size + Capacitate + + + Progress + Progress + + + Priority + Prioritate + + + + TorrentImportDlg + + Torrent Import + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + + + + Torrent file to import: + + + + ... + ... + + + Content location: + + + + Skip the data checking stage and start seeding immediately + + + + Import + + + + Torrent file to import + + + + Torrent files (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + + + + Please provide the location of %1 + %1 is a file name + + + + Please point to the location of the torrent: %1 + + + + Invalid torrent file + + + + This is not a valid torrent file. + + + + + TorrentModel + + Name + i.e: torrent name + Nume + + + Size + i.e: torrent size + Capacitate + + + Done + % Done + Obținut + + + Status + Torrent status (e.g. downloading, seeding, paused) + Stare + + + Seeds + i.e. full sources (often untranslated) + Seeds + + + Peers + i.e. partial sources (often untranslated) + Peer-i + + + Down Speed + i.e: Download speed + Viteza de descărcare + + + Up Speed + i.e: Upload speed + + + + Ratio + Share ratio + Rata + + + ETA + i.e: Estimated Time of Arrival / Time left + ETA + + + Label + Etichetă + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + + + + Completed On + Torrent was completed on 01/01/2010 08:00 + + + + Tracker + + + + Down Limit + i.e: Download limit + + + + Up Limit + i.e: Upload limit + + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + + + + Amount left + Amount of data left to download (e.g. in MB) + + + + Time Active + Time (duration) the torrent is active (not paused) + + + + + TrackerList + + URL + URL + + + Status + Stare + + + Peers + Peer-i + + + Message + Mesaj + + + [DHT] + [DHT] + + + Working + Lucrează + + + Disabled + Dezactivată + + + This torrent is private + Acest torrent este privat + + + Updating... + Reînnoire... + + + Not working + Nu lucrează + + + Not contacted yet + Nu a fost contactat + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Add a new tracker... + + + + Remove tracker + + + + Force reannounce + + + + + TrackersAdditionDlg + + Trackers addition dialog + Dialogul de adaugare a trackerilor + + + List of trackers to add (one per line): + Lista trackerilor(unul pe linie): + + + µTorrent compatible list URL: + µTorrent compatible list URL: + + + I/O Error + I/O Error + + + Error while trying to open the downloaded file. + Error while trying to open the downloaded file. + + + No change + No change + + + No additional trackers were found. + No additional trackers were found. + + + Download error + Eroare de descărcare + + + The trackers list could not be downloaded, reason: %1 + The trackers list could not be downloaded, reason: %1 + + + + TransferListDelegate + + Downloading + Descărcarea + + + Paused + Pauzat + + + Queued + i.e. torrent is queued + În coadă + + + Seeding + Torrent is complete and in upload-only mode + Sedarea + + + Stalled + Torrent is waiting for download to begin + Oprit + + + Checking + Torrent local data is being checked + Verificare + + + /s + /second (.i.e per second) + /s + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + Seeded for %1 + e.g. Seeded for 3m10s + + + + + TransferListFiltersWidget + + All + Toate + + + Downloading + Descărcarea + + + Completed + Completat + + + Active + Activ + + + Inactive + Inactiv + + + All labels + Toate etichetele + + + Unlabeled + Unlabeled + + + Remove label + Șterge eticheta + + + New Label + Etichetă nouă + + + Label: + Etichetă: + + + Invalid label name + Numele etichetei invalid + + + Please don't use any special characters in the label name. + Please don't use any special characters in the label name. + + + Paused + Pauzat + + + Add label... + + + + Resume torrents + + + + Pause torrents + + + + Delete torrents + + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + ETA + + + Column visibility + Vizibilitatea coloanei + + + Open destination folder + Deschide directoriul destinaţie + + + Force recheck + Reverificarea forţată + + + Copy magnet link + Copie link-ul magnet + + + Down Speed + i.e: Download speed + Viteza de descărcare + + + Up Speed + i.e: Upload speed + Viteza de încărcare + + + Name + i.e: torrent name + Nume + + + Size + i.e: torrent size + Capacitate + + + Done + % Done + Obținut + + + Status + Torrent status (e.g. downloading, seeding, paused) + Stare + + + Seeds + i.e. full sources (often untranslated) + Seeds + + + Peers + i.e. partial sources (often untranslated) + Peer-i + + + Ratio + Share ratio + Rata + + + Torrent Download Speed Limiting + Limitarea vitezei de descărcare pentru torrent + + + Torrent Upload Speed Limiting + Limitarea vitezei de încărcare pentru torrent + + + Super seeding mode + Mod de super sedare + + + Download in sequential order + Descarcă în ordine secvențială + + + Download first and last piece first + Descarcă prima și ultima parte din fișier + + + Label + Etichetă + + + New Label + Etichetă nouă + + + Label: + Etichetă: + + + New... + New label... + Nou... + + + Reset + Reset label + Resetează + + + Rename + Redenumești + + + New name: + Nume nou: + + + Rename... + Redenumește... + + + Invalid label name + Numele etichetei invalid + + + Please don't use any special characters in the label name. + Please don't use any special characters in the label name. + + + Choose save path + Alegeţi calea de salvare + + + Save path creation error + Salvează calea care crează erori + + + Could not create the save path + Nu pot crea calea de salvare + + + Set location... + + + + Preview file... + + + + Limit upload rate... + + + + Limit download rate... + + + + Move up + i.e. move up in the queue + + + + Move down + i.e. Move down in the queue + + + + Move to top + i.e. Move to top of the queue + + + + Move to bottom + i.e. Move to bottom of the queue + + + + Priority + Prioritate + + + Resume + Resume/start the torrent + + + + Pause + Pause the torrent + Pauză + + + Delete + Delete the torrent + Şterge + + + Limit share ratio... + + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + + + + Use global ratio limit + + + + buttonGroup + + + + Set no ratio limit + + + + Set ratio limit to + + + + + UsageDisplay + + Usage: + Utilizat: + + + displays program version + displays program version + + + disable splash screen + disable splash screen + + + displays this help message + displays this help message + + + changes the webui port (current: %1) + changes the webui port (current: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [files or urls]: downloads the torrents passed by the user (optional) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + Eu vreau să mulţumesc voluntarilor care au translat qBittorrent: + + + Please contact me if you would like to translate qBittorrent into your own language. + Contactaţimă dacă doriţi să traduceţi qBittorrent in limba dumneavoastră. + + + + addPeerDialog + + Peer addition + Adaugă peer + + + IP + IP + + + Port + Port + + + + addTorrentDialog + + Torrent addition dialog + Dialogul de adăugare a torrentului + + + Save path: + Calea de salvare: + + + ... + ... + + + Torrent content: + Conţinutul torrent-ului: + + + Add to download list in paused state + Adauga în lista de descărcare în stare de pauză + + + Add + Adaugă + + + Cancel + Anulare + + + Normal + Normal + + + High + Înalt + + + Maximum + Maximal + + + Torrent size: + Dimensiunea torrentului: + + + Unknown + Necunoscut + + + Free disk space: + Spațiu liber: + + + Download in sequential order (slower but good for previewing) + Descarcă în ordine secvențială (încet dar bine pentru preview) + + + Skip file checking and start seeding immediately + Nu verifica integritatea, începe sedarea imediat + + + Label: + Etichetă: + + + Select All + + + + Select None + + + + Do not download + + + + + authentication + + Tracker authentication + Autentificarea pe Tracker + + + Tracker: + Tracker: + + + Login + Login + + + Username: + Numele de utilizator: + + + Password: + Parola: + + + Log in + Logare + + + Cancel + Anulare + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + Confirmarea ștergerii - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + Sunteți siguri că doriți să ștergeți torrent-urile selectate ? + + + Remember choice + + + + Also delete the files on the hard disk + + + + + createTorrentDialog + + Cancel + Anulare + + + Torrent Creation Tool + Crearea Torrentului + + + Torrent file creation + Locaţia de creare a torrent-ului + + + Announce urls (trackers): + URL-uri de anunţare (tracke-ri): + + + Comment (optional): + Comentariu(opţional): + + + Web seeds urls (optional): + Web sedări(opţional): + + + File or folder to add to the torrent: + Fişier sau directoriu pentru a adăuga torentul: + + + Piece size: + Dimensiunea bucăţii: + + + 32 KiB + 32 KiB + + + 64 KiB + 64 KiB + + + 128 KiB + 128 KiB + + + 256 KiB + 256 KiB + + + 512 KiB + 512 KiB + + + 1 MiB + 1 MiB + + + 2 MiB + 2 MiB + + + 4 MiB + 4 MiB + + + Private (won't be distributed on DHT network if enabled) + Privat(nu va fi distribuit prin reţeaua DHT dacă este activată) + + + Start seeding after creation + Începe sedarea după creare + + + Create and save... + Crează şi salvează... + + + Progress: + Progress: + + + Add file + Adaugă fișier + + + Add folder + Adaugă directoriu + + + Tracker URLs: + + + + Web seeds urls: + + + + Comment: + Comentarii: + + + Auto + + + + + createtorrent + + Select destination torrent file + Selectează fişierul de destinare + + + Torrent Files + Fişiere Torrent + + + No input path set + Nu sunt selectate fişiere de intrare + + + Please type an input path first + Vă rugăm să arătaţi calea de intrare + + + Torrent creation + Crearea torentului + + + Torrent was created successfully: + Torrentul a fost creat cu success: + + + Select a folder to add to the torrent + Seletaţi directoriul pentru a fi adăugat în torrent fişier + + + Please type an announce URL + Introduceţi URL-ul de anunţare + + + Torrent creation was unsuccessful, reason: %1 + Crearea torrent-ului a eşuat, motivul: %1 + + + Announce URL: + Tracker URL + URL-ul de anunţare: + + + Please type a web seed url + Introduceţi URL-ul de web seed + + + Web seed URL: + Web seed URL: + + + Select a file to add to the torrent + Selectaţi un fişier pentru al adăuga la torrent + + + Created torrent file is invalid. It won't be added to download list. + Fişierul torrent creat este deteriorat. El nu va fi adăugat în lista de download-uri. + + + + downloadFromURL + + Download Torrents from URLs + Descărcarea Torrent-uri de pe URL-uri + + + Only one URL per line + Numai un URL pe linie + + + Download + Descarcă + + + Cancel + Anulare + + + Download from urls + Descărcare de pe url-uri + + + No URL entered + Nu este introdus URL-ul + + + Please type at least one URL. + Vă rugăm să introduceţi cel puţin un URL. + + + Add torrent links + + + + Both HTTP and Magnet links are supported + + + + + downloadThread + + I/O Error + Eroare de intrare/eşire + + + The remote host name was not found (invalid hostname) + Numele host-ului nu a fost găsit(nume invalid) + + + The operation was canceled + Operțiunea a fost anulată + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Serverul a închis conectarea înainte ca să recepționez și proceses răspunsul + + + The connection to the remote server timed out + Timpul de conectare la server a expirat + + + SSL/TLS handshake failed + Conectarea SSL/TLS eșuată + + + The remote server refused the connection + Serverul refuză conectarea + + + The connection to the proxy server was refused + Conectarea prin proxy server refuzată + + + The proxy server closed the connection prematurely + Serverul proxy a închis conectarea pre deverme + + + The proxy host name was not found + Numele serverului proxy nu este găsit + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Timpul de conectare la proxy a expirat + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + The proxy requires authentication in order to honour the request but did not accept any credentials offered + + + The access to the remote content was denied (401) + The access to the remote content was denied (401) + + + The operation requested on the remote content is not permitted + The operation requested on the remote content is not permitted + + + The remote content was not found at the server (404) + The remote content was not found at the server (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + The remote server requires authentication to serve the content but the credentials provided were not accepted + + + The Network Access API cannot honor the request because the protocol is not known + The Network Access API cannot honor the request because the protocol is not known + + + The requested operation is invalid for this protocol + The requested operation is invalid for this protocol + + + An unknown network-related error was detected + An unknown network-related error was detected + + + An unknown proxy-related error was detected + An unknown proxy-related error was detected + + + An unknown error related to the remote content was detected + An unknown error related to the remote content was detected + + + A breakdown in protocol was detected + A breakdown in protocol was detected + + + Unknown error + Eroare necunoscută + + + + engineSelect + + Search plugins + Plugin-uri de căutare + + + Installed search engines: + Motoare de căutare instalare: + + + Name + Nume + + + Url + Url + + + Enabled + Activată + + + Install a new one + Instalez un nou + + + Check for updates + Verifică pentru veriuni mai noi + + + Close + Închide + + + Enable + Activează + + + Disable + Dezactivat + + + Uninstall + Dezinstalează + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + engineSelectDlg + + Uninstall warning + Avertizare de dezinstalare + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Unele plug-inuri nu pot fi dezinstalate deoarece sunt incluse în qBittorrent. +Numai acele adăugate de dvs. pot fi dezinstalate. + + + + Uninstall success + Dezinstalare cu success + + + Select search plugins + Alege motorul de căutare + + + qBittorrent search plugins + Plugin-urilie de căutare al qBittorrent + + + Search plugin install + Caută plugin-ul instalat + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + O versiune mai recentă de al motorului de căutare %1 este de acum instalată. + + + Search plugin update + Reînnoirea plugin-ului de căutare + + + Sorry, update server is temporarily unavailable. + Ne cerem ertare, serverul este temporar inaccesibil. + + + All your plugins are already up to date. + Totate plugin-urile dvs sunt deacum reînnoite. + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 motorul de căutare nu a putut fi reînnoit, folosesc versiunea veche. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + motorul de căutare %1 nu poate fi instalat. + + + All selected plugins were uninstalled successfully + Toate plugin-urile selectate sunt dezinstalate cu success + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + motorul de căutare %1 a fost reînnoit cu success. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + motorul de căutare %1 a fost instalat cu success. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Instalarea motorului de căutare %1 a eşuat. + + + New search engine plugin URL + Adresa noului motor de căutare URL + + + URL: + URL: + + + Yes + Da + + + No + Ny + + + + misc + + B + bytes + B + + + KiB + kibibytes (1024 bytes) + Kib + + + MiB + mebibytes (1024 kibibytes) + Mib + + + GiB + gibibytes (1024 mibibytes) + GiB + + + TiB + tebibytes (1024 gibibytes) + TiB + + + Unknown + Necunoscut + + + Unknown + Unknown (size) + Necunoscut + + + < 1m + < 1 minute + < 1m + + + %1m + e.g: 10minutes + %1m + + + %1h %2m + e.g: 3hours 5minutes + + + + %1d %2h + e.g: 2days 10hours + + + + qBittorrent will shutdown the computer now because all downloads are complete. + + + + + options_imp + + Choose a save directory + Selectează directoriul de salvare + + + Choose an ip filter file + Alageţi un fişier ip filtru + + + Filters + Filtre + + + Choose export directory + + + + Add directory to scan + + + + Folder is already being watched. + + + + Folder does not exist. + + + + Folder is not readable. + + + + Failure + + + + Failed to add Scan Folder '%1': %2 + + + + Parsing error + + + + Failed to parse the provided IP filter + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + + + + Successfully refreshed + + + + Invalid key + + + + This is not a valid SSL key. + + + + Invalid certificate + + + + This is not a valid SSL certificate. + + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + + pluginSourceDlg + + Plugin source + Sursa plugin-ului + + + Search plugin source: + Caută sursa plugin-ului: + + + Local file + Fişier local + + + Web link + Legătură web + + + + preview + + Preview selection + Secţia de preview + + + File preview + Preview Fişier + + + The following files support previewing, <br>please select one of them: + Următoarele fişiere suportă preview, <br>selectaţi unul din ei: + + + Preview + Preview + + + Cancel + Anulare + + + + previewSelect + + Preview impossible + Preview imposibil + + + Sorry, we can't preview this file + Nu putem face preview pentru acest fişier + + + Name + Nume + + + Size + Capacitate + + + Progress + Progress + + + + search_engine + + Search + Caută + + + Status: + Stare: + + + Stopped + Oprit + + + Download + Descarcă + + + Search engines... + Motoare de căutare... + + + Go to description page + + + + + torrentAdditionDialog + + Unable to decode torrent file: + Nu pot decoda fişierul torrent: + + + Choose save path + Alegeţi calea de salvare + + + Empty save path + Calea de salvare vidă + + + Please enter a save path + Vă rugăm să introduceţi calea de salvare + + + Save path creation error + Salvează calea care crează erori + + + Could not create the save path + Nu pot crea calea de salvare + + + Invalid file selection + Selecţia fişierului invalidă + + + You must select at least one file in the torrent + Trebuie să selectaţi cel puţin un fişier din torrent + + + Priority + Prioritate + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 rămas după descărcare torrent-ului) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 mai mult este necesar pentru a descărca) + + + Seeding mode error + Eroare în modul de sedare + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + + + Rename... + Redenumește... + + + New name: + Nume nou: + + + The file could not be renamed + Fișierul nu poate fi redenumit + + + This name is already in use in this folder. Please use a different name. + This name is already in use in this folder. Please use a different name. + + + The folder could not be renamed + The folder could not be renamed + + + Rename the file + Rename the file + + + Unable to decode magnet link: + Unable to decode magnet link: + + + Magnet Link + Link-ul Magnet + + + Invalid label name + Numele este invalid + + + Please don't use any special characters in the label name. + Please don't use any special characters in the label name. + + + This file name contains forbidden characters, please choose a different one. + This file name contains forbidden characters, please choose a different one. + + + diff --git a/src/lang/qbittorrent_ru.qm b/src/lang/qbittorrent_ru.qm new file mode 100644 index 0000000000000000000000000000000000000000..31482bd6a2dd4a68c3e8a5cf372579d50c5e5dda GIT binary patch literal 120268 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 literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_ru.ts b/src/lang/qbittorrent_ru.ts new file mode 100644 index 000000000..15c23d74c --- /dev/null +++ b/src/lang/qbittorrent_ru.ts @@ -0,0 +1,5741 @@ + + + + + AboutDlg + + About qBittorrent + О qBittorrent + + + About + О программе + + + Author + Автор + + + Name: + Имя: + + + Country: + Страна: + + + E-mail: + Электронная почта: + + + Christophe Dumez + Кристоф Дюме (Christophe Dumez) + + + France + Франция + + + Translation + Перевод + + + License + Лицензия + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + chris@qbittorrent.org + chris@qbittorrent.org + + + Thanks to + Благодарности + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Bittorrent клиент, написанный на C++ с использованием библиотеки Qt4 </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">и libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Домашняя страница:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Форум:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent на Freenode</span></p></body></html> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Продвинутый BitTorrent клиент, написанный на C++ с использованием библиотек Qt4 и libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Домашняя страница:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Форум:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent на Freenode</span></p></body></html> + + + + AdvancedSettings + + Property + Свойство + + + Value + Значение + + + Ignore transfer limits on local network + Игнорировать лимиты в локальной сети + + + Include TCP/IP overhead in transfer limits + Включать TCP/IP заголовки в лимит передачи + + + Disk write cache size + Дисковый кеш записи + + + MiB + МиБ + + + Outgoing ports (Min) [0: Disabled] + Исходящие порты (Мин) [0: Отключено] + + + Outgoing ports (Max) [0: Disabled] + Исходящие порты (Макс) [0: Отключено] + + + Recheck torrents on completion + Перепроверить торрент по окончании + + + Transfer list refresh interval + Интеравал обновления списка торрентов + + + ms + milliseconds + мс + + + Resolve peer countries (GeoIP) + Определить страну пира (GeoIP) + + + Resolve peer host names + Определить имя хоста пира + + + Maximum number of half-open connections [0: Disabled] + Максимальное количество полуоткрытых соединений [0:Отключено] + + + Strict super seeding + Режим супер раздачи + + + Network Interface (requires restart) + Сетевой интерфейс (Требует перезагрузки) + + + Any interface + i.e. Any network interface + Любой интерфейс + + + Display program notification baloons + Показывать всплывающие сообщения в системном лотке + + + Display program notification balloons + Показывать всплывающие сообщения в системном лотке + + + Enable embedded tracker + Включить встроенный трекер + + + Embedded tracker port + Порт встроенного трекера + + + Check for software updates + Проверить обновления + + + Use system icon theme + Использовать системные иконки + + + IP Address to report to trackers (requires restart) + IP адрес для сообщения трекерам (требуется перезапуск) + + + Display program on-screen notifications + Показывать экранные сообщения + + + Confirm torrent deletion + Подтверждать удаление торрента + + + Setting + Параметр + + + Value + Value set for this setting + Значение + + + Exchange trackers with other peers + Обмениваться трекерами с другими пирами + + + + AutomatedRssDownloader + + Automated RSS Downloader + Автоматический загрузчик RSS + + + Enable the automated RSS downloader + Включить автоматический загрузчик RSS + + + Download rules + Правила загрузки + + + Rule definition + Описание правил + + + Must contain: + Должно содержать: + + + Must not contain: + Не должно содержать: + + + Save torrent to: + Сохранить торрент в: + + + ... + ... + + + Assign label: + Присвоить метку: + + + Apply rule to feeds: + Применить правило к каналу: + + + Matching RSS articles + Совпадающие RSS заголовки + + + Save to a different directory + Сохранить в другую папку + + + Save to: + Сохранить в: + + + Import... + Импорт... + + + Export... + Экспорт... + + + New rule name + Новое имя правила + + + Please type the name of the new download rule. + Введите имя нового правила скачивания. + + + Rule name conflict + Конфликт имени правила + + + A rule with this name already exists, please choose another name. + Правило с таким именем уже существует. Пожалуйста, выберите другое имя. + + + Are you sure you want to remove the download rule named %1? + Вы уверены, что хотите удалить правило загрузки %1? + + + Are you sure you want to remove the selected download rules? + Вы уверены, что хотите удалить выбранные правила загрузки? + + + Rule deletion confirmation + Подтверждение удаления правила + + + Destination directory + Папка назначения + + + Invalid action + Неверное действие + + + The list is empty, there is nothing to export. + Список пуст. Нечего экспортировать. + + + Where would you like to save the list? + Куда вы хотите соранить список? + + + Rules list (*.rssrules) + Списки правил (*.rssrules) + + + I/O Error + Ошибка ввода/вывода + + + Failed to create the destination file + Не удалось создать целевой файл + + + Please point to the RSS download rules file + Укажите файл с правилами загрузки RSS + + + Rules list (*.rssrules *.filters) + Списки правил (*.rssrules *.filters) + + + Import Error + Ошибка импорта + + + Failed to import the selected rules file + Ошибка импортирования выбранного файла правил + + + Add new rule... + Добавить правило... + + + Delete rule + Удалить правило + + + Rename rule... + Переименовать правило... + + + Delete selected rules + Удалить выбранные правила + + + Rule renaming + Переименование правила + + + Please type the new rule name + Введите новое имя правила + + + Use regular expressions + Использовать регулярные выражения + + + Regex mode: use Perl-like regular expressions + Режим Regex: использовать регулярные выражения в стиле Perl + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Режим Wildcard: можно использовать<ul><li>? для замещения любого одного символа</li><li>* для замещения нуля и более любых символов</li><li>Пробелы действуют как операторы AND</li></ul> + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Режим Wildcard: можно использовать<ul><li>? для замещения любого одного символа</li><li>* для замещения нуля и более любых символов</li><li>| используется как оператор OR</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 достиг установленного вами максимального соотношения. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent привязан к порту: TCP/%1 + + + UPnP support [ON] + Поддержка UPnP [Вкл] + + + UPnP support [OFF] + Поддержка UPnP [Выкл] + + + NAT-PMP support [ON] + Поддержка NAT-PMP [Вкл] + + + NAT-PMP support [OFF] + Поддержка NAT-PMP [Выкл] + + + DHT support [ON], port: UDP/%1 + Поддержка DHT [Вкл.], порт: UDP/%1 + + + DHT support [OFF] + Поддержка DHT [Выкл] + + + PeX support [ON] + Поддержка PeX [Вкл] + + + Local Peer Discovery [ON] + Обнаружение локальных пиров [Вкл] + + + Local Peer Discovery support [OFF] + Обнаружение локальных пиров [Выкл] + + + Encryption support [ON] + Поддержка шифрования [Вкл] + + + Encryption support [FORCED] + Поддержка шифрования [Принудительно] + + + Encryption support [OFF] + Поддержка шифрования [Выкл] + + + Web User Interface Error - Unable to bind Web UI to port %1 + Ошибка WEb интерфейса - Не могу привязаться к порту %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' был удален из списка передач и с жесткого диска. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' был удален из списка передач. + + + '%1' is not a valid magnet URI. + '%1' не является magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' уже присутствует в списке закачек. + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' добавлен в список закачек. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Не удалось декодировать torrent файл: '%1' + + + This file is either corrupted or this isn't a torrent. + Этот файл либо поврежден, либо не torrent типа. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>был заблокирован в соответствии с вашим IP фильтром</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>был заблокирован из-за поврежденных кусочков</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Рекурсивная загрузка файла %1 встроенного в торрент %2 + + + Unable to decode %1 torrent file. + Не удалось декодировать %1 torrent файл. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + Распределение портов UPnP/NAT-PMP не удалось с сообщением: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + Распределение портов UPnP/NAT-PMP прошло успешно: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Быстрое восстановление данных для torrentа %1 было невозможно, проверка заново... + + + Url seed lookup failed for url: %1, message: %2 + Поиск раздающего Url не удался: %1, сообщение: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Скачивание '%1', подождите... + + + Using a disk cache size of %1 MiB + Используется дисковый кеш размером %1 МиБ + + + PeX support [OFF] + Поддержка PeX [Выкл] + + + Restart is required to toggle PeX support + Необходимо перезапустить qBittorrent для включения настройки PeX + + + The Web UI is listening on port %1 + Web интерфейс прослушивает пор %1 + + + HTTP user agent is %1 + Браузер %1 + + + Reason: %1 + Причина: %1 + + + Note: new trackers were added to the existing torrent. + Примечание: новые трекеры были добавлены к существующему торренту. + + + Note: new URL seeds were added to the existing torrent. + Примечание: новые URL сидов были добавлены к существующему торренту. + + + An I/O error occured, '%1' paused. + Ошибка Ввода/Вывода: '%1' приостановлен. + + + Removing torrent %1... + Удаление торрента %1... + + + Pausing torrent %1... + Приостановка торрента %1... + + + Error: The torrent %1 does not contain any file. + Ошибка: Торрент %1 не содержит никаких файлов. + + + File sizes mismatch for torrent %1, pausing it. + Несовпадение размеров файлов для торрента %1, приостанавливаю его. + + + Torrent name: %1 + Имя торрента: %1 + + + Torrent size: %1 + Размер торрента: %1 + + + Save path: %1 + Путь для сохранения: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Торрент был скачен за %1. + + + Thank you for using qBittorrent. + Спасибо за использование qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] скачивание %1 завершено + + + + ConsoleDlg + + General + Общие + + + Blocked IPs + Заблокированные IP + + + qBittorrent log viewer + Просмотрщик журнала qBittorrent + + + + CookiesDlg + + Cookies management + Управление Cookies + + + Key + As in Key/Value pair + Ключ + + + Value + As in Key/Value pair + Значение + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + 'из настроек' - в firefox 3.6.4 + Частые ключи для cookies это : '%1', '%2'. +Вам следует взять эту информацию из настроек вашего веб-браузера. + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + Ваш динамический DNS адрес был успешно обновлён. + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Ошибка Dynamic DNS: Служба временно не доступна. Попробую соединиться через 30 минут. + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Ошибка Dynamic DNS:предоставленное имя хоста не существует в указанной учётной записи. + + + Dynamic DNS error: Invalid username/password. + Ошибка Dynamic DNS: Неверное имя пользователя/пароль. + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Ошибка Dynamic DNS: qBittorrent внесён службой в чёрный список. Пожалуйста, сообщите об ошибке на http://bugs.qbittorrent.org. + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Ошибка Dynamic DNS: %1 было возвращено службой. Пожалуйста, сообщите об ошибке на http://bugs.qbittorrent.org. + + + Dynamic DNS error: Your username was blocked due to abuse. + Ошибка Dynamic DNS: Ваше имя пользователя было блокировано из-за злоупотребления. + + + Dynamic DNS error: supplied domain name is invalid. + Ошибка Dynamic DNS: предоставленное доменное имя неверное. + + + Dynamic DNS error: supplied username is too short. + Ошибка Dynamic DNS: предоставленное имя пользователя слишком короткое. + + + Dynamic DNS error: supplied password is too short. + Ошибка Dynamic DNS: предоставленный пароль слишком короткий. + + + + DownloadThread + + I/O Error + Ошибка ввода/вывода + + + The remote host name was not found (invalid hostname) + Удаленный хост не был найден (неправильное имя хоста) + + + The operation was canceled + Операция была отменена + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Удаленный сервер закрыл соединение, прежде чем весь ответ был принят и обработан + + + The connection to the remote server timed out + Время соединения с удаленным сервером вышло + + + SSL/TLS handshake failed + Соединение SSL/TLS не удалось + + + The remote server refused the connection + Удаленный сервер отклонил соединение + + + The connection to the proxy server was refused + Прокси-сервер отклонил соединение + + + The proxy server closed the connection prematurely + Прокси-сервер преждевременно закрыл соединение + + + The proxy host name was not found + Имя прокси-сервера не было найдено + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Подключение к прокси-серверу истекло или прокси-сервер не ответил на запрос + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Прокси-сервер требует аутентификации, но не принял указанные учетные данные + + + The access to the remote content was denied (401) + В доступе к данным было отказано (401) + + + The operation requested on the remote content is not permitted + В данной операции над данными отказано + + + The remote content was not found at the server (404) + Данные не были найдены на сервере (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Удаленный сервер требует аутентификацию для отдачи данных, но указанные учетные данные не были приняты + + + The Network Access API cannot honor the request because the protocol is not known + API сетевого доступа не может выполнить запрос, потому что протокол не известен + + + The requested operation is invalid for this protocol + Запрошенная операция не поддерживается данным протоколом + + + An unknown network-related error was detected + Неизвестная сетевая ошибка + + + An unknown proxy-related error was detected + Неизвестная ошибка прокси-сервера + + + An unknown error related to the remote content was detected + Неизвестная ошибка данных + + + A breakdown in protocol was detected + Ошибка в протоколе + + + Unknown error + Неизвестная ошибка + + + + EventManager + + %1/s + e.g. 120 KiB/s + %1/с + + + Working + Работает + + + Updating... + Обновляется... + + + Not working + Не работает + + + Not contacted yet + Не соединился + + + this session + эта сессия + + + /s + /second (i.e. per second) + + + + Seeded for %1 + e.g. Seeded for 3m10s + Раздается %1 + + + %1 max + e.g. 10 max + %1 макс + + + + ExecutionLog + + Form + Форма + + + General + Общие + + + Blocked IPs + Заблокированные IP + + + + FeedDownloader + + RSS Feed downloader + dont understand perfectly what is this 'downloader' + Загрузка RSS канала + + + RSS feed: + RSS канал: + + + Feed name + Имя канала + + + Automatically download torrents from this feed + Автоматически загружать торренты с этого канала + + + Download filters + Фильтр загрузок + + + Filters: + Фильтры: + + + Filter settings + Настройки фильтра + + + Matches: + Совпадения: + + + Does not match: + Не совпадают: + + + Destination folder: + Папка назначения: + + + ... + ... + + + Filter testing + Тестирование фильтра + + + Torrent title: + Заголовок торрента: + + + Result: + Результат: + + + Test + Тест + + + Import... + Импорт... + + + Export... + Экспорт... + + + Rename filter + Переименовать фильтр + + + Remove filter + Удалить фильтр + + + Add filter + Добавить фильтр + + + + FeedDownloaderDlg + + New filter + Новый фильтр + + + Please choose a name for this filter + Пожалуйста, выберите имя для этого фильтра + + + Filter name: + имя фильтра: + + + Invalid filter name + Неправильное имя фильтра + + + The filter name cannot be left empty. + Имя фильтра не может быть пустым. + + + This filter name is already in use. + Это имя фильтра уже используется. + + + Filter testing error + Ошибка тестирования фильтра + + + Please specify a test torrent name. + Пожалуйста, укажите имя тестового торрента. + + + matches + совпадения + + + does not match + не совпадают + + + Select file to import + Выберите файл для импорта + + + Filters Files + Файлы фильтров + + + Import successful + Импорт завершен + + + Filters import was successful. + Импорт фильтров завершен. + + + Import failure + Ошибка при импорте + + + Filters could not be imported due to an I/O error. + Фильтры не импортированы из-за ошибки ввода/вывода. + + + Select destination file + Выберите файл назначения + + + Export successful + Экспорт завершен + + + Filters export was successful. + Экспорт фильтров завершен. + + + Export failure + Ошибка при экспорте + + + Filters could not be exported due to an I/O error. + Фильтры не экспортированы из-за ошибки ввода/вывода. + + + Choose save path + Выберите путь сохранения + + + + FeedList + + Unread + Не прочитано + + + + FeedListWidget + + RSS feeds + RSS каналы + + + Unread + Не прочитано + + + + GUI + + qBittorrent + qBittorrent + + + Open Torrent Files + Открыть файлы Torrent + + + Torrent Files + Файлы Torrent + + + Transfers + Передачи + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Скорость скач.: %1 KiB/с + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Отдача: %1 KiB/с + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + скачивание %1 завершено. + + + I/O Error + i.e: Input/Output Error + Ошибка ввода/вывода + + + Search + Поиск + + + RSS + RSS + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Произошла ошибка ввода/вывода для торрента %1. +Причина: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Ошибка при скачивании URL + + + Couldn't download file at url: %1, reason: %2. + Невозможно скачать файл по URL: %1, причина: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Options were saved successfully. + Настройки были успешно сохранены. + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Есть активные торренты. Вы уверены что хотите выйти из qBittorrent? + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Глобальное ограничение скорости раздачи + + + Global Download Speed Limit + Глобальное ограничение скорости закачки + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Скач: %2/с, Отд: %3/с) + + + Recursive download confirmation + Подтверждение рекурсивной загрузки + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Коряво как-то получилось >_< // нормально. + Торрент %1 содержит торрент-файлы, хотите ли вы приступить к их загрузке? + + + Transfers (%1) + Передачи (%1) + + + Torrent file association + Из systemsettings (KDE 4.4.5) + Привязки торрент-файлов + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + Может лучше наоборот, ссылки с файлами к qBittorrent привязывать? + qBittorrent сейчас не является приложением по умолчанию для открытия торрент-файлов или Magnet-ссылок. +Хотите ли вы открывать торрент-файлы и Magnet-ссылки с помощью qBittorrent? + + + Yes + Да + + + No + Нет + + + Never + Никогда + + + Always + Всегда + + + Exiting qBittorrent + Или Завершаю работу будет правильнее? + Завершение работы qBittorrent + + + Set the password... + Установить пароль... + + + Password update + Обновить пароль + + + The UI lock password has been successfully updated + Пароль блокировки интерфейса был успешно обновлен + + + UI lock password + Пароль блокировки интерфейса + + + Please type the UI lock password: + Пожалуйста, введите пароль блокировки интерфейса: + + + Invalid password + Не верный пароль + + + The password is invalid + Этот пароль не верен + + + A newer version is available + Новая версия доступна + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Новая версия qBittorrent доступна на Sourceforge. +Хотите обновить qBittorrent до версии %1? + + + Impossible to update qBittorrent + Невозможно обновить qBittorrent + + + qBittorrent failed to update, reason: %1 + qBitttorrent не может быть обновлен. Причина: %1 + + + + GeoIP + + Australia + Австралия + + + Argentina + Аргентина + + + Austria + Австрия + + + United Arab Emirates + Объединенные Арабские Эмираты + + + Brazil + Бразилия + + + Bulgaria + Болгария + + + Belarus + Беларусь + + + Belgium + Бельгия + + + Bosnia + Босния + + + Canada + Канада + + + Czech Republic + http://translate.google.com/#en|ru|Czech%20Republic + Чешская Республика + + + China + Китай + + + Costa Rica + Коста Рика + + + Switzerland + Швейцария + + + Germany + Германия + + + Denmark + http://translate.google.com/#en|ru|Denmark + Дания + + + Algeria + http://translate.google.com/#en|ru|Algeria + Алжир + + + Spain + Испания + + + Egypt + Египет + + + Finland + Финляндия + + + France + Франция + + + United Kingdom + http://translate.google.com/#en|ru|United%20Kingdom + Великобритания + + + Greece + Греция + + + Georgia + Грузия + + + Hungary + Венгрия + + + Croatia + http://translate.google.com/#en|ru|Croatia + Хорватия + + + Italy + Италия + + + India + Индия + + + Israel + Израиль + + + Ireland + Ирландия + + + Iceland + Исландия + + + Indonesia + Индонезия + + + Japan + ^_^ + Япония + + + South Korea + Южная Корея + + + Luxembourg + http://translate.google.com/#en|ru|Luxembourg + Люксембург + + + Malaysia + Малазия + + + Mexico + http://translate.google.com/#en|ru|Mexico + Мексика + + + Serbia + Сербия + + + Morocco + http://translate.google.com/#en|ru|Morocco + Марокко + + + Netherlands + Нидерланды + + + Norway + Норвегия + + + New Zealand + Новая Зеландия + + + Portugal + Португалия + + + Poland + Польша + + + Pakistan + Пакистан + + + Philippines + Филиппины + + + Russia + Россия + + + Romania + http://translate.google.com/#en|ru|Romania + Румыния + + + France (Reunion Island) + http://translate.google.com/#en|ru|France%20%28Reunion%20Island%29 + Франция (остров Реюньон) + + + Sweden + Швеция + + + Slovakia + Словакия + + + Singapore + Сингапур + + + Slovenia + Словения + + + Taiwan + Тайвань + + + Turkey + Турция + + + Thailand + Таиланд + + + USA + http://translate.google.com/#en|ru|USA + США + + + Ukraine + Украина + + + South Africa + Южная Африка + + + Saudi Arabia + Саудовская Аравия + + + + HeadlessLoader + + Information + Информация + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Чтобы управлять qBittorrent откройте браузер по адресу http://localhost:%1 + + + The Web UI administrator user name is: %1 + Администратор Web интерфейса: %1 + + + The Web UI administrator password is still the default one: %1 + Пароль администратора Web интерфейса все еще пароль по умолчанию: %1 + + + This is a security risk, please consider changing your password from program preferences. + Риск безопасности, пожалуйста, смените ваш пароль в настройках программы. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + Ваш IP адрес был заблокирован после слишком многих недачных попыток аутентификации. + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Скач: %1/с - Перед: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Отдача: %1/с - Перед: %2 + + + + HttpServer + + File + Файл + + + Edit + Изменить + + + Help + Помощь + + + Delete from HD + Удалить с жесткого диска + + + Download Torrents from their URL or Magnet link + Скачативать торренты с их URL и Magnet ссылок + + + Only one link per line + Толко одна ссылка в строке + + + Download + Скачать + + + Download local torrent + Скачать локальный торрент + + + Torrent files were correctly added to download list. + Торренты были добавлены в список скачивания. + + + Point to torrent file + Укажите торрент файл + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Вы уверены что хотите удалить выделенные торренты из списка и с жесткого диска? + + + Download rate limit must be greater than 0 or disabled. + Ограничение соотношения скачивания должно быть больше 0 или отключено. + + + Upload rate limit must be greater than 0 or disabled. + Ограничение соотношения раздачи должно быть больше 0 или отключено. + + + Maximum number of connections limit must be greater than 0 or disabled. + Максимальное число соединений должно быть больше 0 или отключено. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Максимальное число соединений на торрент должно быть больше 0 или отключено. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Максимальное число слотов раздачи на торрент должно быть больше 0 или отключено. + + + Unable to save program preferences, qBittorrent is probably unreachable. + Не возможно сохранить настройки, qBittorrent возможно недоступен. + + + Language + Язык + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Порт для входящих соединений должен быть больше чем 1024 и меньше 65535. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Порт для Web интерфейса должен быть больше 1024 и меньше 65535. + + + The Web UI username must be at least 3 characters long. + Имя пользователя Web интерфейса должно быть длинее 3 символов. + + + The Web UI password must be at least 3 characters long. + Пароль Web интерфейса должен быть длинее 3 символов. + + + Downloaded + Is the file downloaded or not? + Скачано + + + Save + Сохранить + + + qBittorrent client is not reachable + клиент qBittorrent недоступен + + + HTTP Server + HTTP сервер + + + Torrent path + Путь торрента + + + Torrent name + Имя торрента + + + The following parameters are supported: + Поддерживаются следующие параметры: + + + + LegalNotice + + Legal Notice + Официальное уведомление + + + Legal notice + Официальное уведомление + + + Cancel + Отмена + + + I Agree + Я согласен + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent - программа для обмена файлами. Когда вы запускаете торрент, данные становятся доступными другим участникам обмена для отдачи. Конечно, любые данные которые вы отдаете на обмен только ваша ответственность. + +Больше это уведомление не будет показано. + + + Press %1 key to accept and continue... + Нажмите %1 чтобы принять и продолжить... + + + + LineEdit + + Clear the text + Очистить текст + + + + MainWindow + + &Edit + &Изменить + + + &File + &Файл + + + &Help + &Помощь + + + Preview file + Имхо правильнее чем файл предпросмотра + Предпросмотр файла + + + Clear log + Очистить лог + + + Decrease priority + Понизить приоритет + + + Increase priority + Повысить приоритет + + + &Tools + Инс&трументы + + + &View + &Вид + + + &Add File... + &Добавить файл... + + + E&xit + В&ыход + + + &Options... + &Настройки... + + + Add &URL... + Добавить &URL... + + + Torrent &creator + Создатель такой создатель... Но ничего лучше придумать не могу, в голову приходят только 'создавалка' и 'создавайка' (создавайка мне торрент! ^_^) + Мастер &создания Torrent-а + + + Set upload limit... + Установить ограничение раздачи... + + + Set download limit... + Исходя из следущего + Установить ограничение закачки... + + + Set global download limit... + Установить глобальное ограничение закачки... + + + Set global upload limit... + Установить глобальное ограничение раздачи... + + + &Log viewer... + &Просмотрщик лога... + + + Top &tool bar + Ну не понятно лично мне что это за панель... А тулбар - с детства знакомо. + Панель &инструментов + + + Display top tool bar + Показать верхнюю панель + + + &Speed in title bar + &Скорость в заголовке + + + Show transfer speed in title bar + Имхо 'заголовок окна' понятнее чем 'полоса заголовка'. Хотя она ещё и в кнопке на панели задач отображается... + Отображать текущую скорость в заголовке окна + + + Alternative speed limits + Альтернативные лимиты скорости + + + &About + Посмотрел в Firefox - там не обезличенное 'О программе' а более тёплое 'О Mozilla Firefox'. Или может лучше как в Kate - 'О программе Kate'? + &О qBittorrent + + + &Pause + &Приостановить + + + &Delete + &Удалить + + + P&ause All + П&риостановить Все + + + Visit &Website + Посетить &веб-сайт + + + Report a &bug + Сообщить о&б ошибке + + + &Documentation + &Документация + + + &RSS reader + Корявенько... Но имхо 'просмотрщик' - это viewer // читалка как-то криво тоже. но лучше не придумал пока + &RSS читалка + + + Search &engine + Исходя из следущего (хотя я лично целиком и полностью за 'Поисковый движок') + По&исковик + + + Log viewer + Просмотрщик лога + + + Lock qBittorrent + Заблокировать qBittorrent + + + Ctrl+L + + + + Shutdown computer when downloads complete + Выключить компьютер когда закачки будут завершены + + + &Resume + &Возобновить + + + R&esume All + Воз&обновить все + + + Shutdown qBittorrent when downloads complete + Выключить qBittorrent когда загрузки будут завершены + + + Exit + Выход + + + Import torrent... + Импортировать торрент... + + + Donate money + so silly + Пожертвовать деньги + + + If you like qBittorrent, please donate! + Если вам нравится qBittorrent, пожалуйста - пожертвуйте! + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + Установить пароль... + + + Transfers + Передачи + + + Torrent file association + Привязки торрент-файлов + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent сейчас не является приложением по умолчанию для открытия торрент-файлов или Magnet-ссылок. +Хотите ли вы открывать торрент-файлы и Magnet-ссылки с помощью qBittorrent? + + + UI lock password + Пароль блокировки интерфейса + + + Please type the UI lock password: + Пожалуйста, введите пароль блокировки интерфейса: + + + Password update + Обновить пароль + + + The UI lock password has been successfully updated + Пароль блокировки интерфейса был успешно обновлен + + + RSS + RSS + + + Search + Поиск + + + Transfers (%1) + Передачи (%1) + + + Download completion + Завершение загрузок + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + скачивание %1 завершено. + + + I/O Error + i.e: Input/Output Error + Ошибка ввода/вывода + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Произошла ошибка ввода/вывода для торрента %1. +Причина: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Подтверждение рекурсивной загрузки + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Торрент %1 содержит торрент-файлы, хотите ли вы приступить к их загрузке? + + + Yes + Да + + + No + Нет + + + Never + Никогда + + + Url download error + Ошибка при скачивании URL + + + Couldn't download file at url: %1, reason: %2. + Невозможно скачать файл по URL: %1, причина: %2. + + + Global Upload Speed Limit + Глобальное ограничение скорости раздачи + + + Global Download Speed Limit + Глобальное ограничение скорости закачки + + + Invalid password + Неверный пароль + + + The password is invalid + Этот пароль не верен + + + Exiting qBittorrent + Завершение работы qBittorrent + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Есть активные торренты. Вы уверены что хотите выйти из qBittorrent? + + + Always + Всегда + + + Open Torrent Files + Открыть файлы Torrent + + + Torrent Files + Файлы Torrent + + + Options were saved successfully. + Настройки были успешно сохранены. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Скач.: %1 КиБ/с + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Отдача.: %1 КиБ/с + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Скач: %2/с, Отд: %3/с) + + + A newer version is available + Доступна новая версия + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Новая версия qBittorrent доступна на Sourceforge. +Хотите обновить qBittorrent до версии %1? + + + Impossible to update qBittorrent + Невозможно обновить qBittorrent + + + qBittorrent failed to update, reason: %1 + qBitttorrent не может быть обновлен. Причина: %1 + + + &Add torrent file... + &Добавить торрент файл... + + + Add &link to torrent... + Добавит &ссылку к торренту... + + + Import existing torrent... + Импортировать существующий торрент... + + + Execution &Log + &Лог выполнения + + + Execution Log + Лог выполнения + + + Auto-Shutdown on downloads completion + Выключение по завершении загрузок + + + Exit qBittorrent + Выйти из qBittorrent + + + Suspend system + Перейти в спящий режим + + + Shutdown system + Выключить компьютер + + + Disabled + Выключено + + + The password should contain at least 3 characters + Пароль должен содержать минимум 3 символа + + + + PeerAdditionDlg + + Invalid IP + Неверный IP + + + The IP you provided is invalid. + IP который вы указали неправилен. + + + + PeerListDelegate + + /s + /second (i.e. per second) + + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + Клиент + + + Progress + i.e: % downloaded + Прогресс + + + Down Speed + i.e: Download speed + Скорость скачивания + + + Up Speed + i.e: Upload speed + Скорость отдачи + + + Downloaded + i.e: total data downloaded + Скачано + + + Uploaded + i.e: total data uploaded + Отдано + + + Ban peer permanently + Заблокировать пир навсегда + + + Peer addition + Добавление пира + + + The peer was added to this torrent. + Пир был добавлен к этому torrent. + + + The peer could not be added to this torrent. + Пир не может быть добавлен к этому torrent. + + + Are you sure? -- qBittorrent + Вы уверены? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + Вы уверены что хотите навсегда заблокировать выделенные пиры? + + + &Yes + &Да + + + &No + &Нет + + + Manually banning peer %1... + Заблокировать пир %1 вручную... + + + Upload rate limiting + Ограничение соотношения отдачи + + + Download rate limiting + Ограничение соотношения скачивания + + + Add a new peer... + Исходя из предыдущего. Хотя мне больше нравится 'Добавить пира', пиры - они ведь живые... + Добавить новый пир... + + + Limit download rate... + Хоть в предыдущем и 'сотношение скачивания', но мимо _этого_ я пройти просто не могу! Ratio - соотношение, Rate - скорость! + Ограничение скорости скачивания... + + + Limit upload rate... + Хоть в предыдущем и 'сотношение раздачи', но мимо _этого_ я пройти просто не могу! Ratio - соотношение, Rate - скорость! + Ограничение скорости раздачи... + + + Copy IP + Копировать IP + + + Connection + Соединение + + + + Preferences + + UI + User Interface + Интерфейс + + + Downloads + Имхо 'закачка' - это upload + Загрузки + + + Connection + Соединение + + + Bittorrent + Bittorrent + + + Proxy + Прокси + + + Web UI + Web интерфейс + + + Language: + Язык: + + + (Requires restart) + (Требует перезагрузки) + + + Visual style: + Визуальный стиль: + + + Transfer list + Список передач + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Использовать альтернативные цвета строк + + + File system + Файловая система + + + Torrent queueing + Очереди Torrent + + + Maximum active downloads: + Максимальное число активных закачек: + + + Maximum active uploads: + Максимальное число активных раздач: + + + Maximum active torrents: + Максимальное число активных torrent: + + + When adding a torrent + При добавлении торента + + + Display torrent content and some options + Отображать содержимое torrentа и некоторые настройки + + + Listening port + Прослушивание порта + + + Port used for incoming connections: + Порт, используемый для входящих соединений: + + + Random + Случайно + + + Enable UPnP port mapping + Включить распределение портов UPnP + + + Enable NAT-PMP port mapping + Включить распределение портов NAT-PMP + + + Connections limit + Ограничение соединений + + + Global maximum number of connections: + Общее ограничение на число соединений: + + + Maximum number of connections per torrent: + Максимальное число соединений на torrent: + + + Maximum number of upload slots per torrent: + Максимальное количество слотов отдачи на torrent: + + + Upload: + Отдача: + + + Download: + Загрузка: + + + KiB/s + КиБ/с + + + Bittorrent features + Возможности Bittorrent + + + Enable DHT network (decentralized) + Включить DHT сеть (децентрализованную) + + + Use a different port for DHT and Bittorrent + Использовать разные порты для DHT и Bittorrent + + + DHT port: + Порт DHT: + + + Enable Peer Exchange / PeX (requires restart) + Включить Обмен пирами / (PeX) (требует перезагрузки) + + + Enable Local Peer Discovery + Включить обнаружение локальных пиров + + + Enabled + Включено + + + Forced + Принудительно + + + Disabled + Выключено + + + Type: + Тип: + + + (None) + (нет) + + + HTTP + HTTP + + + Port: + Порт: + + + Authentication + Аутентификация + + + Username: + Имя пользователя: + + + Password: + Пароль: + + + SOCKS5 + Сервер SOCKS5 + + + HTTP Server + HTTP сервер + + + Filter path (.dat, .p2p, .p2b): + Путь к фильтрам (.dat, .p2p, .p2b): + + + HTTP Communications (trackers, Web seeds, search engine) + Ну не звучит тут 'Связи'. Никак не звучит. + HTTP соединения (трекеры, раздающие Web, поисковые движки) + + + Host: + Хост: + + + Peer Communications + Связи с пирами + + + SOCKS4 + Сервер SOCKS4 + + + Speed + Скорость + + + Global speed limits + Глобальные лимиты скорости + + + Alternative global speed limits + Альтернативные лимиты скорости + + + to + time1 to time2 + до + + + Every day + Каждый день + + + Week days + Каждый будний день + + + Week ends + Каждый выходной + + + Advanced + Никак не звучит тут 'расширенные'... + Продвинутые + + + Copy .torrent files to: + Скопировать торрент файл в: + + + Remove folder + Удалить папку + + + No action + Нет действия + + + Options + Как в Firefox + Настройки + + + Visual Appearance + Визуальное Поведение + + + Action on double-click + Действие по двойному щелчку + + + Downloading torrents: + Или они 'Загружающиеся'? Или (как в предыдущем) 'Скачиваемые'? // думаю стоит привести download upload к загрузки раздачи а скачивание к самим торентфайликам + Загружаемые торренты: + + + Start / Stop + Начать/Остановить + + + Open destination folder + Открыть папку назначения + + + Completed torrents: + Завершенные торренты: + + + Desktop + Где? o_O // у тех кто с венды пришел и без него жить не могут :D + Рабочий стол + + + Show splash screen on start up + Показать заставку при загрузке + + + Start qBittorrent minimized + Запускать qBittorrent свернутым + + + Show qBittorrent icon in notification area + А может лучше 'в трее'? + Показывать значок qBittorrent в области уведомлений + + + Minimize qBittorrent to notification area + А может лучше 'в трей'? // не думаю, в том же KDE это именно уведомлений. А трей суть калька + Сворачивать qBittorrent в область уведомлений + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Коряво, коряво... + Закрывать qBittorrent в облать уведомлений + + + Do not start the download automatically + The torrent will be added to download list in pause state + Не начинать загрузку автоматически + + + Save files to location: + А надо ли 'расположение'? И имхо 'по умолчанию' здесь будет очень к месту. + Сохранять файлы по умолчанию в: + + + Append the label of the torrent to the save path + Добавить метку торрента к пути сохранения + + + Pre-allocate disk space for all files + Или 'Предварительно резервировать' будет правильнее? + Предварительно зарезервировать место для всех файлов + + + Keep incomplete torrents in: + Хранить незавершенные торренты в: + + + Append .!qB extension to incomplete files' names + Добавить расширение .!qB к незаконченым файлам + + + Automatically add torrents from: + Автоматически добавлять торренты из: + + + Add folder... + Добавить папку... + + + IP Filtering + Фильтрация по IP + + + Schedule the use of alternative speed limits + Или 'для использования'? + Расписание использования альтернативных лимитов скорости + + + from + from (time1 to time2) + С + + + When: + Когда: + + + Look for peers on your local network + Искать пиры в вашей локальной сети + + + Protocol encryption: + Или 'Протокол шифрования'? + Шифрование протокола: + + + Enable Web User Interface (Remote control) + Включить Web интерфейс (Удалённое управление) + + + Share ratio limiting + Ограничение коэффициента раздачи + + + Seed torrents until their ratio reaches + Или тут лучше 'соотношение'? Или 'рейтинг'? + Раздавать торренты пока их соотношение загрузка/раздача не достигнет + + + then + Имхо так красивее звучит... + а затем + + + Pause them + Приостановить их + + + Remove them + Удалить их + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Обмен пирами с совместиыми клиентами Bittorrent (µTorrent, Vuze, ...) + + + Email notification upon download completion + Сообщать об окончании загрузки по Email + + + Destination email: + Email для сообщения: + + + SMTP server: + SMTP сервер: + + + Run an external program on torrent completion + Запустить внешнюю программу по окончании загрузки торрента + + + Use %f to pass the torrent path in parameters + Использовать %f для передачи пути к торренту в параметрах + + + Proxy server + Прокси сервер + + + BitTorrent + BitTorrent + + + Start / Stop Torrent + Запустить / Остановить Торрент + + + Use UPnP / NAT-PMP port forwarding from my router + Использовать UPnP / NAT-PMP из моего роутера + + + Privacy + Приватность + + + Enable DHT (decentralized network) to find more peers + Включить DHT сеть (децентрализованную), чтобы найти больше пиров + + + Use a different port for DHT and BitTorrent + Использовать разные порты для DHT и Bittorrent + + + Enable Peer Exchange (PeX) to find more peers + Включить Обмен пирами (PeX), чтобы найти больше пиров + + + Enable Local Peer Discovery to find more peers + Включить обнаружение локальных пиров, чтобы найти больше пиров + + + Encryption mode: + Режим шифрования: + + + Prefer encryption + Предпочитать шифрование + + + Require encryption + Требовать шифрование + + + Disable encryption + Отключить шифрование + + + User Interface + Пользовательский интерфейс + + + Reload the filter + Перезагрузить фильтр + + + Prevent system from suspend + Предотвращать переход в спящий режим + + + Behavior + Поведение + + + Language + Язык + + + Power Management + Управление питанием + + + Inhibit system sleep when torrents are active + Запретить спящий режим, когда есть активные торренты + + + Bypass authentication for localhost + Пропускать аутентификацию для localhost + + + Ask for program exit confirmation + Запрашивать подтверждение завершения программы + + + Use monochrome system tray icon (requires restart) + Использовать монохромную иконку в трее (требуется перезапуск) + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Поддерживаются следующие параметры: +<ul> +<li>%f: Путь торрента</li> +<li>%n: Имя торрента</li> +</ul> + + + Tray icon style: + Стиль иконки в трее: + + + Normal + Обычная + + + Monochrome (Dark theme) + Монохромная (Тёмная тема) + + + Monochrome (Light theme) + Монохромная (Светлая тема) + + + This server requires a secure connection (SSL) + Этот сервер требует защищённое соединение (SSL) + + + User Interface Language: + Язык пользовательского интерфейса: + + + Transfer List + Список передач + + + Show qBittorrent in notification area + Показывать qBittorrent в области уведомлений + + + Hard Disk + Жёсткий диск + + + Listening Port + Прослушиваемый порт + + + Connections Limits + Ограничения соединений + + + Proxy Server + Прокси сервер + + + Global Speed Limits + Глобальные ограничения скорости + + + Alternative Global Speed Limits + Альтернативные ограничения скорости + + + Torrent Queueing + Очерёдность торрентов + + + Share Ratio Limiting + Ограничение коэффициента раздачи + + + Use UPnP / NAT-PMP to forward the port from my router + Использовать UPnP / NAT-PMP для перенаправления порта через мой маршрутизатор + + + Update my dynamic domain name + Обновлять моё динамическое доменное имя + + + Service: + Служба: + + + Register + Регистрация + + + Domain name: + Доменное имя: + + + Global Rate Limits + Глобальные ограничения скорости + + + Apply rate limit to uTP connections + Применять ограничение скорости к uTP соединениям + + + Apply rate limit to transport overhead + Применять ограничение скорости к накладным расходам передачи + + + Alternative Global Rate Limits + Альтернативные ограничения скорости + + + Schedule the use of alternative rate limits + Запланировать использование альтернативных ограничений скорости + + + Enable bandwidth management (uTP) + Включить управление полосой пропускания (uTP) + + + Otherwise, the proxy server is only used for tracker connections + Иначе прокси сервер используется только для соединения с трекерами + + + Use proxy for peer connections + Использовать прокси для соединения с пирами + + + Append .!qB extension to incomplete files + Добавить расширение .!qB к незаконченным файлам + + + Use HTTPS instead of HTTP + Использовать HTTPS вместо HTTP + + + Import SSL Certificate + Импортировать сертификат SSL + + + Import SSL Key + Импортировать ключ SSL + + + Certificate: + Сертификат: + + + Key: + Ключ: + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Информация о сертификатах</a> + + + + PreviewSelect + + Name + Имя + + + Size + Размер + + + Progress + Прогресс + + + Preview impossible + Предпросмотр невозможен + + + Sorry, we can't preview this file + Извините, предпросмотр этого файла невозможен + + + + ProgramUpdater + + Could not create the file %1 + Невозможно создать файл %1 + + + Failed to download the update at %1 + %1 is an URL + Не удалось скачать обновление с %1 + + + + PropListDelegate + + Normal + Normal (priority) + Обычный + + + High + High (priority) + Высокий + + + Maximum + Maximum (priority) + Максимальный + + + Not downloaded + Не загружать + + + Mixed + Mixed (priorities + Смешанные + + + + PropTabBar + + General + Общие + + + Trackers + Трэкеры + + + Peers + Пиры + + + URL Seeds + URL раздающих + + + Files + Файлы + + + HTTP Sources + Источники HTTP + + + Content + Содержание + + + + PropertiesWidget + + Save path: + Путь сохранения: + + + Torrent hash: + Хэш torrentа: + + + Comment: + Комментарий: + + + Share ratio: + Соотношение раздачи: + + + General + Общие + + + Trackers + Трэкеры + + + URL seeds + URL раздающих + + + Files + Файлы + + + Priority + Приоритет + + + New url seed + New HTTP source + Новый URL раздачи + + + New url seed: + URL нового раздающего: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + Этот URL раздающего уже в списке. + + + Choose save path + Выберите путь сохранения + + + Save path creation error + Ошибка создания пути сохранения + + + Could not create the save path + Невозможно создать путь сохранения + + + Downloaded: + Скачано: + + + Transfer + Передано + + + Uploaded: + Отдано: + + + Wasted: + Потрачено: + + + UP limit: + Отд. огр: + + + DL limit: + Загр. огр: + + + Time elapsed: + Времени прошло: + + + Connections: + Соединения: + + + Information + Информация + + + Created on: + Создан на: + + + Peers + Пиры + + + Normal + Обычный + + + Maximum + Максимальный + + + High + Высокий + + + this session + эта сессия + + + %1 max + e.g. 10 max + %1 макс + + + Availability: + Доступность: + + + /s + /second (i.e. per second) + + + + Seeded for %1 + e.g. Seeded for 3m10s + Раздается %1 + + + Rename... + Переименовать... + + + New name: + Новое имя: + + + The file could not be renamed + Файл не может быть переименован + + + This name is already in use in this folder. Please use a different name. + Файл с таким именем уже существует в этой папке. Используйте другое имя. + + + The folder could not be renamed + Папка не может быть переименована + + + Rename the file + Переименовать файл + + + This file name contains forbidden characters, please choose a different one. + Имя файла содержит недопустимые символы. Пожалуйста, выберите другое. + + + I/O Error + Ошибка ввода/вывода + + + This file does not exist yet. + Этот файл пока не существует. + + + This folder does not exist yet. + Эта папка пока не существует. + + + Reannounce in: + Переанонсировать через: + + + Select All + Выбрать все + + + Select None + Выбрать ничего + + + Do not download + Не загружать + + + Pieces size: + Размер кусочков: + + + Time active: + Time (duration) the torrent is active (not paused) + Время активности: + + + Torrent content: + Содержимое торрента: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1 достиг установленного вами максимального соотношения. + + + Removing torrent %1... + Удаление торрента %1... + + + Pausing torrent %1... + Приостановка торрента %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent привязан к порту: TCP/%1 + + + UPnP support [ON] + Поддержка UPnP [Вкл] + + + UPnP support [OFF] + Поддержка UPnP [Выкл] + + + NAT-PMP support [ON] + Поддержка NAT-PMP [Вкл] + + + NAT-PMP support [OFF] + Поддержка NAT-PMP [Выкл] + + + HTTP user agent is %1 + Браузер %1 + + + Using a disk cache size of %1 MiB + Используется дисковый кеш размером %1 МиБ + + + DHT support [ON], port: UDP/%1 + Поддержка DHT [Вкл.], порт: UDP/%1 + + + DHT support [OFF] + Поддержка DHT [Выкл] + + + PeX support [ON] + Поддержка PeX [Вкл] + + + PeX support [OFF] + Поддержка PeX [Выкл] + + + Restart is required to toggle PeX support + Необходимо перезапустить qBittorrent для включения настройки PeX + + + Local Peer Discovery [ON] + Обнаружение локальных пиров [Вкл] + + + Local Peer Discovery support [OFF] + Обнаружение локальных пиров [Выкл] + + + Encryption support [ON] + Поддержка шифрования [Вкл] + + + Encryption support [FORCED] + Поддержка шифрования [Принудительно] + + + Encryption support [OFF] + Поддержка шифрования [Выкл] + + + Embedded Tracker [ON] + Встроенный трекер [Вкл] + + + Failed to start the embedded tracker! + Не удалось запустить встроенный трекер! + + + Embedded Tracker [OFF] + Встроенный трекер [Выкл] + + + The Web UI is listening on port %1 + Web интерфейс прослушивает порт %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Ошибка Web интерфейса - Не могу привязаться к порту %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' был удален из списка передач и с жесткого диска. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' был удален из списка передач. + + + '%1' is not a valid magnet URI. + '%1' не является magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' уже присутствует в списке закачек. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + %1 возобновлен. (быстрое возобновление) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' добавлен в список закачек. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Не удалось декодировать torrent файл: '%1' + + + This file is either corrupted or this isn't a torrent. + Этот файл либо поврежден, либо это не торрент-файл. + + + Error: The torrent %1 does not contain any file. + Ошибка: Торрент %1 не содержит никаких файлов. + + + Note: new trackers were added to the existing torrent. + Примечание: новые трекеры были добавлены к существующему торренту. + + + Note: new URL seeds were added to the existing torrent. + Примечание: новые URL сидов были добавлены к существующему торренту. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>был заблокирован в соответствии с вашим IP фильтром</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>был заблокирован из-за поврежденных кусочков</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Рекурсивная загрузка файла %1 встроенна в торрент %2 + + + Unable to decode %1 torrent file. + Не удалось декодировать %1 torrent файл. + + + Torrent name: %1 + Имя торрента: %1 + + + Torrent size: %1 + Размер торрента: %1 + + + Save path: %1 + Путь для сохранения: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Торрент был скачен за %1. + + + Thank you for using qBittorrent. + Спасибо за использование qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] скачивание %1 завершено + + + An I/O error occured, '%1' paused. + Ошибка Ввода/Вывода: '%1' приостановлен. + + + Reason: %1 + Причина: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + Распределение портов UPnP/NAT-PMP не удалось с сообщением: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + Распределение портов UPnP/NAT-PMP прошло успешно: %1 + + + File sizes mismatch for torrent %1, pausing it. + Несовпадение размеров файлов для торрента %1, приостанавливаю его. + + + Fast resume data was rejected for torrent %1, checking again... + Быстрое восстановление данных для torrentа %1 было невозможно, проверка заново... + + + Url seed lookup failed for url: %1, message: %2 + Поиск раздающего Url не удался: %1, сообщение: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Скачивание '%1', подождите... + + + The network interface defined is invalid: %1 + Указанный сетевой интерфейс ошибочен: %1 + + + Trying any other network interface available instead. + Пробуем другой достпуный сетевой интерфейс. + + + Listening on IP address %1 on network interface %2... + Слушаем на IP адресе %1 на сетевом интерфейсе %2... + + + Failed to listen on network interface %1 + Не возможно слушать сетевой интерфейс %1 + + + UPnP / NAT-PMP support [ON] + Поддержка UPnP / NAT-PMP [Вкл] + + + UPnP / NAT-PMP support [OFF] + Поддержка UPnP / NAT-PMP [Выкл] + + + Local Peer Discovery support [ON] + Обнаружение локальных пиров [Вкл] + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Успешно прочитан фильтр IP: %1 правил применено. + + + Error: Failed to parse the provided IP filter. + Ошибка: Не возможно разобрать фильтр IP. + + + Reporting IP address %1 to trackers... + Сообщаю IP адрес %1 трекерам... + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Сейчас компьютер перейдёт в спящий режим, если вы не отмените это в течение следующих 15 секунд... + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Сейчас компьютер будет отключён, если вы не отмените это в течение следующих 15 секунд... + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + Сейчас qBittorrent будет завершен, если вы не отмените это в течение следующих 15 секунд... + + + + RSS + + Search + Поиск + + + Delete + Удалить + + + Rename + Переименовать + + + Refresh RSS streams + Обновить RSS потоки + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Торренты:</span> <span style=" font-style:italic;">(дважды щелкните для загрузки)</span></p></body></html> + + + Download torrent + Скачать торрент + + + Open news URL + Открыть новый URL + + + Copy feed URL + Скопировать URL канала + + + New subscription + Новая подписка + + + Mark items read + Отметить элементы как прочитанные + + + Update all + Обновить все + + + Update all feeds + Обновить все каналы + + + RSS feeds + RSS каналы + + + Update + Обновить + + + Feed URL + URL канала + + + Article title + Заголовок статьи + + + Rename... + Переименовать... + + + New subscription... + Новая подписка... + + + RSS feed downloader... + Загрузка RSS канала... + + + New folder... + Новая папка... + + + Manage cookies... + Или 'Управлять'? + Управление cookies... + + + Settings... + Настройки... + + + RSS Downloader... + Загрузчик RSS... + + + + RSSImp + + Please type a rss stream url + Введите URL RSS потока + + + Stream URL: + URL потока: + + + Are you sure? -- qBittorrent + Вы уверены? -- qBittorrent + + + &Yes + &Да + + + &No + &Нет + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + Этот RSS канал уже в списке. + + + Date: + Дата: + + + Author: + Автор: + + + Please choose a folder name + Выберите имя папки + + + Folder name: + Имя папки: + + + New folder + Новая папка + + + Are you sure you want to delete these elements from the list? + Вы уверены что хотите удалить эти элементы из списка? + + + Are you sure you want to delete this element from the list? + Вы уверены что хотите удалить этот элемент из списка? + + + Please choose a new name for this RSS feed + Укажите новое имя для этого RSS канала + + + New feed name: + Новое имя канала: + + + Name already in use + Имя уже используется + + + This name is already used by another item, please choose another one. + Это имя уже используется. Выберите другое. + + + Overwrite attempt + Подтверждение перезаписи + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Вы не можете перезаписать %1. + + + Unread + Не прочитано + + + + RssArticle + + No description available + Описание недоступно + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + Автоматически загрузить %1 торрент с %2 RSS канала... + + + + RssItem + + No description available + Описание недоступно + + + + RssSettings + + RSS Reader Settings + И опять читалка... + Настройки читалки RSS + + + RSS feeds refresh interval: + Интервал обновления RSS каналов: + + + minutes + минут + + + Maximum number of articles per feed: + Максимальное число статей на канал: + + + + RssSettingsDlg + + RSS Reader Settings + Настройки читалки RSS + + + RSS feeds refresh interval: + Интервал обновления RSS каналов: + + + minutes + минут + + + Maximum number of articles per feed: + Максимальное число статей на канал: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Автоматически загрузить %1 торрент с %2 RSS канала... + + + + ScanFoldersModel + + Watched Folder + Отслеживаемые папки + + + Download here + Скачивать сюда + + + + SearchCategories + + All categories + Все категории + + + Movies + Фильмы + + + TV shows + ТВ-шоу + + + Music + Музыка + + + Games + Игры + + + Anime + Аниме + + + Software + Программы + + + Pictures + Изображения + + + Books + Книги + + + + SearchEngine + + Empty search pattern + Очистить шаблон поиска + + + Please type a search pattern first + Пожалуйста, наберите сначала шаблон поиска + + + Results + Результаты + + + Searching... + Поиск... + + + Cut + Вырезать + + + Copy + Копировать + + + Paste + Вставить + + + Clear field + Очистить поле + + + Clear completion history + Очистить историю + + + Search Engine + Поисковый движок + + + Search has finished + Поиск завершен + + + An error occured during search... + Во время поиска произошла ошибка... + + + Search aborted + Поиск прерван + + + Search returned no results + Поиск не дал результатов + + + Results + i.e: Search results + Результаты + + + Unknown + Неизвестно + + + Search + Поиск + + + Download error + Ошибка при скачивании + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + А вот нефиг ставить вручную! Ставить надо из репозитория. Думаю тут лучше будет 'самостоятельно'... + Установщик Python не может быть загружен по причине: %1. +Пожалуйста, установите его вручную. + + + Missing Python Interpreter + Отсутствует интерпретатор Python + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x требуется для использования поисковиков, но не похоже что он установлен. +Хотите ли Вы установить его сечас? + + + Confirmation + Подтверждение + + + Are you sure you want to clear the history? + Или 'журнал'? + Вы уверены, что хотите очистить историю? + + + + SearchTab + + Name + i.e: file name + Имя + + + Size + i.e: file size + Размер + + + Seeders + i.e: Number of full sources + Раздающие + + + Leechers + i.e: Number of partial sources + Скачивающие + + + Search engine + Поисковый движок + + + + ShutdownConfirmDlg + + Shutdown confirmation + Подтверждение выключения + + + + SpeedLimitDialog + + KiB/s + КиБ/с + + + + StatusBar + + Connection status: + Состояние связи: + + + No direct connections. This may indicate network configuration problems. + Нет прямых соединений. Причиной этого могут быть проблемы в настройке сети. + + + DHT: %1 nodes + DHT: %1 узлов + + + Connection Status: + Состояние связи: + + + Online + В сети + + + Global Download Speed Limit + Глобальное ограничение скорости закачки + + + Global Upload Speed Limit + Глобальное ограничение скорости раздачи + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Скач: %1/с - Перед: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Отдача: %1/с - Перед: %2 + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + Скач: %1Б/с - Перед: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + Отдача: %1Б/с - Перед: %2 + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Отключен. Обычно это означает, что qBittorrent не может прослушивать выбранный порт для входящих соединений. + + + Click to disable alternative speed limits + Нажмите для отключения альтернативных лимитов скорости + + + Click to enable alternative speed limits + Нажмите для включения альтернативных лимитов скорости + + + qBittorrent needs to be restarted + qBittorrent надо перезапустить + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent был обновлен и нуждается в перезапуске, чтобы изменение вступили в силу. + + + Click to switch to alternative speed limits + Нажмите для переключения к альтернативным лимитам скорости + + + Click to switch to regular speed limits + Нажмите для переключения к обычным лимитам скорости + + + %1/s + Per second + %1/с + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + Выберите папку для добавления в torrent + + + Select a file to add to the torrent + Выберите файл для добавления в torrent + + + Please type an announce URL + Введите ссылку анонсирования + + + Announce URL: + Tracker URL + Анонсирующий URL: + + + Please type a web seed url + Введите URL веб раздачи + + + Web seed URL: + URL веб раздачи: + + + No input path set + Не установлен входной путь + + + Please type an input path first + Пожалуйста, сначала введите путь источника + + + Select destination torrent file + Выберите torrent файл назначения + + + Torrent Files + Файлы Torrent + + + Torrent creation + Создание Torrent-а + + + Torrent creation was unsuccessful, reason: %1 + Создание torrent-а не завершено, причина: %1 + + + Created torrent file is invalid. It won't be added to download list. + Созданный torrent файл испорчен. Он не будет добавлен в список закачек. + + + Torrent was created successfully: + Torrent успешно создан: + + + + TorrentFilesModel + + Name + Имя + + + Size + Размер + + + Progress + Прогресс + + + Priority + Приоритет + + + + TorrentImportDlg + + Torrent Import + Импортировать торрент + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + dont understand phrase + Помошник поможет вам настроить раздачу торрента, который вы уже скачали. + + + Torrent file to import: + Имя файла торрента для импорта: + + + ... + ... + + + Content location: + Размещение содержимого: + + + Skip the data checking stage and start seeding immediately + Пропустить проверку данных и начать раздачу немедленно + + + Import + Импорт + + + Torrent file to import + Торрент файл для импорта + + + Torrent files (*.torrent) + Торрент файлы (*.torrent) + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 файлы + + + Please provide the location of %1 + %1 is a file name + Укажите размещение %1 + + + Please point to the location of the torrent: %1 + Укажите расположение торрент файла: %1 + + + Invalid torrent file + Неправильный торрент файл + + + This is not a valid torrent file. + Это не правильный торрент файл. + + + + TorrentModel + + Name + i.e: torrent name + Имя + + + Size + i.e: torrent size + Размер + + + Done + % Done + Завершено + + + Status + Torrent status (e.g. downloading, seeding, paused) + Статус + + + Seeds + i.e. full sources (often untranslated) + Источники + + + Peers + i.e. partial sources (often untranslated) + Пиры + + + Down Speed + i.e: Download speed + Скорость скач + + + Up Speed + i.e: Upload speed + Скорость отдачи + + + Ratio + Share ratio + Соотношение + + + ETA + i.e: Estimated Time of Arrival / Time left + Ост. времени + + + Label + Метка + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Добавлен + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Закончен + + + Tracker + Трэкер + + + Down Limit + i.e: Download limit + Лимит Загр + + + Up Limit + i.e: Upload limit + Лимит Отд + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Загружено + + + Amount left + Amount of data left to download (e.g. in MB) + Осталось + + + Time Active + Time (duration) the torrent is active (not paused) + Время активности + + + + TrackerList + + URL + Ссылка + + + Status + Статус + + + Peers + Пиры + + + Message + Сообщение + + + [DHT] + + + + [PeX] + + + + [LSD] + + + + Working + Работает + + + Disabled + Выключено + + + This torrent is private + Это приватный торрент + + + Updating... + Обновляется... + + + Not working + Не работает + + + Not contacted yet + Не соединился + + + Add a new tracker... + Добавить новый трекер... + + + Remove tracker + Удалить трекер + + + Force reannounce + Коряво >_< + Переанонсировать принудительно + + + + TrackersAdditionDlg + + Trackers addition dialog + Диалог добавления трекеров + + + List of trackers to add (one per line): + Список трекеров для добавления (один трекер на строку): + + + µTorrent compatible list URL: + URL списка совместимого с µTorrent: + + + I/O Error + Ошибка ввода/вывода + + + Error while trying to open the downloaded file. + Ошибка при открытии скачанного файла. + + + No change + Без изменений + + + No additional trackers were found. + Дополнительных трекеров не найдено. + + + Download error + Ошибка при скачивании + + + The trackers list could not be downloaded, reason: %1 + Список трекеров не может быть скачан. Причина: %1 + + + + TransferListDelegate + + Downloading + Скачивание + + + Paused + Пауза + + + Queued + i.e. torrent is queued + В очереди + + + Seeding + Torrent is complete and in upload-only mode + Раздача + + + Stalled + Torrent is waiting for download to begin + Простаивает + + + Checking + Torrent local data is being checked + Проверка + + + /s + /second (.i.e per second) + + + + KiB/s + KiB/second (.i.e per second) + КиБ/с + + + Seeded for %1 + e.g. Seeded for 3m10s + Раздается %1 + + + + TransferListFiltersWidget + + All + Все + + + Downloading + Скачивание + + + Completed + Завершено + + + Active + Активные + + + Inactive + Не активные + + + All labels + Все метки + + + Unlabeled + Без метки + + + Remove label + Удалить метку + + + New Label + Новая метка + + + Label: + Метка: + + + Invalid label name + Неправильное имя метки + + + Please don't use any special characters in the label name. + Пожалуйста, не используйте специальные символы в имени метки. + + + Paused + Пауза + + + Add label... + Добавить метку... + + + Resume torrents + Возобновить торренты + + + Pause torrents + Приостановить торренты + + + Delete torrents + Удалить торренты + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + Ост. времени + + + Column visibility + Отображение колонок + + + Open destination folder + Открыть папку назначения + + + Force recheck + Проверить принудительно + + + Copy magnet link + Скопировать ссылку magnet + + + Down Speed + i.e: Download speed + Скорость скач + + + Up Speed + i.e: Upload speed + Скорость отдачи + + + Name + i.e: torrent name + Имя + + + Size + i.e: torrent size + Размер + + + Done + % Done + Завершено + + + Status + Torrent status (e.g. downloading, seeding, paused) + Статус + + + Seeds + i.e. full sources (often untranslated) + Источники + + + Peers + i.e. partial sources (often untranslated) + Пиры + + + Ratio + Share ratio + Соотношение + + + Torrent Download Speed Limiting + Ограничение скорости скачивания торрента + + + Torrent Upload Speed Limiting + Ограничение скорости раздачи торрента + + + Super seeding mode + Режим супер раздачи + + + Download in sequential order + Скачивать последовательно + + + Download first and last piece first + Скачивать первый и последний кусок сначала + + + Label + Метка + + + New Label + Новая метка + + + Label: + Метка: + + + New... + New label... + Новая... + + + Reset + Reset label + Восстановить метку + + + Rename + Переименовать + + + New name: + Новое имя: + + + Rename... + Переименовать... + + + Invalid label name + Неправильное имя метки + + + Please don't use any special characters in the label name. + Пожалуйста, не используйте специальные символы в имени метки. + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Добавлен + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Закончен + + + Down Limit + i.e: Download limit + Лимит Загр + + + Up Limit + i.e: Upload limit + Лимит Отд + + + Choose save path + Выберите путь сохранения + + + Save path creation error + Ошибка создания пути сохранения + + + Could not create the save path + Невозможно создать путь сохранения + + + Set location... + Блин, до чего же коряво! Может лучше 'Переместить файлы'? + Установить размещение... + + + Preview file... + Предпросмотр файла... + + + Limit upload rate... + Ограничение скорости раздачи... + + + Limit download rate... + Ограничение скорости скачивания... + + + Move up + i.e. move up in the queue + Вверх + + + Move down + i.e. Move down in the queue + Вниз + + + Move to top + i.e. Move to top of the queue + На самый верх + + + Move to bottom + i.e. Move to bottom of the queue + На самый низ + + + Priority + Приоритет + + + Resume + Resume/start the torrent + Возобновить + + + Pause + Pause the torrent + Приостановить + + + Delete + Delete the torrent + Удалить + + + Tracker + Трэкер + + + Limit share ratio... + Ограничить коэффициент раздачи... + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + Ограничение коэффициента скачивания/раздачи торрента + + + Use global ratio limit + Использовать глобальное ограничение коэффициента + + + buttonGroup + Do you really need to translate it? + buttonGroup + + + Set no ratio limit + Убрать ограничение коэффициента + + + Set ratio limit to + Установить ограничение коэффициента + + + + UsageDisplay + + Usage: + Использование: + + + displays program version + показать версию программы + + + disable splash screen + показать заставку при загрузке + + + displays this help message + показать эту справку + + + changes the webui port (current: %1) + Изменить порт Web интерфейса (сейчас: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [файлы или ссылки]: скачать торренты указанные пользователем (опционально) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + Я хочу поблагодарить следующих людей, кто вызвался перевести qBittorrent: + + + Please contact me if you would like to translate qBittorrent into your own language. + Пожалуйста, свяжитесь со мной, если хотите перевести qBittorrent на свой язык. + + + + addPeerDialog + + Peer addition + Добавление пира + + + IP + IP + + + Port + Порт + + + + addTorrentDialog + + Torrent addition dialog + Окно добавления torrent-а + + + Save path: + Путь сохранения: + + + ... + ... + + + Torrent content: + Содержимое torrent-а: + + + Add to download list in paused state + Добавить в список закачек в приостановленном состоянии + + + Add + Добавить + + + Cancel + Отмена + + + Normal + Обычный + + + High + Высокий + + + Maximum + Максимальный + + + Torrent size: + Размер торрента: + + + Unknown + Неизвестно + + + Free disk space: + Свободное место на диске: + + + Download in sequential order (slower but good for previewing) + Загружать последовательно (медленнее но удобнее для предпросмотра) + + + Skip file checking and start seeding immediately + Пропустить проверку файла и начать раздачу немедленно + + + Label: + Метка: + + + Select All + Выбрать все + + + Select None + Выбрать ничего + + + Do not download + Не загружать + + + + authentication + + Tracker authentication + Аутентификация Трэкера + + + Tracker: + Трэкер: + + + Login + Логин + + + Username: + Имя пользователя: + + + Password: + Пароль: + + + Log in + Вход + + + Cancel + Отмена + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + Подтверждение удаления - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + Вы уверены что хотите удалить выделенные торренты из списка передач? + + + Remember choice + Запомнить выбор + + + Also delete the files on the hard disk + Также удалить файлы и с жесткого диска + + + + createTorrentDialog + + Cancel + Отмена + + + Torrent Creation Tool + Инструмент для создания Torrent-ов + + + Torrent file creation + Создание Torrent файла + + + Announce urls (trackers): + Аносирующие ссылки (трэкеров): + + + Comment (optional): + Комментарий (необязателен): + + + Web seeds urls (optional): + Ссылки на веб раздачи (необязательно): + + + File or folder to add to the torrent: + Файл или папка для добавления в torrent: + + + Piece size: + Размер кусочка: + + + 32 KiB + 32 КиБ + + + 64 KiB + 64 КиБ + + + 128 KiB + 128 КиБ + + + 256 KiB + 256 КиБ + + + 512 KiB + 512 КиБ + + + 1 MiB + 1 МиБ + + + 2 MiB + 2 МиБ + + + 4 MiB + 4 МиБ + + + Private (won't be distributed on DHT network if enabled) + Закрытый (не будет передаваться через безтрекерную сеть / DHT при включении) + + + Start seeding after creation + Начать раздавать после создания + + + Create and save... + Создать и сохранить... + + + Progress: + Прогресс: + + + Add file + Добавить файл + + + Add folder + Добавить папку + + + Tracker URLs: + URL-ы трекера: + + + Web seeds urls: + URL веб раздачи: + + + Comment: + Комментарий: + + + Auto + Авто + + + + createtorrent + + Select destination torrent file + Выберите torrent файл назначения + + + Torrent Files + Файлы Torrent + + + No input path set + Не установлен входной путь + + + Please type an input path first + Пожалуйста, сначала введите путь назначения + + + Torrent creation + Создание Torrent-а + + + Torrent was created successfully: + Torrent успешно создан: + + + Select a folder to add to the torrent + Выберите папку для добавления torrent-а + + + Please type an announce URL + Введите ссылку анонсирования + + + Torrent creation was unsuccessful, reason: %1 + Создание torrent-а не завершено, причина: %1 + + + Announce URL: + Tracker URL + Анонсирующий URL: + + + Please type a web seed url + Введите URL веб раздачи + + + Web seed URL: + URL веб раздачи: + + + Select a file to add to the torrent + Выберите файл для добавления в torrent + + + Created torrent file is invalid. It won't be added to download list. + Созданный torrent файл испорчен. Он не будет добавлен в список закачек. + + + + downloadFromURL + + Download Torrents from URLs + Скачать торрент из URL + + + Only one URL per line + Только один URL в строке + + + Download + Закачать + + + Cancel + Отмена + + + Download from urls + Загрузить Torrent(ы) из URL(s) + + + No URL entered + URL не введен + + + Please type at least one URL. + Пожалуйста введите минимум один URL. + + + Add torrent links + Добавить ссылки торрент + + + Both HTTP and Magnet links are supported + Поддреживаются HTTP и Magnet ссылки + + + + downloadThread + + I/O Error + Ошибка ввода/вывода + + + The remote host name was not found (invalid hostname) + Имя удалённого хоста не было найдено (неправильное имя хоста) + + + The operation was canceled + Операция была отменена + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Удаленный сервер преждевременно закрыл соединение, прежде чем весь ответ был принят и обработан + + + The connection to the remote server timed out + Время соединения с удаленным сервером вышло + + + SSL/TLS handshake failed + Соединение SSL/TLS не удалось + + + The remote server refused the connection + Удаленный сервер отклонил соединение + + + The connection to the proxy server was refused + Соединение с прокси-сервером отклонено + + + The proxy server closed the connection prematurely + Прокси-сервер преждевременно закрыл соединение + + + The proxy host name was not found + Имя прокси-сервера не было найдено + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Подключение к прокси-серверу истекло или прокси-сервер не ответил на запрос + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Прокси-сервер требует аутентификации, но не принял указанные учетные данные + + + The access to the remote content was denied (401) + В доступе к данным было отказано (401) + + + The operation requested on the remote content is not permitted + Запрошенная операция над данными запрещена + + + The remote content was not found at the server (404) + Данные не были найдены на сервере (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Удаленный сервер требует аутентификацию для отдачи данных, но указанные учетные данные не были приняты + + + The Network Access API cannot honor the request because the protocol is not known + API сетевого доступа не может выполнить запрос, потому что протокол не известен + + + The requested operation is invalid for this protocol + Запрошенная операция не поддерживается данным протоколом + + + An unknown network-related error was detected + Неизвестная сетевая ошибка + + + An unknown proxy-related error was detected + Неизвестная ошибка прокси-сервера + + + An unknown error related to the remote content was detected + Неизвестная ошибка данных + + + A breakdown in protocol was detected + Ошибка в протоколе + + + Unknown error + Неизвестная ошибка + + + + engineSelect + + Search plugins + Плагины поиска + + + Installed search engines: + Установленные плагины поиска: + + + Name + Имя + + + Url + Ссылка + + + Enabled + Включено + + + Install a new one + Установить новый + + + Check for updates + Проверить обновления + + + Close + Закрыть + + + Enable + Включить + + + Disable + Отключить + + + Uninstall + Удалить + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Вы можете получить новые плагины поиска здесь: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + engineSelectDlg + + Uninstall warning + Предупреждение об удалении + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Некоторые плагины не могут быть удалены, так как включены в qBittorrent. +Удалены могут быть лишь те, что вы установили сами. +Но все равно, эти плагины будут отключены. + + + Uninstall success + Удаление произведено + + + Select search plugins + Выбрать поисковые движки + + + qBittorrent search plugins + Плагин поиска qBittorrent + + + Search plugin install + Установка поискового плагина + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Самая последняя версия поискового движка %1 уже установлена. + + + Search plugin update + Обновление поисковых плагинов + + + Sorry, update server is temporarily unavailable. + Извините, сервер обновлений временно недоступен. + + + All your plugins are already up to date. + Все ваши плагины имеют последние версии. + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + Плагин поискового движка %1 не может быть обновлен, осталась старая версия. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Плагин поискового движка %1 не может быть установлен. + + + All selected plugins were uninstalled successfully + Все выбранные плагины были успешно удалены + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + Плагин поискового движка %1 был успешно обновлен. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Плагин поискового движка %1 был успешно установлен. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Извините, установка поискового плагина %1 не удалась. + + + New search engine plugin URL + URL нового плагина поискового движка + + + URL: + URL: + + + Yes + Да + + + No + Нет + + + + misc + + B + bytes + Б + + + KiB + kibibytes (1024 bytes) + КиБ + + + MiB + mebibytes (1024 kibibytes) + МиБ + + + GiB + gibibytes (1024 mibibytes) + ГиБ + + + TiB + tebibytes (1024 gibibytes) + ТиБ + + + Unknown + Неизвестно + + + Unknown + Unknown (size) + Неизвестно + + + < 1m + < 1 minute + < 1м + + + %1m + e.g: 10minutes + %1м + + + %1h %2m + e.g: 3hours 5minutes + %1ч%2м + + + %1d %2h + e.g: 2days 10hours + %1д%2ч + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorent сейчас выключит компьютер, потому что все загрузки завершены. + + + + options_imp + + Choose a save directory + Выберите путь сохранения + + + Choose an ip filter file + Укажите файл ip фильтра + + + Filters + Фильтры + + + Choose export directory + Выберите папку для экспорта + + + Add directory to scan + Добавить папку для сканирования + + + Folder is already being watched. + Папка уже отслеживается. + + + Folder does not exist. + Папка не существует. + + + Folder is not readable. + Папка не доступна для чтения. + + + Failure + Ошибка + + + Failed to add Scan Folder '%1': %2 + Не удалось добавить папку для сканирования '%1': %2 + + + Parsing error + Ошибка разбора + + + Failed to parse the provided IP filter + Не возможно разобрать данный фильтр IP + + + Succesfully refreshed + Успешно обновлен + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Успешно прочитан данный фильтр IP: %1 правил применено. + + + Successfully refreshed + Успешно обновлён + + + SSL Certificate (*.crt *.pem) + SSL сертификат (*.crt *.pem) + + + SSL Key (*.key *.pem) + SSL ключ (*.key *.pem) + + + Invalid key + Недействительный ключ + + + This is not a valid SSL key. + Это не действительный SSL ключ. + + + Invalid certificate + Недействительный сертификат + + + This is not a valid SSL certificate. + Это не действительный SSL сертификат. + + + + pluginSourceDlg + + Plugin source + Код плагина + + + Search plugin source: + Код поискового плагина: + + + Local file + Локальный файл + + + Web link + Веб ссылка + + + + preview + + Preview selection + Выбор предпросмотра + + + File preview + Предпросмотр файла + + + The following files support previewing, <br>please select one of them: + Следующие файлы поддерживают предпросмотр, <br>выберите один из них: + + + Preview + Предпросмотр + + + Cancel + Отмена + + + + previewSelect + + Preview impossible + Предпросмотр невозможен + + + Sorry, we can't preview this file + Извините, предпросмотр этого файла невозможен + + + Name + Имя + + + Size + Размер + + + Progress + Состояние + + + + search_engine + + Search + Поиск + + + Status: + Состояние: + + + Stopped + Остановлено + + + Download + Скачать + + + Search engines... + Поисковые движки... + + + Go to description page + Перейти на страницу описания + + + + torrentAdditionDialog + + Unable to decode torrent file: + Невозможно декодировать torrent файл: + + + Choose save path + Выберите путь сохранения + + + Empty save path + Очистить путь сохранения + + + Please enter a save path + Пожалуйста, введите путь сохранения + + + Save path creation error + Ошибка создания пути сохранения + + + Could not create the save path + Невозможно создать путь сохранения + + + Invalid file selection + Неправильное выделение файлов + + + You must select at least one file in the torrent + Вы должны выбрать по меньшей мере один файл в torrentе + + + Priority + Приоритет + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 останется после загрузки торрента) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (на %1 больше нужно для загрузки) + + + Seeding mode error + Ошибка режима раздачи + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Вы выбрали пропустить проверку файла. Однако локальные файлы судя по всему не существует в указанной директории. Пожалуйста, отключите это возможность или измените путь сохранения. + + + Rename... + Переименовать... + + + New name: + Новое имя: + + + The file could not be renamed + Файл не может быть переименован + + + This name is already in use in this folder. Please use a different name. + Файл с таким именем уже существует в этой папке. Используйте другое имя. + + + The folder could not be renamed + Папка не может быть переименована + + + Rename the file + Переименовать файл + + + Unable to decode magnet link: + Невозможно декодировать ссылку magnet: + + + Magnet Link + Ссылка magnet + + + Invalid label name + Неправильное имя метки + + + Please don't use any special characters in the label name. + Пожалуйста, не используйте специальные символы в имени метки. + + + This file name contains forbidden characters, please choose a different one. + Имя файла содержит недопустимые символы. Пожалуйста, выберите другое. + + + diff --git a/src/lang/qbittorrent_sk.qm b/src/lang/qbittorrent_sk.qm new file mode 100644 index 0000000000000000000000000000000000000000..7ddc673bf92c0b82f61190ce24732ce995dfc8ee GIT binary patch literal 120018 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 literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_sk.ts b/src/lang/qbittorrent_sk.ts new file mode 100644 index 000000000..0b22ffa53 --- /dev/null +++ b/src/lang/qbittorrent_sk.ts @@ -0,0 +1,5665 @@ + + + + + AboutDlg + + About qBittorrent + O aplikácii qBittorrent + + + About + O aplikácii + + + Author + Autor + + + Name: + Meno: + + + Country: + Krajina: + + + E-mail: + E-mail: + + + Christophe Dumez + Christophe Dumez + + + France + Francúzsko + + + Translation + Preklad + + + License + Licencia + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + chris@qbittorrent.org + chris@qbittorrent.org + + + Thanks to + Poďakovanie + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Klient siete Bittorrent naprogramovaný v C++, založený na sade nástrojov Qt4 </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">a libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Domovská stránka:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent na Freenode</span></p></body></html> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Pokročílý klient siete Bittorrent naprogramovaný v C++, založený na sade nástrojov Qt4 a libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Domovská stránka:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Sledovanie chýb:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Fórum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent na Freenode</span></p></body></html> + + + + AdvancedSettings + + Property + Vlastnosť + + + Value + Hodnota + + + Ignore transfer limits on local network + Ignorovať prenosové limity na lokálnej sieti + + + Include TCP/IP overhead in transfer limits + Zarátavať réžiu TCP/IP do prenosových limitov + + + Disk write cache size + Veľkosť vyrovnávacej pamäte pre zápis na disk + + + MiB + MiB + + + Outgoing ports (Min) [0: Disabled] + Odcházajúce porty (min) [0: Vyonuté] + + + Outgoing ports (Max) [0: Disabled] + Odcházajúce porty (max) [0: Vyonuté] + + + Recheck torrents on completion + Znovu skontrolovať torrenty po dokončení + + + Transfer list refresh interval + Interval obnovovania zoznamu prenosov + + + ms + milliseconds + ms + + + Resolve peer countries (GeoIP) + Prekladať názvy krajín rovesníkov (GeoIP) + + + Resolve peer host names + Prekladať názvy počítačov rovesníkov + + + Maximum number of half-open connections [0: Disabled] + Maximálny počet polootvorených spojení [0: vypnuté] + + + Strict super seeding + Prísne super seedovanie + + + Network Interface (requires restart) + Sieťové rozhranie (vyžaduje reštart) + + + Any interface + i.e. Any network interface + t.j. Ľubovoľné sieťové rozhranie + + + Display program notification baloons + Zobrazovať bublinové upozornenia programu + + + Display program notification balloons + Zobrazovať bublinové upozornenia programu + + + Enable embedded tracker + Zapnúť zabudovaný tracker + + + Embedded tracker port + Port zabudovaného trackera + + + Check for software updates + Skontrolovať aktualizácie softvéru + + + Use system icon theme + Používať vzhľad ikon systému + + + Confirm torrent deletion + Potvrdenie zmazania torrentu + + + IP Address to report to trackers (requires restart) + Akú IP adresu oznamovať trackeru (vyžaduje reštart) + + + Display program on-screen notifications + Zobrazovať OSD upozornenia + + + Setting + Nastavenie + + + Value + Value set for this setting + Hodnota + + + Exchange trackers with other peers + + + + + AutomatedRssDownloader + + Automated RSS Downloader + Automatické sťahovanie RSS + + + Enable the automated RSS downloader + Zapnúť automatické sťahovanie RSS + + + Download rules + Pravidlá sťahovania + + + Rule definition + Definícia pravidla + + + Must contain: + Musí obsahovať: + + + Must not contain: + Nesmie obsahovať: + + + ... + ... + + + Assign label: + Priradiť označenie: + + + Apply rule to feeds: + Použiť pravidlo na kanáy: + + + Matching RSS articles + Zodpovedajúce RSS články + + + Save to a different directory + Uložiť do iného adresára + + + Save to: + Uložiť do: + + + Import... + Importovať... + + + Export... + Exportovať... + + + New rule name + Nový názov pravidla + + + Please type the name of the new download rule. + Prosím, napíšte nový názov pre tonto pravidlo sťahovania. + + + Rule name conflict + Konflikt v názvoch pravidel + + + A rule with this name already exists, please choose another name. + Pravidlo s týmto názvom už existuje. Prosím, zvoľte iný názov. + + + Are you sure you want to remove the download rule named %1? + Ste si istý, že chcete odstrániť pravidlo sťahovania s názvom %1? + + + Are you sure you want to remove the selected download rules? + Ste si istý, že chcete odstrániť vybrané pravidlá sťahovania? + + + Rule deletion confirmation + Potvrdenie zmazania pravidla + + + Destination directory + Cieľový adresár + + + Invalid action + Neplatná operácia + + + The list is empty, there is nothing to export. + Zoznam je prázdny, niet čo exportovať. + + + Where would you like to save the list? + Kam chcete uložiť tento súbor? + + + Rules list (*.rssrules) + Zoznam pravidiel (*.rssrules) + + + I/O Error + V/V Chyba + + + Failed to create the destination file + Nepodarilo sa vytvoriť cieľový súbor + + + Please point to the RSS download rules file + Prosím, vyberte súbor s pravidlami sťahovania RSS + + + Rules list (*.rssrules *.filters) + Zoznam pravidiel (*.rssrules *.filters) + + + Import Error + Chyba importu + + + Failed to import the selected rules file + Nepodarilo sa importovať vybraný súbor pravidiel + + + Add new rule... + Pridať nové pravidlo... + + + Delete rule + Zmazať pravidlo + + + Rename rule... + Premenovať pravidlo... + + + Delete selected rules + Zmazať vybrané pravidlá + + + Rule renaming + Premenovanie pravidiel + + + Please type the new rule name + Prosím, napíšte názov nového pravidla + + + Use regular expressions + Používať regulárne výrazy + + + Regex mode: use Perl-like regular expressions + Režim regulárnych výrazov: používať štýl Perl + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Režim zástupných znakov: <ul><li>? zodpovedá ľubovoľnému jednotlivému znaku</li><li>* zodpovedá nula alebo viac ľubovoľným znakom</li><li>Netlačiteľné znaky sa počítajú ako operátory AND</li></ul> + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Režim zástupných znakov: <ul><li>? zodpovedá ľubovoľnému jednotlivému znaku</li><li>* zodpovedá nula alebo viac ľubovoľným znakom</li><li>| sa používa ako operátor OR</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 dosiahol maximálny požadovaný pomer. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent sa viaže na port: TCP/%1 + + + UPnP support [ON] + Podpora UPnP [zapnutá] + + + UPnP support [OFF] + Podpora UPnP [vypnutá] + + + NAT-PMP support [ON] + Podpora NAT-PMP [zapnutá] + + + NAT-PMP support [OFF] + Podpora NAT-PMP [vypnutá] + + + DHT support [ON], port: UDP/%1 + Podpora DHT [ZAP], port: UDP/%1 + + + DHT support [OFF] + Podpora DHT [vypnutá] + + + PeX support [ON] + Podpora PeX [zapnutá] + + + Local Peer Discovery [ON] + Local Peer Discovery [zapnutá] + + + Local Peer Discovery support [OFF] + Podpora Local Peer Discovery support [vypnutá] + + + Encryption support [ON] + Podpora šifrovania [zapnuté] + + + Encryption support [FORCED] + Podpora šifrovania [vynútené] + + + Encryption support [OFF] + Podpora šifrovania [vypnuté] + + + Web User Interface Error - Unable to bind Web UI to port %1 + Chyba webového rozhrania - nepodaril sa bind webového rozhrania na port %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + „%1“ bol odstránený zo zoznamu sťahovaných a z pevného disku. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + „%1“ bol odstránený zo zoznamu sťahovaných. + + + '%1' is not a valid magnet URI. + „%1“ nie je platný magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + „%1“ sa už nachádza v zozname sťahovaných. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + „%1“ bol obnovený. (rýchle obnovenie) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + „%1“ bol pridaný do zoznamu na sťahovanie. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Nepodarilo sa dekódovať torrent súbor: „%1“ + + + This file is either corrupted or this isn't a torrent. + Tento súbor je buď poškodený alebo to nie je torrent. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>zablokoval váš filter IP adries</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>zablokovaný kvôli posielaniu poškodených častí</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekurzívne sťahovanie súboru %1 vnoreného v torrente %2 + + + Unable to decode %1 torrent file. + Nepodarilo sa dekódovať torrent súbor %1. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Zlyhanie mapovania portov, správa: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Mapovanie portov úspešné, správa: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Rýchle obnovenie torrentu %1 bolo odmietnuté, prebieha opätovná kontrola... + + + Url seed lookup failed for url: %1, message: %2 + Vyhľadanie url seedu zlyhalo pre url: %1, správa: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Prebieha sťahovanie „%1“, čakajte prosím... + + + Using a disk cache size of %1 MiB + Používa sa veľkosť vyrovnávacej diskovej pamäte %1 MiB + + + PeX support [OFF] + Podpora PeX [VYP] + + + Restart is required to toggle PeX support + Na prepnutie podpory PeX je potrebný reštart + + + The Web UI is listening on port %1 + Webové rozhranie počúva na porte %1 + + + HTTP user agent is %1 + HTTP user agent je %1 + + + Reason: %1 + Dôvod: %1 + + + Note: new trackers were added to the existing torrent. + Pozn.: Do existujúceho torrentu boli pridané nové trackery. + + + Note: new URL seeds were added to the existing torrent. + Pozn.: Do existujúceho torrentu boli pridané nové URL seedy. + + + An I/O error occured, '%1' paused. + Vyskytla sa V/V chyba, „%1“ pozastavené. + + + Removing torrent %1... + Odstraňuje sa torrent %1... + + + Pausing torrent %1... + Pozastavuje sa torrent %1... + + + Error: The torrent %1 does not contain any file. + Chyba: Torrent %1 neobsahuje žiaden súbor. + + + File sizes mismatch for torrent %1, pausing it. + Veľkosti súborov sa líšia pri torrente %1, pozastavuje sa. + + + Torrent name: %1 + Názov torrentu: %1 + + + Torrent size: %1 + Veľkosť torrentu: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent bol stiahnutý za %1. + + + Thank you for using qBittorrent. + Ďakujeme, že používate qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] sťahovanie %1 bolo dokončené + + + + ConsoleDlg + + General + Všeobecné + + + Blocked IPs + Zablokované IP + + + qBittorrent log viewer + Prehliadač záznamov qBittorrent + + + + CookiesDlg + + Cookies management + Správa cookies + + + Key + As in Key/Value pair + Kľúč + + + Value + As in Key/Value pair + Hodnota + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Bežné kľúče cookies sú : '%1', '%2'. +Túto informáciu by ste mali zistiť z nastavení svojho webového prehliadača. + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + Váš dynamický DNS záznam bol úspešne aktualizovaný. + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Chyba dynamického DNS: Služba je dočasne nedostupná, pokus sa zopakuje o 30 minút. + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Chyba dynamického DNS: Zadaný názov hostiteľa v uvedenom účte neexistuje. + + + Dynamic DNS error: Invalid username/password. + Chyba dynamického DNS: Neplatné používateľské meno alebo heslo. + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Chyba dynamického DNS: qBittorrent bol zaradenú na čiernu listinu služby, prosím, nahláste chybu na http://bugs.qbittorrent.org. + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Chyba dynamického DNS: Služba vrátila %1, prosím, nahláste chybu na http://bugs.qbittorrent.org. + + + Dynamic DNS error: Your username was blocked due to abuse. + Chyba dynamického DNS: Vaše používateľské meno bolo zablokované z dôvodu zneužitia. + + + Dynamic DNS error: supplied domain name is invalid. + Chyba dynamického DNS: Zadaný názov domény nie je platný. + + + Dynamic DNS error: supplied username is too short. + Chyba dynamického DNS: Zadané používateľské meno je príliš krátke. + + + Dynamic DNS error: supplied password is too short. + Chyba dynamického DNS: Zadané heslo je príliš krátke. + + + + DownloadThread + + I/O Error + V/V Chyba + + + The remote host name was not found (invalid hostname) + Názov vzdialeného počítača nebol zistený (neplatný názov počítača) + + + The operation was canceled + Operácia bola zrušená + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Vzdialený server predčasne zatvoril spojenie predtým, než bola prijatá a spracovaná celá odpoveď + + + The connection to the remote server timed out + Čas spojenia so vzdialeným serverom vypršal + + + SSL/TLS handshake failed + SSL/TLS handshake zlyhal + + + The remote server refused the connection + Vzdialený server odmietol spojenie + + + The connection to the proxy server was refused + Spojenie s proxy serverom bolo odmietnuté + + + The proxy server closed the connection prematurely + Proxy server predčasne zatvoril spojenie + + + The proxy host name was not found + Názov proxy servera nebol nájdený + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Čas spojenia s proxy serverom vypršal alebo proxy server neodpovedal včas na zaslanú požiadavku + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Proxy vyžaduje autentifikáciu aby mohol splniť požiadavku, ale neprijal žiadne z ponúknutých prihlasovacích údajov + + + The access to the remote content was denied (401) + Prístup k vzdialenému obsahu bol zamietnutý (401) + + + The operation requested on the remote content is not permitted + Požadovaná operácia so vzdialeným obsahom nie je povolená + + + The remote content was not found at the server (404) + Vzdialený obsah nebol nájdený na serveri (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Vzdialený server vyžaduje na poskytnutie obsahu autentifikáciu, ale neprijal žiadne z ponúknutých prihlasovacích údajov + + + The Network Access API cannot honor the request because the protocol is not known + Network Access API neprijalo požiadavku, pretože nie je známy protokol + + + The requested operation is invalid for this protocol + Požadovaná operácia nie je platná pre tento protokol + + + An unknown network-related error was detected + Bola zistená neznáma chyba týkajúca sa siete + + + An unknown proxy-related error was detected + Bola zistená neznáma chyba týkajúca sa proxy + + + An unknown error related to the remote content was detected + Bola zistená neznáma chyba týkajúca sa vzdialeného obsahu + + + A breakdown in protocol was detected + Bola zistená porucha v protokole + + + Unknown error + Neznáma chyba + + + + EventManager + + %1/s + e.g. 120 KiB/s + %1/s + + + Working + Pracuje sa + + + Updating... + Prebieha aktualizácia... + + + Not working + Nefunguje + + + Not contacted yet + Zatiaľ nekontaktovaný + + + this session + táto relácia + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seedovaný %1 + + + %1 max + e.g. 10 max + max %1 + + + + ExecutionLog + + Form + Formulár + + + General + Všeobecné + + + Blocked IPs + Zablokované IP + + + + FeedDownloader + + RSS Feed downloader + Sťahovanie RSS kanála + + + RSS feed: + RSS kanál: + + + Feed name + Názov kanála + + + Automatically download torrents from this feed + Automaticky sťahovať torrenty z tohto kanála + + + Download filters + Filtre sťahovania + + + Filters: + Filtre: + + + Filter settings + Nastavenia filtrov + + + Matches: + Zodpovedá: + + + Does not match: + Nezodpovedá: + + + Destination folder: + Cieľový priečinok: + + + ... + ... + + + Filter testing + Testovanie filtra + + + Torrent title: + Názov torrentu: + + + Result: + Výsledok: + + + Test + Test + + + Import... + Import... + + + Export... + Export... + + + Rename filter + Premenovať filter + + + Remove filter + Odstrániť filter + + + Add filter + Pridať filter + + + + FeedDownloaderDlg + + New filter + Nový filter + + + Please choose a name for this filter + Prosím, vyberte názov pre tento filter + + + Filter name: + Názov filtra: + + + Invalid filter name + Neplatný názov filtra + + + The filter name cannot be left empty. + Názov filtra nemôže byť prázdny. + + + This filter name is already in use. + Tento názov filtra už existuje. + + + Filter testing error + Chyba pri testovaní filtra + + + Please specify a test torrent name. + Prosím, uveďte názov testovacieho torrentu. + + + matches + zodpovedá + + + does not match + nezodpovedá + + + Select file to import + Vyberte súbor na import + + + Filters Files + Filtre Súbory + + + Import successful + Import prebehol úspešne + + + Filters import was successful. + Import filtrov prebehol úspešne. + + + Import failure + Chyba importu + + + Filters could not be imported due to an I/O error. + Nebolo možné importovať filtre z dôvodu V/V chyby. + + + Select destination file + Vyberte cieľový súbor + + + Export successful + Export prebehol úspešne + + + Filters export was successful. + Export filtrov prebehol úspešne. + + + Export failure + Chyba exportu + + + Filters could not be exported due to an I/O error. + Nebolo možné exportovať filtre z dôvodu V/V chyby. + + + Choose save path + Ukladať kam + + + + FeedList + + Unread + Neprečítané + + + + FeedListWidget + + RSS feeds + RSS kanály + + + + Unread + Neprečítané + + + + GUI + + Open Torrent Files + Otvoriť torrent súbory + + + Torrent Files + Torrent súbory + + + qBittorrent + qBittorrent + + + Transfers + Prenosy + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Rýchlosť sťahovania: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Rýchlosť nahrávania: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 je stiahnutý. + + + I/O Error + i.e: Input/Output Error + V/V Chyba + + + Search + Vyhľadávanie + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Vyskytla sa V/V chyba pri torrente %1. + Dôvod: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Chyba sťahovania url + + + Couldn't download file at url: %1, reason: %2. + Nebolo možné stiahnuť súbor z url: %1, dôvod: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Options were saved successfully. + Nastavenia boli úspešne uložené. + + + Download completion + Dokončenie sťahovnia + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Niektoré súbory sa práve prenášajú. +Ste si istý, že chcete ukončiť Bittorrent? + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Globálne rýchlostné obmedzenie nahrávania + + + Global Download Speed Limit + Globálne rýchlostné obmedzenie sťahovania + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (sťah: %2/s, nahr: %3/s) + + + Recursive download confirmation + Potvrdenie rekurzívneho sťahovania + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent %1 obsahuje ďalšie súbory torrent. Chcete začať sťahovať aj tie? + + + Torrent file association + Asociácia typu súboru .torrent + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent nie je predvolená aplikácia na otváranie súborov torrent a odkazov Magnet. +Chcete asociovať qbittorrent so súbormi torrent a odkazmi Magnet? + + + Transfers (%1) + Prenosy (%1) + + + Yes + Áno + + + No + Nie + + + Never + Nikdy + + + Always + Vždy + + + Exiting qBittorrent + Ukončuje sa qBittorrent + + + Set the password... + Nastaviť heslo... + + + Password update + Aktualizovať heslo + + + The UI lock password has been successfully updated + Heslo na zamknutie používateľského rozhrania bolo úspešne aktualizované + + + UI lock password + Heslo na zamknutie používateľského rozhrania + + + Please type the UI lock password: + Prosím, napíšte heslo na zamknutie používateľského rozhrania: + + + Invalid password + Neplatné heslo + + + The password is invalid + Heslo nie je platné + + + A newer version is available + Je dostupná novšia verzia + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + qBittorrent má novú verziu dostupnú zo Sourceforge. +Chcete aktualizovať qBittorrent na verziu %1? + + + Impossible to update qBittorrent + Nie je možné aktualizovať qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent sa nepodarilo aktualizovať. Dôvod: %1 + + + + GeoIP + + Australia + Austrália + + + Argentina + Argentína + + + Austria + Rakúsko + + + United Arab Emirates + Spojené arabské emiráty + + + Brazil + Brazília + + + Bulgaria + Bulharsko + + + Belarus + Bielorusko + + + Belgium + Belgicko + + + Bosnia + Bosna + + + Canada + Kanada + + + Czech Republic + Česko + + + China + Čína + + + Costa Rica + Kostarika + + + Switzerland + Švajčiarsko + + + Germany + Nemecko + + + Denmark + Dánsko + + + Algeria + Alžírsko + + + Spain + Španielsko + + + Egypt + Egypt + + + Finland + Fínsko + + + France + Francúzsko + + + United Kingdom + Spojené kráľovstvo + + + Greece + Grécko + + + Georgia + Gruzínsko + + + Hungary + Maďarsko + + + Croatia + Chorvátsko + + + Italy + Taliansko + + + India + India + + + Israel + Izrael + + + Ireland + Írsko + + + Iceland + Island + + + Indonesia + Indonézia + + + Japan + Japonsko + + + South Korea + Kórejská republika + + + Luxembourg + Luxembursko + + + Malaysia + Malajzia + + + Mexico + Mexiko + + + Serbia + Srbsko + + + Morocco + Maroko + + + Netherlands + Holandsko + + + Norway + Nórsko + + + New Zealand + Nový Zéland + + + Portugal + Portugalsko + + + Poland + Poľsko + + + Pakistan + Pakistan + + + Philippines + Filipíny + + + Russia + Rusko + + + Romania + Rumunsko + + + France (Reunion Island) + Francúzsko (ostrov Réunion) + + + Sweden + Švédsko + + + Slovakia + Slovensko + + + Singapore + Singapur + + + Slovenia + Slovinsko + + + Turkey + Turecko + + + Thailand + Thajsko + + + USA + Spojené štáty + + + Ukraine + Ukrajina + + + South Africa + Južná Afrika + + + Saudi Arabia + Saudská Arábia + + + + HeadlessLoader + + Information + Informácie + + + To control qBittorrent, access the Web UI at http://localhost:%1 + qBittorrentmôžete ovládať z webového rozhrania na adrese http://localhost:%1 + + + The Web UI administrator user name is: %1 + Používateľské meno správcu webového rozhrania je: %1 + + + The Web UI administrator password is still the default one: %1 + Heslo správcu webového rozhrania je stále predvolená hodnota: %1 + + + This is a security risk, please consider changing your password from program preferences. + Toto je bezpečnostné riziko. Prosím, zmeňte si heslo v Nastaveniach programu. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + Vaša IP adresa bola zablokovaná po príliš mnohých pokusoch o autentifikáciu. + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Sťah.: %1/s - Pren.: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Nahr.: %1/s - Pren.: %2 + + + + HttpServer + + File + Súbor + + + Edit + Upraviť + + + Help + Pomocník + + + Delete from HD + Zmazať z disku + + + Download Torrents from their URL or Magnet link + Stiahnuť torrenty z ich URL alebo Magnet odkazu + + + Only one link per line + Iba jeden odkaz na riadok + + + Download + Stiahnuť + + + Download local torrent + Stiahnuť lokálny torrent + + + Torrent files were correctly added to download list. + Torrenty boli úspešne pridané do zoznamu sťahovaných. + + + Point to torrent file + Ukázať na torrent + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Ste s istý, že chcete zmazať vybrané torrenty zo zoznamu prenosov a pevného disku? + + + Download rate limit must be greater than 0 or disabled. + Obmedzenie rýchlosti sťahovania musí byť väčšie ako 0 alebo vypnuté. + + + Upload rate limit must be greater than 0 or disabled. + Obmedzenie rýchlosti nahrávania musí byť väčšie ako 0 alebo vypnuté. + + + Maximum number of connections limit must be greater than 0 or disabled. + Maximálny počet spojení musí byť väčší ako 0 alebo vypnutý. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Maximálny počet spojení na torrent musí byť väčší ako 0 alebo vypnutý. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Maximálny počet nahrávacích pozící musí byť väčší ako 0 alebo vypnutý. + + + Unable to save program preferences, qBittorrent is probably unreachable. + Nepodarilo sa uložiť nastavenia programu, qBittorrent je pravdepodobne nedostupný. + + + Language + Jazyk + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Port pre prichádzajúce spojenia musí byť medzi 1024 a 65535. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Port pre webové rozhranie musí byť medzi 1024 a 65535. + + + The Web UI username must be at least 3 characters long. + Používateľské meno pre webové rozhranie musí mať dĺžku aspoň 3 znaky. + + + The Web UI password must be at least 3 characters long. + Heslo pre webové rozhranie musí mať dĺžku aspoň 3 znaky. + + + Downloaded + Is the file downloaded or not? + Stiahnuté + + + Save + Uložiť + + + qBittorrent client is not reachable + Klient qBittorrent nie je dostupný + + + HTTP Server + HTTP server + + + Torrent path + Cesta k torrentu + + + Torrent name + Názov torrentu + + + The following parameters are supported: + Nasledovné parametre sú podporované: + + + + LegalNotice + + Legal Notice + Právny oznam + + + Legal notice + Právne upozornenie + + + Cancel + Zrušiť + + + I Agree + Súhlasím + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent je program na zdieľanie súborov. Keď spustíte torrent, jeho dáta sa sprástupnia iným prostredníctvom nahrávania. Za akýkoľvek obsah, ktorý zdieľate, nesiete zodpovednosť vy. + +Už vás nebudeme ďalej upozorňovať. + + + Press %1 key to accept and continue... + Pokračujte stlačením klávesu %1... + + + + LineEdit + + Clear the text + Vyčistiť pole + + + + MainWindow + + &Edit + &Úpravy + + + &File + &Súbor + + + &Help + &Pomocník + + + Preview file + Náhľad súboru + + + Clear log + Vyčistiť záznam + + + Decrease priority + Znížiť prioritu + + + Increase priority + Zvýšiť prioritu + + + &Tools + Nás&troje + + + &View + &Zobraziť + + + &Add File... + Prid&ať súbor... + + + E&xit + &Ukončiť + + + &Options... + Mo&žnosti... + + + Add &URL... + Pridať &URL... + + + Torrent &creator + Tvor&ca torrentu + + + Set upload limit... + Nastaviť obmedzenie nahrávania... + + + Set download limit... + Nastaviť obmedzenie šťahovania... + + + Set global download limit... + Nastaviť globálne obmedzenie sťahovania... + + + Set global upload limit... + Nastaviť globálne obmedzenie nahrávania... + + + &Log viewer... + Preh&liadač záznamov... + + + Top &tool bar + Horný panel nás&trojov + + + Display top tool bar + Zobrazovať horný panel nástrojov + + + &Speed in title bar + Rýchlo&sť v titulnom pruhu + + + Show transfer speed in title bar + Zobraziť prenosovú rýchlosť v titulnom pruhu + + + Alternative speed limits + Alternatívne rýchlostné obmedzenia + + + &About + O &aplikácii + + + &Pause + &Pozastaviť + + + &Delete + + + + P&ause All + Poz&astaviť všetky + + + Visit &Website + Navštíviť &webstránku + + + Report a &bug + Oznámiť chy&bu + + + &Documentation + &Dokumentácia + + + &RSS reader + Čítačka &RSS + + + Search &engine + &Vyhľadávač + + + Lock qBittorrent + Zamknúť qBittorrent + + + Ctrl+L + Ctrl+L + + + Shutdown computer when downloads complete + Vypnúť počítač po dokončení sťahovaní + + + &Resume + Pok&račovať + + + R&esume All + Pokračovať vš&etky + + + Shutdown qBittorrent when downloads complete + Vypnúť qBittorrent po dokončení sťahovaní + + + Exit + Ukončiť + + + Import torrent... + Importovať torrent... + + + Donate money + Venovať peniaze + + + If you like qBittorrent, please donate! + Ak sa vám qBittorrent páči, prosím, prispejte! + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + Nastaviť heslo... + + + Transfers + Prenosy + + + Torrent file association + Asociácia typu súboru .torrent + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent nie je predvolená aplikácia na otváranie súborov torrent a odkazov Magnet. +Chcete asociovať qBittorrent so súbormi torrent a odkazmi Magnet? + + + UI lock password + Heslo na zamknutie používateľského rozhrania + + + Please type the UI lock password: + Prosím, napíšte heslo na zamknutie používateľského rozhrania: + + + Password update + Aktualizovať heslo + + + The UI lock password has been successfully updated + Heslo na zamknutie používateľského rozhrania bolo úspešne aktualizované + + + RSS + RSS + + + Search + Vyhľadávanie + + + Transfers (%1) + Prenosy (%1) + + + Download completion + Dokončenie sťahovnia + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 je stiahnutý. + + + I/O Error + i.e: Input/Output Error + V/V Chyba + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Vyskytla sa V/V chyba pri torrente %1. + Dôvod: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Potvrdenie rekurzívneho sťahovania + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent %1 obsahuje ďalšie súbory torrent. Chcete začať sťahovať aj tie? + + + Yes + Áno + + + No + Nie + + + Never + Nikdy + + + Url download error + Chyba sťahovania url + + + Couldn't download file at url: %1, reason: %2. + Nebolo možné stiahnuť súbor z url: %1, dôvod: %2. + + + Global Upload Speed Limit + Globálne rýchlostné obmedzenie nahrávania + + + Global Download Speed Limit + Globálne rýchlostné obmedzenie sťahovania + + + Invalid password + Neplatné heslo + + + The password is invalid + Heslo nie je platné + + + Exiting qBittorrent + Ukončuje sa qBittorrent + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Niektoré súbory sa práve prenášajú. +Ste si istý, že chcete ukončiť Bittorrent? + + + Always + Vždy + + + Open Torrent Files + Otvoriť torrent súbory + + + Torrent Files + Torrent súbory + + + Options were saved successfully. + Nastavenia boli úspešne uložené. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Rýchlosť sťahovania: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Rýchlosť nahrávania: %1 KiB/s + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (sťah: %2/s, nahr: %3/s) + + + A newer version is available + Je dostupná novšia verzia + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + qBittorrent má novú verziu dostupnú na Sourceforge. +Chcete aktualizovať qBittorrent na verziu %1? + + + Impossible to update qBittorrent + Nie je možné aktualizovať qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent sa nepodarilo aktualizovať. Dôvod: %1 + + + &Add torrent file... + Prid&ať súbor torrent... + + + Add &link to torrent... + Pridať &odkaz na torrent... + + + Import existing torrent... + Importovať existujúci torrent... + + + Execution &Log + &Záznam spustení + + + Execution Log + Záznam spustení + + + Auto-Shutdown on downloads completion + Vypnúť počítač po dokončení sťahovaní + + + Exit qBittorrent + Ukončiť qBittorrent + + + Suspend system + Uspať systém + + + Shutdown system + Vypnúť systém + + + Disabled + Vypnuté + + + The password should contain at least 3 characters + Heslo by malo obsahovať aspoň 3 znaky + + + + PeerAdditionDlg + + Invalid IP + Neplatná IP + + + The IP you provided is invalid. + IP, ktorú ste poskytli je neplatná. + + + + PeerListDelegate + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + Klient + + + Progress + i.e: % downloaded + Priebeh + + + Down Speed + i.e: Download speed + Rýchlosť sťahovania + + + Up Speed + i.e: Upload speed + Rýchlosť nahrávania + + + Downloaded + i.e: total data downloaded + Stiahnuté + + + Uploaded + i.e: total data uploaded + Nahrané + + + Ban peer permanently + Zablokovať rovesníka na stálo + + + Peer addition + Pridanie rovesníka + + + The peer was added to this torrent. + Rovesník bol pridaný k tomuto torrentu. + + + The peer could not be added to this torrent. + Rovesníka nebolo možné pridať k tomuto torrentu. + + + Are you sure? -- qBittorrent + Ste si istý? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + Ste si istý, že chcete zmazať natrvalo zablokovať vybraného rovesníka? + + + &Yes + Án&o + + + &No + &Nie + + + Manually banning peer %1... + Manuálne zablokovaný rovesník %1... + + + Upload rate limiting + Obmedzenie rýchlosti nahrávania + + + Download rate limiting + Obmedzenie rýchlosti sťahovania + + + Add a new peer... + Pridať nového rovesníka... + + + Limit download rate... + Obmedziť rýchlosť sťahovania... + + + Limit upload rate... + Obmedziť rýchlosť nahrávania... + + + Copy IP + Kopírovať IP + + + Connection + Spojenie + + + + Preferences + + UI + User Interface + Rozhranie + + + Downloads + Sťahovania + + + Connection + Spojenie + + + Bittorrent + Bittorrent + + + Proxy + Proxy + + + Web UI + Webové rozhranie + + + Language: + Jazyk: + + + (Requires restart) + Obnoviť RSS kanály + + + Visual style: + Vizuálny štýl: + + + Transfer list + Zoznam prenosov + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Používať striedavé farby pozadia riadkov + + + File system + Súborový systém + + + Torrent queueing + Zaraďovanie torrentov do frontu + + + Maximum active downloads: + Maximum aktívnych sťahovaní: + + + Maximum active uploads: + Max. aktívnych nahrávaní: + + + Maximum active torrents: + Maximum aktívnych torrentov: + + + When adding a torrent + Pri pridávaní torrentu + + + Display torrent content and some options + Zobraziť obsah torrentu a nejaké voľby + + + Listening port + Počúvať na porte + + + Port used for incoming connections: + Port pre prichádzajúce spojenia: + + + Random + Náhodný + + + Enable UPnP port mapping + Zapnúť mapovanie portov UPnP + + + Enable NAT-PMP port mapping + Zapnúť mapovanie portov NAT-PMP + + + Connections limit + Limit spojení + + + Global maximum number of connections: + Maximálny globálny počet spojení: + + + Maximum number of connections per torrent: + Maximálny počet spojení na torrent: + + + Maximum number of upload slots per torrent: + Maximálny počet slotov pre nahrávanie na torrent: + + + Upload: + Nahrávanie: + + + Download: + Sťahovanie: + + + KiB/s + KiB/s + + + Bittorrent features + Možnosti siete Bittorrent + + + Enable DHT network (decentralized) + Zapnúť sieť DHT (decentralizovaná) + + + Use a different port for DHT and Bittorrent + Používať odlišný port pre DHT a Bittorrent + + + DHT port: + Port DHT: + + + Enable Peer Exchange / PeX (requires restart) + Zapnúť Peer eXchange / PeX (vyžaduje reštart) + + + Enable Local Peer Discovery + Zapnúť Local Peer Discovery + + + Enabled + Zapnuté + + + Forced + Vynútené + + + Disabled + Vypnuté + + + Type: + Typ: + + + (None) + (žiadny) + + + HTTP + HTTP + + + Port: + Port: + + + Authentication + Autentifikácia + + + Username: + Meno používateľa: + + + Password: + Heslo: + + + SOCKS5 + SOCKS5 + + + HTTP Server + HTTP Server + + + Filter path (.dat, .p2p, .p2b): + Cesta k filtrom (.dat, .p2p, .p2b): + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP komunikácia (trackery, web seedy, vyhľadávač) + + + Host: + Počítač: + + + Peer Communications + Komunikácia s rovesníkmi + + + SOCKS4 + SOCKS4 + + + Speed + Rýchlosť + + + Global speed limits + Globálne rýchlostné obmedzenia + + + Alternative global speed limits + Alternatívne globálne rýchlostné obmedzenia + + + to + time1 to time2 + do + + + Every day + Každý deň + + + Week days + Pracovné dni + + + Week ends + Víkendy + + + Advanced + Rozšírené + + + Copy .torrent files to: + Kopírovať .torrent súbory do: + + + Remove folder + Odstrániť priečinok + + + No action + Žiadna činnosť + + + Options + Možnosti + + + Visual Appearance + Vzhľad + + + Action on double-click + Operácia po dvojitom kliknutí + + + Downloading torrents: + Sťahujú sa torrenty: + + + Start / Stop + Spustiť/zastaviť + + + Open destination folder + Otvoriť cieľový priečinok + + + Completed torrents: + Dokončené torrenty: + + + Desktop + Plocha + + + Show splash screen on start up + Zobraziť pri spustení štartovaciu obrazovku + + + Start qBittorrent minimized + Spustiť qBittorrent minimalizovaný + + + Show qBittorrent icon in notification area + Zobraziť qBittorrent v oznamovacej oblasti + + + Minimize qBittorrent to notification area + Minimalizovať qBittorrent do oznamovacej oblasti + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Zatvoriť qBittorrent do oznamovacej oblasti + + + Do not start the download automatically + The torrent will be added to download list in pause state + Torrent sa pridá do zoznamu sťahovaných v stave pozastavený + + + Save files to location: + Ukladať súbory do priečinka: + + + Append the label of the torrent to the save path + Pridať označenie torrentu k ceste, kam sa ukladá + + + Pre-allocate disk space for all files + Dopredu alokovať miesto pre všetky súbory + + + Keep incomplete torrents in: + Ponechať neúplné torrenty v: + + + Append .!qB extension to incomplete files' names + Pridávať nedosťahovaným súborom príponu.!qB + + + Automatically add torrents from: + Automaticky pridať torrenty z: + + + Add folder... + Pridať priečinok ... + + + IP Filtering + IP filter + + + Schedule the use of alternative speed limits + Naplánovať použitie alternatívnych rýchlostných obmedzení + + + from + from (time1 to time2) + od + + + When: + Kedy: + + + Look for peers on your local network + Hľadať rovesníkov na vašej lokálnej sieti + + + Protocol encryption: + Šifrovanie protokolu: + + + Enable Web User Interface (Remote control) + Zapnúť webové rozhranie (diaľkové ovládanie) + + + Share ratio limiting + Obmedzenie pomeru zdieľania + + + Seed torrents until their ratio reaches + Seedovať torrenty pokým ich pomer nedosiahne + + + then + potom + + + Pause them + ich pozastaviť + + + Remove them + ich odstrániť + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Vymieňať si zoznam rovesníkov s kompatibilnými klientmi siete Bittorrent (µTorrent, Vuze, ...) + + + Email notification upon download completion + Upozornenie o dokončení sťahovania emailom + + + Destination email: + Cieľový email: + + + SMTP server: + SMTP server: + + + Run an external program on torrent completion + Po dokončení sťahovania spustiť externý program + + + Use %f to pass the torrent path in parameters + Pomocou %f môžete odovzdať v parametroch cestu k torrentu + + + Proxy server + Proxy server + + + BitTorrent + Bittorrent + + + Start / Stop Torrent + Spustiť/zastaviť torrent + + + Use UPnP / NAT-PMP port forwarding from my router + Použiť presmerovanie portov UPnP/NAT-PMP z môjho smerovača + + + Privacy + Súkromie + + + Enable DHT (decentralized network) to find more peers + Zapnúť DHT (decentralizovaná sieť) - umožní nájsť viac rovesníkov + + + Use a different port for DHT and BitTorrent + Používať odlišný port pre DHT a Bittorrent + + + Enable Peer Exchange (PeX) to find more peers + Zapnúť Peer eXchange (PeX) - umožní nájsť viac rovesníkov + + + Enable Local Peer Discovery to find more peers + Zapnúť Local Peer Discovery - umožní nájsť viac rovesníkov + + + Encryption mode: + + + + Prefer encryption + Uprednostňovať šifrovanie + + + Require encryption + Vyžadovať šifrovanie + + + Disable encryption + Vypnúť šifrovanie + + + User Interface + Používateľské rozhranie + + + Reload the filter + Znovu načítať filter + + + Behavior + Správanie + + + Language + Jazyk + + + Power Management + Správa napájania + + + Inhibit system sleep when torrents are active + Potlačiť prechod systému do režimu spánku ak sú torrenty aktívne + + + Bypass authentication for localhost + Obísť autentifikáciu pri prihlasovaní z lokálneho počítača + + + Ask for program exit confirmation + Potvrdenie ukončenia programu + + + Use monochrome system tray icon (requires restart) + Používať monochromatickú ikonu v oznamovacej oblasti (vyžaduje reštart) + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Nasledovné parametre sú podporované: +<ul> +<li>%f: Cesta k torrentu</li> +<li>%n: Názov torrentu</li> +</ul> + + + Tray icon style: + Štýl ikony v oznamovacej oblasti: + + + Normal + Normálny + + + Monochrome (Dark theme) + Monochromatický (tmavá téma) + + + Monochrome (Light theme) + Monochromatický (svetlá téma) + + + This server requires a secure connection (SSL) + Tento server vyžaduje zabezpečené pripojenie (SSL) + + + User Interface Language: + Jazyk používateľského rozhrania: + + + Transfer List + Zoznam prenosov + + + Show qBittorrent in notification area + Zobraziť qBittorrent v oznamovacej oblasti + + + Hard Disk + Pevný disk + + + Listening Port + Počúvať na porte + + + Connections Limits + Limit spojení + + + Proxy Server + Proxy server + + + Torrent Queueing + Zaraďovanie torrentov do frontu + + + Share Ratio Limiting + Obmedzenie pomeru zdieľania + + + Use UPnP / NAT-PMP to forward the port from my router + Použiť presmerovanie portov UPnP/NAT-PMP z môjho smerovača + + + Update my dynamic domain name + Aktualizovať môj dynamický názov domény + + + Service: + Služba: + + + Register + Zaregistrovať sa + + + Domain name: + Názov domény: + + + Global Rate Limits + Globálne rýchlostné obmedzenia + + + Apply rate limit to uTP connections + Použiť rýchlostné obmedzenie na spojenia uTP + + + Apply rate limit to transport overhead + Použiť rýchlostné obmedzenie na réžiu prenosu + + + Alternative Global Rate Limits + Alternatívne globálne rýchlostné obmedzenia + + + Schedule the use of alternative rate limits + Naplánovať použitie alternatívnych rýchlostných obmedzení + + + Enable bandwidth management (uTP) + Zapnúť správu šírky pásma (uTP) + + + Otherwise, the proxy server is only used for tracker connections + Inak sa proxy server použije iba na pripojenia k trackeru + + + Use proxy for peer connections + Používať proxy na spojenia s rovesníkmi + + + Append .!qB extension to incomplete files + Pridávať príponu .!qB k neúplným súborom + + + Use HTTPS instead of HTTP + Používať HTTPS namiesto HTTP + + + Import SSL Certificate + Importovať certifikát SSL + + + Import SSL Key + Importovať kľúč SSL + + + Certificate: + Certifikát: + + + Key: + Kľúč: + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Informácie o certifikátoch</a> + + + + PreviewSelect + + Name + Názov + + + Size + Veľkosť + + + Progress + Priebeh + + + Preview impossible + Náhľad nie je možný + + + Sorry, we can't preview this file + Prepáčte, tento súbor sa nedá otvoriť ako náhľad + + + + ProgramUpdater + + Could not create the file %1 + Nepodarilo sa vytvoriť súbor %1 + + + Failed to download the update at %1 + %1 is an URL + Nepodarilo sa stiahnuť aktualizáciu z %1 + + + + PropListDelegate + + Normal + Normal (priority) + Normálna + + + High + High (priority) + Vysoká + + + Maximum + Maximum (priority) + Maximálna + + + Not downloaded + Nestiahnuté + + + Mixed + Mixed (priorities + Ziešané + + + + PropTabBar + + General + Všeobecné + + + Trackers + Trackery + + + Peers + Rovesníci + + + URL Seeds + URL seedy + + + Files + Súbory + + + HTTP Sources + HTTP zdroje + + + Content + Obsah + + + + PropertiesWidget + + Save path: + Uložiť kam: + + + Torrent hash: + Haš torrentu: + + + Share ratio: + Pomer zdieľania: + + + General + Všeobecné + + + Trackers + Trackery + + + URL seeds + URL seedy + + + Files + Súbory + + + Priority + Priorita + + + New url seed + New HTTP source + Nový HTTP zdroj + + + New url seed: + Nový URL seed: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + Tento URL seed je už v zozname. + + + Choose save path + Zvoľte cieľový adresár + + + Save path creation error + Chyba pri vytváraní cieľového adresára + + + Could not create the save path + Nepodarilo sa vytvoriť cieľový adresár + + + Downloaded: + Stiahnuté: + + + Transfer + Prenos + + + Uploaded: + Nahrané: + + + Wasted: + Premrhané: + + + UP limit: + Limit nahr.: + + + DL limit: + Limit sťah.: + + + Time elapsed: + Uplynulý čas: + + + Connections: + Spojení: + + + Information + Informácie + + + Created on: + Vytvorené: + + + Peers + Rovesníkov + + + Normal + Normálna + + + Maximum + Maximálna + + + High + Vysoká + + + this session + táto relácia + + + %1 max + e.g. 10 max + max. %1 + + + Availability: + Dostupnosť: + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seedovanie trvalo %1 + + + Comment: + Komentár: + + + Rename... + Premenovať... + + + New name: + Nový názov: + + + The file could not be renamed + Nebolo možné premenovať súbor + + + This name is already in use in this folder. Please use a different name. + Tento názov sa v tomto adresári už používa. Prosím, zvoľte iný názov. + + + The folder could not be renamed + Nebolo možné premenovať adresár + + + Rename the file + Premenovať súbor + + + This file name contains forbidden characters, please choose a different one. + Tento názov súboru obsahuje nepovolené znaky, preto zvoľte iný. + + + I/O Error + V/V chyba + + + This file does not exist yet. + Tento súbor zatiaľ neexistuje. + + + This folder does not exist yet. + Tento priečinok zatiaľ neexistuje. + + + Reannounce in: + Znova ohlásiť o: + + + Select All + Vybrať všetky + + + Select None + Nevybrať nič + + + Do not download + Nesťahovať + + + Pieces size: + Veľkosť častí: + + + Time active: + Time (duration) the torrent is active (not paused) + Čas aktivity: + + + Torrent content: + Obsah torrentu: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1 dosiahol maximálny požadovaný pomer. + + + Removing torrent %1... + Odstraňuje sa torrent %1... + + + Pausing torrent %1... + Pozastavuje sa torrent %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent sa viaže na port: TCP/%1 + + + UPnP support [ON] + Podpora UPnP [zapnutá] + + + UPnP support [OFF] + Podpora UPnP [vypnutá] + + + NAT-PMP support [ON] + Podpora NAT-PMP [zapnutá] + + + NAT-PMP support [OFF] + Podpora NAT-PMP [vypnutá] + + + HTTP user agent is %1 + HTTP user agent je %1 + + + Using a disk cache size of %1 MiB + Používa sa veľkosť diskovej vyrovnávacej pamäte %1 MiB + + + DHT support [ON], port: UDP/%1 + Podpora DHT [ZAP], port: UDP/%1 + + + DHT support [OFF] + Podpora DHT [vypnutá] + + + PeX support [ON] + Podpora PeX [zapnutá] + + + PeX support [OFF] + Podpora PeX [VYP] + + + Restart is required to toggle PeX support + Na prepnutie podpory PeX je potrebný reštart + + + Local Peer Discovery [ON] + Local Peer Discovery [zapnutá] + + + Local Peer Discovery support [OFF] + Podpora Local Peer Discovery support [vypnutá] + + + Encryption support [ON] + Podpora šifrovania [zapnuté] + + + Encryption support [FORCED] + Podpora šifrovania [vynútené] + + + Encryption support [OFF] + Podpora šifrovania [vypnuté] + + + Embedded Tracker [ON] + Zabudovaný tracker [zapnuté] + + + Failed to start the embedded tracker! + Nepodarilo sa spustiť zabudovaný tracker! + + + Embedded Tracker [OFF] + Zabudovaný tracker [vypnuté] + + + The Web UI is listening on port %1 + Webové rozhranie počúva na porte %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Chyba webového rozhrania - nepodaril sa bind webového rozhrania na port %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + „%1“ bol odstránený zo zoznamu sťahovaných a z pevného disku. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + „%1“ bol odstránený zo zoznamu sťahovaných. + + + '%1' is not a valid magnet URI. + „%1“ nie je platný magnet URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + „%1“ sa už nachádza v zozname sťahovaných. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + „%1“ bol obnovený. (rýchle obnovenie) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + „%1“ bol pridaný do zoznamu na sťahovanie. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Nepodarilo sa dekódovať torrent súbor: „%1“ + + + This file is either corrupted or this isn't a torrent. + Tento súbor je buď poškodený alebo to nie je torrent. + + + Error: The torrent %1 does not contain any file. + Chyba: Torrent %1 neobsahuje žiaden súbor. + + + Note: new trackers were added to the existing torrent. + Pozn.: Do existujúceho torrentu boli pridané nové trackery. + + + Note: new URL seeds were added to the existing torrent. + Pozn.: Do existujúceho torrentu boli pridané nové URL seedy. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>zablokoval váš filter IP adries</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>zablokovaný kvôli posielaniu poškodených častí</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekurzívne sťahovanie súboru %1 vnoreného v torrente %2 + + + Unable to decode %1 torrent file. + Nepodarilo sa dekódovať torrent súbor %1. + + + Torrent name: %1 + Názov torrentu: %1 + + + Torrent size: %1 + Veľkosť torrentu: %1 + + + Save path: %1 + Uložiť do: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent bol stiahnutý za %1. + + + Thank you for using qBittorrent. + Ďakujeme, že používate qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] sťahovanie %1 bolo dokončené + + + An I/O error occured, '%1' paused. + Vyskytla sa V/V chyba, „%1“ pozastavené. + + + Reason: %1 + Dôvod: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Zlyhanie mapovania portov, správa: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Mapovanie portov úspešné, správa: %1 + + + File sizes mismatch for torrent %1, pausing it. + Veľkosti súborov sa líšia pri torrente %1, pozastavuje sa. + + + Fast resume data was rejected for torrent %1, checking again... + Rýchle obnovenie torrentu %1 bolo odmietnuté, prebieha opätovná kontrola... + + + Url seed lookup failed for url: %1, message: %2 + Vyhľadanie url seedu zlyhalo pre url: %1, správa: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Prebieha sťahovanie „%1“, čakajte prosím... + + + The network interface defined is invalid: %1 + Definované sieťové rozhranie je neplatné: %1 + + + Trying any other network interface available instead. + Namiesto toho sa skúša ľubovoľné iné sieťové rozhranie. + + + Listening on IP address %1 on network interface %2... + Počúva sa na IP adrese %1 na sieťovom rozhraní %2... + + + Failed to listen on network interface %1 + Nepodarilo sa spustiť počúvanie na sieťovom rozhraní %1 + + + UPnP / NAT-PMP support [ON] + Podpora UPnP/NAT-PMP [zapnutá] + + + UPnP / NAT-PMP support [OFF] + Podpora UPnP/NAT-PMP [vypnutá] + + + Local Peer Discovery support [ON] + Podpora Local Peer Discovery [zapnutá] + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Poskytnutý filter IP úspešne spracovaný: %1 pravidiel bolo použitých. + + + Error: Failed to parse the provided IP filter. + Chyba: Nepodarilo sa spracovať poskytnutý filter IP. + + + Reporting IP address %1 to trackers... + Trackerom sa oznamuje IP adresa %1... + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Počítač prejde do režimu spánku ak to nezrušíte do 15 sekúnd odteraz... + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Počítač sa vypne ak to nezrušíte do 15 sekúnd odteraz... + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent sa ukončí ak to nezrušíte do 15 sekúnd odteraz... + + + + RSS + + Search + Vyhľadávanie + + + Refresh RSS streams + Obnoviť RSS streamy + + + Delete + Zmazať + + + Rename + Premenovať + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrenty:</span> <span style=" font-style:italic;">(stiahnite dvojitým kliknutím)</span></p></body></html> + + + Download torrent + Stiahnuť torrent + + + Open news URL + Otvoriť URL kanála + + + Copy feed URL + Skopírovať URL kanála + + + New subscription + Nové predplatné + + + Mark items read + Označiť položku ako prečítané + + + Update all + Aktualizovať všetky + + + Update all feeds + Aktualizovať všetky kanálu + + + RSS feeds + RSS kanály + + + + Update + Aktualizovať + + + Feed URL + URL kanála + + + Article title + Názov článku + + + Rename... + Premenovať... + + + New subscription... + Nový odber... + + + RSS feed downloader... + Sťahovanie RSS kanálov... + + + New folder... + Nový priečinok ... + + + Manage cookies... + Správa cookies... + + + Settings... + Nastavenia... + + + RSS Downloader... + Sťahovanie RSS kanálov... + + + + RSSImp + + Are you sure? -- qBittorrent + Ste si istý? -- qBittorrent + + + &Yes + &Áno + + + &No + &Nie + + + Please type a rss stream url + Prosím, napíšte URL RSS streamu + + + Stream URL: + URL streamu: + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + Tento RSS kanál už je v zozname. + + + Date: + Dátum: + + + Author: + Autor: + + + Please choose a folder name + Prosím, vyberte názov priečinka + + + Folder name: + Názov priečinka: + + + New folder + Nový priečinok + + + Are you sure you want to delete these elements from the list? + Ste si istý, že chcete zmazať tieto prvky zo zoznamu? + + + Are you sure you want to delete this element from the list? + Ste si istý, že chcete zmazať tento prvok zo zoznamu? + + + Please choose a new name for this RSS feed + Prosím, vyberte nový názov pre tento RSS kanál + + + New feed name: + Nový názov kanála: + + + Name already in use + Názov sa už používa + + + This name is already used by another item, please choose another one. + Tento názov už používa iná položka. Prosím, zvoľte iný názov. + + + Overwrite attempt + Pokus o prepísanie + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Nemôžete prepísať položku %1. + + + Unread + Neprečítané + + + + RssArticle + + No description available + Popis nie je dostupný + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + Automaticky sa sťahuje torrent %1 z RSS kanála %2... + + + + RssItem + + No description available + Popis nie je dostupný + + + + RssSettings + + RSS Reader Settings + Nastavenia čítačky RSS + + + RSS feeds refresh interval: + Interval obnovovania RSS kanálov: + + + minutes + minút + + + Maximum number of articles per feed: + Maximálny počet článkov na kanál: + + + + RssSettingsDlg + + RSS Reader Settings + Nastavenia čítačky RSS + + + RSS feeds refresh interval: + Interval obnovovania RSS kanálov: + + + minutes + minút + + + Maximum number of articles per feed: + Maximálny počet článkov na kanál: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Automaticky sa sťahuje torrent %1 z RSS kanála %2... + + + + ScanFoldersModel + + Watched Folder + Sledovaný priečinok + + + Download here + Stiahnuť sem + + + + SearchCategories + + All categories + Všetky kategórie + + + Movies + Filmy + + + TV shows + TV relácie + + + Music + Hudba + + + Games + Hry + + + Anime + Anime + + + Software + Softvér + + + Pictures + Obrázky + + + Books + Knihy + + + + SearchEngine + + Empty search pattern + Prázdny vyhľadávací vzor + + + Please type a search pattern first + Prosím, najprv zadajte vyhľadávací vzor + + + Results + Výsledky + + + Searching... + Hľadá sa... + + + Cut + Vystrihnúť + + + Copy + Kopírovať + + + Paste + Vložiť + + + Clear field + Vyčistiť pole + + + Clear completion history + Vyčistiť históriu dopĺňania + + + Search Engine + Vyhľadávač + + + Search has finished + Hľadanie skončené + + + An error occured during search... + Počas vyhľadávania sa vyskytla chyba... + + + Search aborted + Vyhľadávanie preušené + + + Search returned no results + Vyhľadávanie nevrátilo žiadne výsledky + + + Results + i.e: Search results + Výsledky + + + Unknown + Neznámy + + + Search + Vyhľadávanie + + + Download error + Chyba pri sťahovaní + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Nebolo možné stiahnuť inštalačný program Pythonu. Dôvod: %1 +Prosím, nainštalujte ho ručne. + + + Missing Python Interpreter + Chýbajúci interpreter Pythonu + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Na používanie vyhľadávača je potrebný Python 2.x, ale zdá sa, že nie je nainštalovaný. +Chcete ho nainštalovať teraz? + + + Confirmation + Potvrdenie + + + Are you sure you want to clear the history? + Ste si istý, že chcete vymazať históriu? + + + + SearchTab + + Name + i.e: file name + Názov + + + Size + i.e: file size + Veľkosť + + + Seeders + i.e: Number of full sources + Seederi + + + Leechers + i.e: Number of partial sources + Leecheri + + + Search engine + Vyhľadávač + + + + ShutdownConfirmDlg + + Shutdown confirmation + Potvrdenie vypnutia + + + + SpeedLimitDialog + + KiB/s + KiB/s + + + + StatusBar + + Connection status: + Stav spojenia: + + + No direct connections. This may indicate network configuration problems. + Žiadne priame spojenia. To môže znamenať problém s nastavením siete. + + + DHT: %1 nodes + DHT: %1 uzlov + + + Connection Status: + Stav spojenia: + + + Online + Online + + + Global Download Speed Limit + Globálne rýchlostné obmedzenie sťahovania + + + Global Upload Speed Limit + Globálne rýchlostné obmedzenie nahrávania + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Sťah.: %1/s - Pren.: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Nahr.: %1/s - Pren.: %2 + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + Sťah.: %1 B/s - Pren.: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + Nahr.: %1 B/s - Pren.: %2 + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Odpojený. To zvyčajne znamená, že qBittorrent nedokázal počúvať prichádzajúce spojenia na zvolenom porte. + + + Click to disable alternative speed limits + Kliknutím vypnete alternatívne globálne rýchlostné obmedzenia + + + Click to enable alternative speed limits + Kliknutím zapnete alternatívne globálne rýchlostné obmedzenia + + + qBittorrent needs to be restarted + Je potrebné reštartovať qBittorrent + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent bol práve aktualizovaný a je potrebné ho reštartovať, aby sa zmeny prejavili. + + + Click to switch to alternative speed limits + Kliknutím prepnete na alternatívne rýchlostné obmedzenia + + + Click to switch to regular speed limits + Kliknutím prepnete na bežné rýchlostné obmedzenia + + + %1/s + Per second + %1/s + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + Vyberte adresár, ktorý sa má pridať do torrentu + + + Select a file to add to the torrent + Vyberte súbor, ktorý sa má pridať do torrentu + + + Please type an announce URL + Prosím, napíšte announce URL + + + Announce URL: + Tracker URL + Announce URL: + + + Please type a web seed url + Prosím, napíšte web seed URL + + + Web seed URL: + Web seed URL: + + + No input path set + Nebola zadaná vstupná cesta + + + Please type an input path first + Napíšte prosím najprv vstupnú cestu + + + Select destination torrent file + Vybrať cieľový torrent súbor + + + Torrent Files + Torrent súbory + + + Torrent creation + Vytvorenie torrentu + + + Torrent creation was unsuccessful, reason: %1 + Torrent nebol vytvorený, dôvod: %1 + + + Created torrent file is invalid. It won't be added to download list. + Vytvorený torrent je neplatný. Nebude pridaný do zoznamu sťahovaných. + + + Torrent was created successfully: + Torrent bol úspešne vytvorený: + + + + TorrentFilesModel + + Name + Názov + + + Size + Veľkosť + + + Progress + Priebeh + + + Priority + Priorita + + + + TorrentImportDlg + + Torrent Import + Importovať torrent + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Asistent vám teraz pomôže zdieľať pomocou qBittorrentu torrent, ktorý ste už stiahli. + + + Torrent file to import: + Importovať torrent: + + + ... + ... + + + Content location: + Umiestnenie obsahu: + + + Skip the data checking stage and start seeding immediately + Preskočiť kontrolu súborov a začať seedovať okamžite + + + Import + Importovať + + + Torrent file to import + Importovať torrent + + + Torrent files (*.torrent) + Torrent súbory (*.torrent) + + + %1 Files + %1 is a file extension (e.g. PDF) + Súbory %1 + + + Please provide the location of %1 + %1 is a file name + Prosím, napíšte umiestnenie %1 + + + Please point to the location of the torrent: %1 + Prosím, napíšte umiestnenie torrentu %1 + + + Invalid torrent file + Neplatný torrent + + + This is not a valid torrent file. + Toto nie je platný torrent. + + + + TorrentModel + + Name + i.e: torrent name + Názov + + + Size + i.e: torrent size + Veľkosť + + + Done + % Done + Hotovo + + + Status + Torrent status (e.g. downloading, seeding, paused) + Stav + + + Seeds + i.e. full sources (often untranslated) + Seedov + + + Peers + i.e. partial sources (often untranslated) + Rovesníkov + + + Down Speed + i.e: Download speed + Rýchlosť sťahovania + + + Up Speed + i.e: Upload speed + Rýchlosť nahrávania + + + Ratio + Share ratio + Pomer + + + ETA + i.e: Estimated Time of Arrival / Time left + Odhad. čas + + + Label + Označenie + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Pridané + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Dokončené + + + Tracker + Tracker + + + Down Limit + i.e: Download limit + Limit sťah. + + + Up Limit + i.e: Upload limit + Limit nahr. + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Stiahnuté + + + Amount left + Amount of data left to download (e.g. in MB) + Zostáva + + + Time Active + Time (duration) the torrent is active (not paused) + Čas aktivity + + + + TrackerList + + URL + URL + + + Status + Stav + + + Peers + Rovesníci + + + Message + Správa + + + [DHT] + [DHT] + + + Working + Pracuje sa + + + Disabled + Vypnuté + + + This torrent is private + Torrent je súkromný + + + Updating... + Prebieha aktualizácia... + + + Not working + Nefunguje + + + Not contacted yet + Zatiaľ nekontaktovaný + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Add a new tracker... + Pridať nový tracker... + + + Remove tracker + Odstrániť tracker + + + Force reannounce + Vynútiť opätovné ohlásenie + + + + TrackersAdditionDlg + + Trackers addition dialog + Dialóg pre pridanie torrentu + + + List of trackers to add (one per line): + Pridať nasledovné trackery (jeden tracker na riadok): + + + µTorrent compatible list URL: + Zoznam URL kompatibilný s µTorrent: + + + I/O Error + V/V Chyba + + + Error while trying to open the downloaded file. + Chyba počas pokusu otvoriť stiahnutý súbor. + + + No change + Bez zmeny + + + No additional trackers were found. + Neboli nájdené žiadne ďalšie trackery. + + + Download error + Chyba pri sťahovaní + + + The trackers list could not be downloaded, reason: %1 + Trackery nebolo možné stiahnuť. Dôvod: %1 + + + + TransferListDelegate + + Downloading + Sťahuje sa + + + Paused + Pozastavený + + + Queued + i.e. torrent is queued + Vo fronte + + + Seeding + Torrent is complete and in upload-only mode + Seeduje sa + + + Stalled + Torrent is waiting for download to begin + Bez pohybu + + + Checking + Torrent local data is being checked + + + + /s + /second (.i.e per second) + /s + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + Seeded for %1 + e.g. Seeded for 3m10s + Seedovanie trvalo %1 + + + + TransferListFiltersWidget + + All + Všetky + + + Downloading + Sťahované + + + Completed + Dokončené + + + Active + Aktívne + + + Inactive + Neaktívne + + + All labels + Všetky označenia + + + Unlabeled + Bez označenia + + + Remove label + Odstrániť označenie + + + New Label + Nové označenie + + + Label: + Označenie: + + + Invalid label name + Neplatný názov označenia + + + Please don't use any special characters in the label name. + Prosím, nepoužívajte v názve označenia špeciálne znaky. + + + Paused + Pozastavený + + + Add label... + Pridať označenie... + + + Resume torrents + Pokračovať v torrentoch + + + Pause torrents + Pozastaviť torrenty + + + Delete torrents + Zmazať torrenty + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + Odhad. čas + + + Column visibility + Viditeľnosť stĺpca + + + Open destination folder + Otvoriť cieľový priečinok + + + Force recheck + Vynútiť opätovnú kontrolu + + + Copy magnet link + Kopírovať magnet URI + + + Down Speed + i.e: Download speed + Rýchlosť sťahovania + + + Up Speed + i.e: Upload speed + Rýchlosť nahrávania + + + Name + i.e: torrent name + Názov + + + Size + i.e: torrent size + Veľkosť + + + Done + % Done + Hotovo + + + Status + Torrent status (e.g. downloading, seeding, paused) + Stav + + + Seeds + i.e. full sources (often untranslated) + Seedy + + + Peers + i.e. partial sources (often untranslated) + Rovesníci + + + Ratio + Share ratio + Pomer + + + Torrent Download Speed Limiting + Obmedzenie rýchlosti sťahovania torrentu + + + Torrent Upload Speed Limiting + Obmedzenie rýchlosti nahrávania torrentu + + + Super seeding mode + Režim super seedovania + + + Download in sequential order + Sťahovať v poradí + + + Download first and last piece first + Sťahovať najprv prvú a poslednú časť + + + Label + Označenie + + + New Label + Nové označenie + + + Label: + Označenie: + + + New... + New label... + Nové... + + + Reset + Reset label + Vrátiť + + + Rename + Premenovať + + + New name: + Nový názov: + + + Rename... + Premenovať... + + + Invalid label name + Neplatný názov označenia + + + Please don't use any special characters in the label name. + Prosím, nepoužívajte v názve označenia špeciálne znaky. + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Pridané + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Dokončené + + + Down Limit + i.e: Download limit + Limit sťah. + + + Up Limit + i.e: Upload limit + Limit nahr. + + + Choose save path + Zvoľte cieľový adresár + + + Save path creation error + Chyba pri vytváraní cieľového adresára + + + Could not create the save path + Nepodarilo sa vytvoriť cieľový adresár + + + Set location... + Nastaviť cieľ... + + + Preview file... + Náhľad súboru... + + + Limit upload rate... + Obmedziť rýchlosť nahrávania... + + + Limit download rate... + Obmedziť rýchlosť sťahovania... + + + Move up + i.e. move up in the queue + Presunúť vyššie + + + Move down + i.e. Move down in the queue + Presunúť nižšie + + + Move to top + i.e. Move to top of the queue + Presunúť navrch + + + Move to bottom + i.e. Move to bottom of the queue + Presunúť na spodok + + + Priority + Priorita + + + Resume + Resume/start the torrent + Pokračovať + + + Pause + Pause the torrent + Pozastaviť + + + Delete + Delete the torrent + Zmazať + + + Limit share ratio... + Obmedzenie pomeru zdieľania... + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + Obmedzenie pomeru odoslaných/stiahnutých dát torrentu + + + Use global ratio limit + Použiť globálne obmedzenie pomeru + + + buttonGroup + buttonGroup + + + Set no ratio limit + Bez obmedzenia pomeru + + + Set ratio limit to + Nastaviť obmedzenie pomeru na + + + + UsageDisplay + + Usage: + Použitie: + + + displays program version + zobrazí verziu programu + + + disable splash screen + vypnúť štartovaciu obrazovku + + + displays this help message + zobrazí túto správu Pomocníka + + + changes the webui port (current: %1) + zmení port webového rozhrania (momentálne: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [súbory alebo URL]: stiahne uvedené torrenty (nepovinné) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + Rád by som poďakoval nasledovným dobrovoľníkom, ktorí preložili qBittorrent: + + + Please contact me if you would like to translate qBittorrent into your own language. + Prosím, kontaktujte ma ak chcete preložiť qBittorrent do vášho jazyka. + + + + addPeerDialog + + Peer addition + Pridanie rovesníka + + + IP + IP + + + Port + Port + + + + addTorrentDialog + + Torrent addition dialog + Dialóg pre pridanie torrentu + + + Save path: + Uložiť kam: + + + ... + ... + + + Torrent content: + Obsah torrentu: + + + Add to download list in paused state + Pridať do zoznamu sťahovaných v stave pozastavený + + + Add + Pridať + + + Cancel + Storno + + + Normal + Normálna + + + High + Vysoká + + + Maximum + Maximálna + + + Torrent size: + Veľkosť torrentu: + + + Unknown + Neznáma + + + Free disk space: + Voľné miesto na disku: + + + Download in sequential order (slower but good for previewing) + Sťahovať v postupnom poradí (pomalšie, ale lepšie pre náhľady) + + + Skip file checking and start seeding immediately + Preskočiť kontrolu súborov a začať seedovať okamžite + + + Label: + Označenie: + + + Select All + Vybrať všetky + + + Select None + Nevybrať nič + + + Do not download + Nesťahovať + + + + authentication + + Tracker authentication + Autentifikácia trackera + + + Tracker: + Tracker: + + + Login + Prihlásenie + + + Username: + Meno používateľa: + + + Password: + Heslo: + + + Log in + Prihásiť sa + + + Cancel + Storno + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + Potvrdenie zmazania - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + Ste s istý, že chcete zmazať vybrané torrenty zo zoznamu prenosov? + + + Remember choice + Pamätať si vyrovnávaciu pamäť + + + Also delete the files on the hard disk + Zmazať aj súbory na pevnom disku + + + + createTorrentDialog + + Cancel + Storno + + + Torrent Creation Tool + Nástroj na vytvorenie Torrentu + + + Torrent file creation + Vytvorenie Torrent súboru + + + Announce urls (trackers): + Announce url (trackery): + + + Comment (optional): + Komentár (voliteľné): + + + Web seeds urls (optional): + URL web seedov (voliteľné): + + + File or folder to add to the torrent: + Súbor alebo priečinok, ktorý sa má pridať do torrentu: + + + Piece size: + Veľkosť časti: + + + 32 KiB + 32 KiB + + + 64 KiB + 64 KiB + + + 128 KiB + 128 KiB + + + 256 KiB + 256 KiB + + + 512 KiB + 512 KiB + + + 1 MiB + 1 MiB + + + 2 MiB + 2 MiB + + + 4 MiB + 4 MiB + + + Private (won't be distributed on DHT network if enabled) + Súkromný (ak je zapnuté, nebude sa šíriť pomocou siete DHT) + + + Start seeding after creation + Začať seedovanie po vytvorení + + + Create and save... + Vytvoriť a uložiť... + + + Progress: + Priebeh: + + + Add file + Pridať súbor + + + Add folder + Pridať priečinok + + + Tracker URLs: + URL trackera: + + + Web seeds urls: + URL web seedov: + + + Comment: + Komentár: + + + Auto + Auto + + + + createtorrent + + Select destination torrent file + Vybrať cieľový torrent súbor + + + Torrent Files + Torrent súbory + + + No input path set + Nebola zadaná vstupná cesta + + + Please type an input path first + Napíšte prosím najprv vstupnú cestu + + + Torrent creation + Vytvorenie torrentu + + + Torrent was created successfully: + Torrent bol úspešne vytvorený: + + + Select a folder to add to the torrent + Vyberte adresár, ktorý sa má pridať do torrentu + + + Please type an announce URL + Prosím, napíšte announce URL + + + Torrent creation was unsuccessful, reason: %1 + Torrent nebol vytvorený, dôvod: %1 + + + Announce URL: + Tracker URL + Announce URL: + + + Please type a web seed url + Prosím, napíšte web seed URL + + + Web seed URL: + Web seed URL: + + + Select a file to add to the torrent + Vyberte súbor, ktorý sa má pridať do torrentu + + + Created torrent file is invalid. It won't be added to download list. + Vytvorený torrent je neplatný. Nebude pridaný do zoznamu sťahovaných. + + + + downloadFromURL + + Download from urls + Stiahnuť z viacerých url + + + Download Torrents from URLs + Stiahnuť torrenty z viacerých URL + + + Only one URL per line + Iba jeden URL na riadok + + + Download + Stiahnuť + + + Cancel + Storno + + + No URL entered + Nebolo zadané URL + + + Please type at least one URL. + Prosím, napíšte aspoň jedno URL. + + + Add torrent links + Pridať odkazy na torrent + + + Both HTTP and Magnet links are supported + Sú podporované odkazy HTTP aj Magnet + + + + downloadThread + + I/O Error + V/V Chyba + + + The remote host name was not found (invalid hostname) + Názov vzdialeného počítača nebol zistený (neplatný názov) + + + The operation was canceled + Operácia bola zrušená + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Vzdialený server predčasne zatvoril spojenie predtým, než bola prijatá a spracovaná celá odpoveď + + + The connection to the remote server timed out + Čas spojenia so vzdialeným serverom vypršal + + + SSL/TLS handshake failed + SSL/TLS handshake zlyhal + + + The remote server refused the connection + Vzdialený server odmietol spojenie + + + The connection to the proxy server was refused + Spojenie s proxy serverom bolo odmietnuté + + + The proxy server closed the connection prematurely + Proxy server predčasne zatvoril spojenie + + + The proxy host name was not found + Názov proxy servera nebol nájdený + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Čas spojenia s proxy serverom vypršal alebo proxy server neodpovedal včas na zaslanú požiadavku + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Proxy vyžaduje autentifikáciu aby mohol splniť požiadavku, ale neprijal žiadne z ponúknutých prihlasovacích údajov + + + The access to the remote content was denied (401) + Prístup k vzdialenému obsahu bol zamietnutý (401) + + + The operation requested on the remote content is not permitted + Požadovaná operácia so vzdialeným obsahom nie je povolená + + + The remote content was not found at the server (404) + Vzdialený obsah nebol nájdený na serveri (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Vzdialený server vyžaduje na poskytnutie obsahu autentifikáciu, , ale neprijal žiadne z ponúknutých prihlasovacích údajov + + + The Network Access API cannot honor the request because the protocol is not known + Network Access API neprijalo požiadavku, pretože nie je známy protokol + + + The requested operation is invalid for this protocol + Požadovaná operácia nie je platná pre tento protokol + + + An unknown network-related error was detected + Bola zistená neznáma chyba týkajúca sa siete + + + An unknown proxy-related error was detected + Bola zistená neznáma chyba týkajúca sa proxy + + + An unknown error related to the remote content was detected + Bola zistená neznáma chyba týkajúca sa vzdialeného obsahu + + + A breakdown in protocol was detected + Bola zistená porucha v protokole + + + Unknown error + Neznáma chyba + + + + engineSelect + + Search plugins + Zásuvné moduly vyhľadávania + + + Installed search engines: + Nainštalované vyhľadávače: + + + Name + Názov + + + Url + Url + + + Enabled + Zapnuté + + + Install a new one + Nainštalovať nový + + + Check for updates + Skontrolovať aktualizácie + + + Close + Zatvoriť + + + Enable + Zapnúť + + + Disable + Vypnúť + + + Uninstall + Odinštalovať + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Nové zásuvné moduly vyhľadávačov nájdete tu: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + engineSelectDlg + + Uninstall warning + Upozornenie o odstránení + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Niektoré zásuvné moduly nebolo možné odstrániť, pretože sú súčasťou aplikácie qBittorrent. + Iba tie, ktoré ste sami pridali je možné odstrániť. +Tieto moduly však boli vypnuté. + + + Uninstall success + Odstránenie prebehlo úspešne + + + Select search plugins + Zvoliť zásuvné moduly vyhľadávačov + + + qBittorrent search plugins + Zásuvné moduly vyhľadávania qBittorrent + + + Search plugin install + Inštalácia zásuvného modulu vyhľadávača + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Novšia verzia zásuvného modulu vyhľadávača %1 je už nainštalovaná. + + + Search plugin update + Aktualizácia zásuvného modulu vyhľadávača + + + Sorry, update server is temporarily unavailable. + Je mi ľúto, aktualizačný server je dočasne nedostupný. + + + All your plugins are already up to date. + Všetky vaše vyhľadávacie zásuvné moduly sú už aktuálne. + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + Zásuvný modul vyhľadávača %1 nebolo možné aktualizovať, zachovávam starú verziu. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Zásuvný modul vyhľadávača %1 nebolo možné nainštalovať. + + + All selected plugins were uninstalled successfully + Všetky zvolené zásuvné moduly boli úspešne odinštalované + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + Zásuvný modul vyhľadávača %1 bol úspešne aktualizovaný. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Zásuvný modul vyhľadávača %1 bol úspešne nainštalovaný. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Je mi ľúto, aktualizácia zásuvného modulu vyhľadávača %1 zlyhala. + + + New search engine plugin URL + URL zásuvného modulu nového vyhľadávača + + + URL: + URL: + + + Yes + Áno + + + No + Nie + + + + misc + + Unknown + Neznámy + + + B + bytes + B + + + KiB + kibibytes (1024 bytes) + KiB + + + MiB + mebibytes (1024 kibibytes) + MiB + + + GiB + gibibytes (1024 mibibytes) + GiB + + + TiB + tebibytes (1024 gibibytes) + TiB + + + Unknown + Unknown (size) + Neznáma + + + < 1m + < 1 minute + < 1m + + + %1m + e.g: 10minutes + %1m + + + %1h %2m + e.g: 3hours 5minutes + %1h %2m + + + %1d %2h + e.g: 2days 10hours + %1d %2h + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent teraz vypne počítač, pretože sťahovanie všetkých torrentov bolo dokončené. + + + + options_imp + + Choose a save directory + Vyberte adresár, kde sa bude ukladať + + + Choose an ip filter file + Zvoliť súbor IP filtra + + + Filters + Filtre + + + Choose export directory + Vyberte adresár, kde sa bude exportovať + + + Add directory to scan + Vyberte adresár, ktorý sa bude prehliadať + + + Folder is already being watched. + Priečinok sa už sleduje. + + + Folder does not exist. + Priečinok neexistuje. + + + Folder is not readable. + Priečinok nemožno prečítať. + + + Failure + Zlyhanie + + + Failed to add Scan Folder '%1': %2 + Nepodarilo sa pridať priečinok na prehľadanie: „%1“: %2 + + + Parsing error + Chyba pri spracovaní + + + Failed to parse the provided IP filter + Nepodarilo sa spracovať poskytnutý filter IP + + + Succesfully refreshed + Obnovenie prebehlo úspešne + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Poskytnutý filter IP úspešne spracovaný: %1 pravidiel bolo použitých. + + + Successfully refreshed + Úspešne obnovené + + + Invalid key + + + + This is not a valid SSL key. + + + + Invalid certificate + + + + This is not a valid SSL certificate. + + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + + pluginSourceDlg + + Plugin source + Zdroj zásuvného modulu + + + Search plugin source: + Zdroj zásuvného modulu vyhľadávača: + + + Local file + Lokálny súbor + + + Web link + Webový odkaz + + + + preview + + Preview selection + Výber náhľadu + + + File preview + Náhľad súboru + + + The following files support previewing, <br>please select one of them: + Nasledujúce súbory podporujú náhľad, <br>prosím vyberte jeden z nich: + + + Preview + Náhľad + + + Cancel + Storno + + + + previewSelect + + Preview impossible + Náhľad nemožný + + + Sorry, we can't preview this file + Prepáčte, tento súbor sa nedá otvoriť ako náhľad + + + Name + Názov + + + Size + Veľkosť + + + Progress + Priebeh + + + + search_engine + + Search + Vyhľadávanie + + + Status: + Stav: + + + Stopped + Zastavený + + + Download + Stiahnuť + + + Search engines... + Vyhľadávače... + + + Go to description page + Prejsť na stránku popisu + + + + torrentAdditionDialog + + Unable to decode torrent file: + Nemohol som dekódovať torrent súbor: + + + Choose save path + Zvoľte cestu pre uloženie + + + Empty save path + Prázdna cesta pre uloženie + + + Please enter a save path + Prosím, zadajte cestu pre uloženie + + + Save path creation error + Chyba pri vytváraní cesty pre uloženie + + + Could not create the save path + Nemohol som vytvoriť cestu pre uloženie + + + Invalid file selection + Neplatný výber súboru + + + You must select at least one file in the torrent + Musíte vybrať aspoň jeden súbor z torrentu + + + Priority + Priorita + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (po stiahnutí torrentu zostane %1) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (na stiahnutie treba ďalších %1) + + + Seeding mode error + Chyba režimu seedovania + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Rozhodli ste sa preskočiť kontrolu súborov. Zdá sa však, že lokálne súbory neexistujú v aktuálnom cieľovom priečinku torrentu. Prosím, vypnite túto možnosť alebo aktualizujte cieľovú cestu. + + + Rename... + Premenovať... + + + New name: + Nový názov: + + + The file could not be renamed + Nepodarilo sa premenovať súbor + + + This name is already in use in this folder. Please use a different name. + Tento názov už používa iná položka. Prosím, zvoľte iný názov. + + + The folder could not be renamed + Nepodarilo sa premenovať adresár + + + Rename the file + Premenovať súbor + + + Unable to decode magnet link: + Nepodarilo sa dekódovať odkaz Magnet: + + + Magnet Link + Odkaz Magnet + + + Invalid label name + Neplatný názov označenia + + + Please don't use any special characters in the label name. + Prosím, nepoužívajte v názve označenia špeciálne znaky. + + + This file name contains forbidden characters, please choose a different one. + Tento názov súboru obsahuje nepovolené znaky, preto zvoľte iný. + + + diff --git a/src/lang/qbittorrent_sr.qm b/src/lang/qbittorrent_sr.qm new file mode 100644 index 0000000000000000000000000000000000000000..e67246e24e7ccb66da557fba1e8480fa227b3549 GIT binary patch literal 118806 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 C+TpeU literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_sr.ts b/src/lang/qbittorrent_sr.ts new file mode 100644 index 000000000..d5ecb42f9 --- /dev/null +++ b/src/lang/qbittorrent_sr.ts @@ -0,0 +1,5800 @@ + + + + + AboutDlg + + About qBittorrent + O qBittorrent-у + + + About + О програму + + + Author + Аутор + + + Name: + Име: + + + Country: + Земља: + + + E-mail: + Електронска-пошта: + + + Christophe Dumez + Christophe Dumez + + + France + Француска + + + Translation + by Anaximandar + Превод + + + License + Лиценца + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + chris@qbittorrent.org + chris@qbittorrent.org + + + Thanks to + Хвала на + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Бит-торен клијент програмиран у C++, базиран на Qt4 програмском алату </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">и libtorrent-rasterbar-у. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Напредни Бит-торен клијент програмиран у C++, базиран на Qt4 програмском алату и libtorrent-rasterbar-у. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + AdvancedSettings + + Property + Својства + + + Value + Вредност + + + Disk write cache size + Величина кеша Диска + + + MiB + MiB + + + Outgoing ports (Min) [0: Disabled] + Одлазних портова (Min) [0: Искључено] + + + Outgoing ports (Max) [0: Disabled] + Одлазних портова (Max) [0: Искључено] + + + Recheck torrents on completion + Провери торенте на завршетку + + + Transfer list refresh interval + Трансфер листа интервал освежавања + + + ms + milliseconds + милисекунди + ms + + + Resolve peer countries (GeoIP) + Одреди земљу peer-а (учесника) (GeoIP) + + + Resolve peer host names + Одреди име хоста peer-а (учесника) + + + Ignore transfer limits on local network + Игнориши ограничење преноса на локалној мрежи + + + Include TCP/IP overhead in transfer limits + Укључи TCP/IP прекорачење при ограничењу преноса + + + Maximum number of half-open connections [0: Disabled] + Максимални број полу-отворених конекција [0: Онемогућено] + + + Strict super seeding + донирање-seeding + Искључиво супер донирање (seeding) + + + Network Interface (requires restart) + Мрежни интерфејс (захтева рестарт) + + + Any interface + i.e. Any network interface + Било који мрежни интерфејс + + + Display program notification baloons + Прикажи балоне са програмским коментарима + + + Display program notification balloons + Прикажи балоне са програмским коментарима + + + Enable embedded tracker + Омогући уграђени пратилац + + + Embedded tracker port + Уграђени пратилац порта + + + Check for software updates + Проверите за надоградњу софтвера + + + Use system icon theme + Користи тему системских икона + + + Confirm torrent deletion + Потврда брисања торента + + + IP Address to report to trackers (requires restart) + IP адресни извештај о пратиоцима (захтева рестарт) + + + Display program on-screen notifications + Прикажи програмска обавештења на екрану + + + Setting + Подешавање + + + Value + Value set for this setting + Вредност + + + Exchange trackers with other peers + Размена претилаца са осталим учесницима + + + + AutomatedRssDownloader + + Automated RSS Downloader + Аутоматизовани RSS преузимач + + + Enable the automated RSS downloader + Омогући аутоматско преузимање RSS порука + + + Download rules + Правила преузимања + + + Rule definition + Дефинисање правила + + + Must contain: + Мора да садржи: + + + Must not contain: + Не треба да садржи: + + + ... + ... + + + Assign label: + Додели ознаку: + + + Apply rule to feeds: + feeds-поруке;фидови;канали + Примени правило на поруке: + + + Matching RSS articles + Усклађивање RSS чланака + + + Save to a different directory + Сачувај у другом директоријуму + + + Save to: + Сачувај у: + + + Import... + Увези... + + + Export... + Извези... + + + New rule name + Назив новог правила + + + Please type the name of the new download rule. + Молим упишите назив новог правила преузимања. + + + Rule name conflict + Конфликт у називу правила + + + A rule with this name already exists, please choose another name. + Правило са овим називом већ постоји, молим изаберите неки други назив. + + + Are you sure you want to remove the download rule named %1? + Да ли сте сигурни да желите да уклоните правило преузимања назива %1? + + + Are you sure you want to remove the selected download rules? + Да ли сте сигурни да желите да уклоните изабрана правила преузимања? + + + Rule deletion confirmation + Потврда брисања - правила + + + Destination directory + Одредишни директоријум + + + Invalid action + Неважећа акција + + + The list is empty, there is nothing to export. + Листа је празна, не постоји ништа за извоз. + + + Where would you like to save the list? + Где желите да сачувате листу? + + + Rules list (*.rssrules) + Листа правила (*.rssrules) + + + I/O Error + И/О Грешка + + + Failed to create the destination file + Грешка при креирању циљне датотеке + + + Please point to the RSS download rules file + Молим укажите на RSS датотеку са правилима преузимања + + + Rules list (*.rssrules *.filters) + Листа правила (*.rssrules *.filters) + + + Import Error + Грешка при увозу + + + Failed to import the selected rules file + Грешка при увозу изабране датотеке са правилима + + + Add new rule... + Додај ново правило... + + + Delete rule + Обриши правило + + + Rename rule... + Преименуј правило... + + + Delete selected rules + Обриши изабрана правила + + + Rule renaming + Преименовање правила + + + Please type the new rule name + Молим упишите назив за ново правило + + + Use regular expressions + Користите регуларне изразе + + + Regex mode: use Perl-like regular expressions + Regex мод: користи слично Perl-у регуларне изразе + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Џокер мод: можете користити<ul><li>? да представља било који појединачни карактер</li><li>* да представља нулу или било које друге карактере</li><li>Размак број као AND операторе</li></ul> + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Џокер мод: можете користити<ul><li>? да представља било који појединачни карактер</li><li>* да представља нулу или било које друге карактере</li><li>| се користи као OR оператор</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 достигао је максимални ниво који сте подесили. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + н.пр.: qBittorrent је повезан на порт: 6881 + qBittorrent је повезан на порт: TCP/%1 + + + UPnP support [ON] + UPnP подршка [Укључена] + + + UPnP support [OFF] + UPnP подршка [Искључена] + + + NAT-PMP support [ON] + NAT-PMP подршка [Укључена] + + + NAT-PMP support [OFF] + NAT-PMP подршка [Искључена] + + + HTTP user agent is %1 + HTTP кориснички агент је %1 + + + Using a disk cache size of %1 MiB + Користи кеш диска величине %1 MiB + + + DHT support [ON], port: UDP/%1 + DHT подршка [Укључена], порт: UDP/%1 + + + DHT support [OFF] + DHT подршка [Искључена] + + + PeX support [ON] + PeX подршка [Укључена] + + + PeX support [OFF] + PeX подршка [Искључена] + + + Restart is required to toggle PeX support + Рестарт је потребан за укључивање PeX подршке + + + Local Peer Discovery [ON] + Peer-Учесник + Претраживање локалних веза [Укључено] + + + Local Peer Discovery support [OFF] + Peer-Учесник + Претраживање локалних веза подршка [Искључено] + + + Encryption support [ON] + Шифровање подршка [Укључена] + + + Encryption support [FORCED] + Шифровање подршка [Форсирано] + + + Encryption support [OFF] + Шифровање подршка [Искључена] + + + The Web UI is listening on port %1 + Веб КИ надгледа порт %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Веб Кориснички Интерфејс Грешка - Не могу да повежем Веб КИ на порт %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + 'xxx.avi' је уклоњен... + '%1' је уклоњен са трансфер листе и хард диска. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + 'xxx.avi' је уклоњен... + '%1' је уклоњен са трансфер листе. + + + '%1' is not a valid magnet URI. + '%1' није валидан магнет URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + н.пр.: 'xxx.avi' је већ на листи преузимања. + '%1' већ је додат на листу за преузимање. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '/home/y/xxx.torrent' је наставио. (брзи наставак) + '%1' настави. (брзо настави) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '/home/y/xxx.torrent' је додат на листу преузимања. + '%1' додат на листу за преузимање. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + н.пр.: Не може да декодира торент фајл: '/home/y/xxx.torrent' + Није у стању да декодира торент фајл: '%1' + + + This file is either corrupted or this isn't a torrent. + Овај фајл је оштећен или ово није торент. + + + Note: new trackers were added to the existing torrent. + Напомена: нови пратиоци су додати у постојећи торент. + + + Note: new URL seeds were added to the existing torrent. + Напомена: нови URL донори су додати у постојећи торент. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + x.y.z.w је блокиран + <font color='red'>%1</font> <i>је блокиран због вашег IP филтера</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + x.y.z.w је одбачен + <font color='red'>%1</font> <i>је одбачен због оштећених делова</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Поновно преузимање фајла %1 омогућено у торенту %2 + + + Unable to decode %1 torrent file. + Није у стању да декодира %1 торент фајл. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Порт мапирање грешка, порука: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Порт мапирање успешно, порука: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Брзи наставак података је одбијен за торент %1, покушајте поново... + + + Reason: %1 + Разлог: %1 + + + An I/O error occured, '%1' paused. + Нека И/О грешка се догодила, '%1' паузирано. + + + Url seed lookup failed for url: %1, message: %2 + Url преглед донора , грешка url: %1, порука: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + н.пр.: Преузимам 'xxx.torrent', молим сачекајте... + Преузимање '%1', молим сачекајте... + + + Removing torrent %1... + Уклањање торента %1... + + + Pausing torrent %1... + Паузирање торента %1... + + + Error: The torrent %1 does not contain any file. + Грешка: Торент %1 не садржи ни један фајл. + + + File sizes mismatch for torrent %1, pausing it. + Величина фајла није одговарајућа за торент %1, паузирајте га. + + + Torrent name: %1 + Име Торента: %1 + + + Torrent size: %1 + Величина Торента: %1 + + + Save path: %1 + Путања чувања: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Торент ће бити преузет за %1. + + + Thank you for using qBittorrent. + Хвала што користите qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 је завршио преузимање + + + + ConsoleDlg + + General + Опште + + + Blocked IPs + Блокирани IP-и + + + qBittorrent log viewer + qBittorrent преглед дневника + + + + CookiesDlg + + Cookies management + Управљање колачићима + + + Key + As in Key/Value pair + Кључ + + + Value + As in Key/Value pair + Вредност + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Уобичајени кључеви за колачиће су : '%1', '%2'. +Требало би да добијете ове информације из подешавања вашег Веб читача. + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + Ваш динамички DNS је успешно ажуриран. + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Динамички DNS грешка: сервис је привремено недоступан, биће проверено за 30 минута. + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Динамички DNS грешка: наведено име рачунара не постоји на специфираном налогу. + + + Dynamic DNS error: Invalid username/password. + Динамички DNS грешка: Погрешно корисничко име/лозинка. + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Динамички DNS грешка: qBittorrent је на црној листи сервиса, пријавите грешку на http://bugs.qbittorrent.org. + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Динамички DNS грешка: %1 је враћен од сервиса, пријавите грешку на http://bugs.qbittorrent.org. + + + Dynamic DNS error: Your username was blocked due to abuse. + Динамички DNS грешка: Ваше корисничко име је блокирано због злоупотребе. + + + Dynamic DNS error: supplied domain name is invalid. + Динамички DNS грешка: Наведено име домена је погрешно. + + + Dynamic DNS error: supplied username is too short. + Динамички DNS грешка: Наведено корисничко име је прекратко. + + + Dynamic DNS error: supplied password is too short. + Динамички DNS грешка: Наведена лозинка је прекратка. + + + + DownloadThread + + I/O Error + И/О Грешка + + + The remote host name was not found (invalid hostname) + Име удаљеног рачунара није пронађено (неисправно име рачунара) + + + The operation was canceled + Операција је отказана + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Удаљени сервер је прерано затворио конекцију, пре него што је цео одговор примљен и обрађен + + + The connection to the remote server timed out + Конекција на удаљени сервер је временски истекла (покушајте поново) + + + SSL/TLS handshake failed + SSL/TLS управљање неуспешно + + + The remote server refused the connection + Удаљени сервер не прихвата конекцију + + + The connection to the proxy server was refused + Конекција на прокси сервер је одбијена + + + The proxy server closed the connection prematurely + Прокси сервер је превремено затворио конекцију + + + The proxy host name was not found + Назив прокси сервера није пронађен + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Време повезивања са прокси-јем је истекло, или прокси није одговорио када је захтев послат + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Прокси захтева проверу идентитета да би испунио захтев али не прихвата понуђене акредитиве + + + The access to the remote content was denied (401) + Приступ удаљеном садржају је одбијен (401) + + + The operation requested on the remote content is not permitted + Захтевана операција за удаљеним садржајем се не одобрава + + + The remote content was not found at the server (404) + Захтевани садржај, није пронађен на серверу (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Удаљени сервер захтева ауторизацију за слање садржаја, али дати акредитиви нису прихваћени + + + The Network Access API cannot honor the request because the protocol is not known + Мрежни приступ API-ја не може да се прихвати јер протокол није познат + + + The requested operation is invalid for this protocol + Захтевана операција је погрешна за овај протокол + + + An unknown network-related error was detected + Детектована је непозната грешка у вези са мрежом + + + An unknown proxy-related error was detected + Детектована је непозната грешка у вези са проксијем + + + An unknown error related to the remote content was detected + Детектована је непозната грешка у вези са удаљеним садржајем + + + A breakdown in protocol was detected + Детектован је проблем са протоколом + + + Unknown error + Непозната грешка + + + + EventManager + + Working + Ради + + + Updating... + Ажурирање... + + + Not working + Не ради + + + Not contacted yet + Није још контактиран + + + this session + ова сесија + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Донирано за %1 + + + %1 max + e.g. 10 max + %1 max + + + %1/s + e.g. 120 KiB/s + н.пр. 120 KiB/s + %1/s + + + + ExecutionLog + + Form + Образац + + + General + Опште + + + Blocked IPs + Блокирани IP-и + + + + FeedDownloader + + RSS Feed downloader + Feed-допис,порука,канал + RSS преузимач Порука + + + RSS feed: + feed-допис,порука,канал + RSS допис: + + + Feed name + Feed-допис,порука,канал + Име поруке + + + Automatically download torrents from this feed + Аутоматски преузми торенте са ових дописа + + + Download filters + Преузимање филтера + + + Filters: + Филтери: + + + Filter settings + Подешавања филтера + + + Matches: + Усклађен: + + + Does not match: + Неусклађен: + + + Destination folder: + Одредишна фасцикла: + + + ... + ... + + + Filter testing + Тестирање филтера + + + Torrent title: + Име Торента (наслов): + + + Result: + Резултат: + + + Test + Тест + + + Import... + Увези... + + + Export... + Извези... + + + Rename filter + Преименуј филтер + + + Remove filter + Уклони филтер + + + Add filter + Додај филтер + + + + FeedDownloaderDlg + + New filter + Нови филтер + + + Please choose a name for this filter + Молим изаберите име за овај филтер + + + Filter name: + Име филтера: + + + Invalid filter name + Погрешно име филтера + + + The filter name cannot be left empty. + Име филтера не може бити празно. + + + This filter name is already in use. + Ово име филтера већ постоји. + + + Choose save path + Изаберите путању чувања + + + Filter testing error + Грешака тестирања филтера + + + Please specify a test torrent name. + Молим наведите неко тест име за торент. + + + matches + усклађен + + + does not match + неусклађен + + + Select file to import + Изаберите фајл за увоз + + + Filters Files + Филтер фајлови + + + Import successful + Увоз успешан + + + Filters import was successful. + Увоз филтера је успешан. + + + Import failure + Увоз погрешан + + + Filters could not be imported due to an I/O error. + Филтери не могу бити увежени због неке I/O грешке. + + + Select destination file + Изабери одредишни фајл + + + Export successful + Извоз успешан + + + Filters export was successful. + Филтери су извезени успешно. + + + Export failure + Извоз погрешан + + + Filters could not be exported due to an I/O error. + Филтери не могу бити извежени због неке I/O грешке. + + + + FeedList + + Unread + Непрочитане + + + + FeedListWidget + + RSS feeds + RSS поруке + + + Unread + Непрочитане + + + + GUI + + Open Torrent Files + Отвори Торент фајлове + + + Torrent Files + Торент Фајлови + + + qBittorrent %1 + e.g: qBittorrent v0.x + н.пр.: qBittorrent v0.x + qBittorrent %1 + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + н.пр.: Брзина преузимања: 10 KiB/s + ПР брзина: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + н.пр.: Брзина слања: 10 KiB/s + СЛ брзина: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + н.пр.: xxx.avi је завршио преузимање. + %1 је завршио преузимање. + + + I/O Error + i.e: Input/Output Error + н.пр.: Улазно/Излазна грешка + И/О Грешка + + + Search + Претраживање + + + RSS + RSS је породица веб формата који се користе за објављивање садржаја који се често мењају, као што су новински наслови. RSS документ садржи или сажетак садржаја са придружене веб стране, или читав текст. RSS вам омогућава да будете у току са изменама и новостима са неког веб сајта потпуно аутоматски, а тај садржај се може увести у RSS апликацију на вашој страни. + RSS + + + Alt+1 + shortcut to switch to first tab + пречица за пребацивање на прво поље + Alt+1 + + + Url download error + Url грешка преузимања + + + Couldn't download file at url: %1, reason: %2. + Немогуће преузети фајл са url: %1, разлог: %2. + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + н.пр.: Догодила се грешка са торентом xxx.avi. Разлог: диск је пун. + Нека И/О грешка се догодила са торентом %1. + Разлог: %2 + + + Transfers + Преноси + Трансфери + + + Download completion + Комплетно преузет + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + пречица за пребацивање на поље претраживања + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Општи лимит брзине слања + + + Global Download Speed Limit + Општи лимит брзине преузимања + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Неки фајлови се тренутно преносе. +Да ли сте сигурни да желите да прекинете qBittorrent? + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Преуз: %2/s, Сл: %3/s) + + + Options were saved successfully. + Опције када је сачуван успешно. + + + Recursive download confirmation + Потврда поновног преузимања + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Торент %1 садржи торент фајлове, да ли желите да наставите њихово преузимање? + + + Torrent file association + Асоцириње Торент фајла + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent није подразумевана апликација за отварање Торент фајлова или Magnet линкова. +Да ли желите да асоцирате qBittorrent за Торент фајлове и Magnet линкове? + + + Transfers (%1) + Трансфери (%1) + + + Yes + Да + + + No + Не + + + Never + Никада + + + Always + Увек + + + Exiting qBittorrent + Излазак из qBittorrent-а + + + Set the password... + Подешавање лозинке... + + + Password update + Обнављање лозинке + + + The UI lock password has been successfully updated + КИ-кориснички интерфејс + Закључавање КИ-а лозинком је успешно обновљено + + + UI lock password + КИ-кориснички интерфејс + Закључавање КИ-а лозинком + + + Please type the UI lock password: + КИ-кориснички интерфејс + Молим упишите лозинку закључавања КИ-а: + + + Invalid password + Погрешна лозинка + + + The password is invalid + Лозинка је погрешна + + + A newer version is available + Нова верзија је доступна + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Нова верзија qBittorrent-а је доступна на Sourceforge-u. +Да ли желите да ажурирате qBittorrent на верзију %1? + + + Impossible to update qBittorrent + Није могуће ажурирање qBittorrent-а + + + qBittorrent failed to update, reason: %1 + qBittorrent грешка при ажурирању, разлог: %1 + + + + GeoIP + + Australia + Аустралија + + + Argentina + Аргентина + + + Austria + Ауструја + + + United Arab Emirates + Уједињени Арапски Емирати + + + Brazil + Бразил + + + Bulgaria + Бугарска + + + Belarus + Белорусија + + + Belgium + Белгија + + + Bosnia + Босна + + + Canada + Канада + + + Czech Republic + Република Чешка + + + China + Кина + + + Costa Rica + Коста Рика + + + Switzerland + Швајцарска + + + Germany + Немачка + + + Denmark + Данска + + + Algeria + Алжир + + + Spain + Шпанија + + + Egypt + Египат + + + Finland + Финска + + + France + Француска + + + United Kingdom + Енглеска + + + Greece + Грчка + + + Georgia + Грузија + + + Hungary + Мађарска + + + Croatia + Хрватска + + + Italy + Италија + + + India + Индија + + + Israel + Израел + + + Ireland + Ирска + + + Iceland + Исланд + + + Indonesia + Индонезија + + + Japan + Јапан + + + South Korea + Јужна Кореја + + + Luxembourg + Луксембург + + + Malaysia + Малезија + + + Mexico + Мексико + + + Serbia + Србија + + + Morocco + Мароко + + + Netherlands + Холандија + + + Norway + Норвешка + + + New Zealand + Нови Зеланд + + + Portugal + Португалија + + + Poland + Пољска + + + Pakistan + Пакистан + + + Philippines + Филипини + + + Russia + Русија + + + Romania + Румунија + + + France (Reunion Island) + Француска (Reunion Island) + + + Sweden + Шведска + + + Slovakia + Словачка + + + Singapore + Сингапур + + + Slovenia + Словенија + + + Taiwan + Тајван + + + Turkey + Турска + + + Thailand + Тајланд + + + USA + САД + + + Ukraine + Украјина + + + South Africa + Јужна Африка + + + Saudi Arabia + Саудијска Арабија + + + + HeadlessLoader + + Information + Информације + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Да управљате qBittorrent-ом, приступите са Веб КИ на http://localhost:%1 + + + The Web UI administrator user name is: %1 + Веб КИ име администратора је: %1 + + + The Web UI administrator password is still the default one: %1 + Веб КИ лозинка администратора је још увек стандардна: %1 + + + This is a security risk, please consider changing your password from program preferences. + То је безбедносни ризик, молимо Вас да размислите о промени лозинке из програмског подешавања. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + Ваша IP адреса је одбијена после више покушаја аутентификације. + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Брзина преузимања: x KiB/s - Транспортовано: x MiB + П: %1/s - T: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Брзина слања: x KiB/s - Транспортовано: x MiB + С: %1/s - T: %2 + + + + HttpServer + + File + Фајл + + + Edit + Едитуј + Уреди + + + Help + Помоћ + + + Delete from HD + Обриши са HD-а (хард диск-а) + + + Download Torrents from their URL or Magnet link + Преузми Торенте са овог URL-а или Магнет линка + + + Only one link per line + Само један линк по линији + + + Download local torrent + Преузми локални торент + + + Torrent files were correctly added to download list. + Торент фајлови су коректно додати на листу за преузимање. + + + Point to torrent file + Указивање на Торент фајл + + + Download + Преузимање + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Да ли сте сигурни да желите да обришете селектоване Торенте са трансфер листе и са хард диска? + + + Download rate limit must be greater than 0 or disabled. + Вредност лимита Преузимања мора бити већа од 0 или онемугућена. + + + Upload rate limit must be greater than 0 or disabled. + Вредност лимита Слања мора бити већа од 0 или онемугућена. + + + Maximum number of connections limit must be greater than 0 or disabled. + Максимални број конекција при лимитирању мора бити већи од 0 или онемогућен. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Максимални број конекција по Торенту при лимитирању мора бити већи од 0 или онемогућен. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Максимални број слотова за слање Торента при лимитирању мора бити већи од 0 или онемогућен. + + + Unable to save program preferences, qBittorrent is probably unreachable. + Не могу да сачувам програмска подешавања, qBittorrent је вероватно недоступан. + + + Language + Језик + + + Downloaded + Is the file downloaded or not? + Преузет + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Порт који се користи за долазне конекције мора бити већи од 1024 а мањи од 65535. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Порт који се користи за Веб КИ мора бити већи од 1024 а мањи од 65535. + + + The Web UI username must be at least 3 characters long. + Веб КИ име корисника мора имати најмање 3 карактера. + + + The Web UI password must be at least 3 characters long. + Веб КИ лозинка мора имати најмање 3 карактера. + + + Save + Сачувај + + + qBittorrent client is not reachable + qBittorrent клијент није доступан + + + HTTP Server + HTTP Сервер + + + Torrent path + Путања Трента + + + Torrent name + Име Торента + + + The following parameters are supported: + Следећи параметри су подржани: + + + + LegalNotice + + Legal Notice + Правно Обавештење + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent је програм за дељење датотека. Када покренете Торент, дељене датотеке ће бити доступне другима за преузимање. И наравно, било који садржај који делите је Ваша лична одговорност. + +Ви вероватно то знате, тако да Вам то нећемо понављати. + + + Press %1 key to accept and continue... + Притисните %1 тастер да ово прихватите и наставите... + + + Legal notice + Правно обавештење + + + Cancel + Откажи + + + I Agree + Слажем се , Прихватам + Сагласан сам + + + + LineEdit + + Clear the text + Обриши текст + + + + MainWindow + + &Edit + &Едитуј + &Уреди + + + &File + &Датотека + &Фајл + + + &Help + &Помоћ + + + Preview file + Приказ датотеке + + + Clear log + Обриши лог + + + Decrease priority + Снизи приоритет + + + Increase priority + Повиси приоритет + + + &Tools + &Алати + + + &View + &Изглед + + + &Add File... + &Додај фајл... + + + E&xit + И&злаз + + + &Options... + &Опције... + + + Add &URL... + Додај &URL... + + + Torrent &creator + Торент &креатор + + + Set upload limit... + Подеси ограничење слања... + + + Set download limit... + Подеси ограничење преузимања... + + + Set global download limit... + Подеси општи лимит преузимања... + + + Set global upload limit... + Подеси општи лимит слања... + + + &Log viewer... + Log-Дневник-Лог + &Преглед дневника... + + + Top &tool bar + Горња &трака алата + + + Display top tool bar + Прикажи горњу траку алата + + + &Speed in title bar + &Брзина на насловној траци + + + Show transfer speed in title bar + Прикажи брзину преноса на насловној траци + + + Alternative speed limits + Алтернативно ограничење брзине + + + &About + &О програму + + + &Pause + &Пауза + + + &Delete + &Обриши + + + P&ause All + П&аузирај све + + + Visit &Website + Посети &Веб страну + + + Report a &bug + Извести о &грешци + + + &Documentation + &Документација + + + &RSS reader + &RSS читач + + + Search &engine + Претраживачки &модул + + + Log viewer + Преглед дневника + + + Lock qBittorrent + Закључај qBittorrent + + + Ctrl+L + Ctrl+L + + + Shutdown computer when downloads complete + Искључи рачунар по комплетном преузимању + + + &Resume + &Настави + + + R&esume All + Н&астави Све + + + Shutdown qBittorrent when downloads complete + Искључи qBittorrent по комплетном преузимању + + + Exit + Излаз + + + Import torrent... + Увези торент... + + + Donate money + Донирање новца + + + If you like qBittorrent, please donate! + Ако волите qBittorrent, молимо Вас донирајте! + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + Подешавање лозинке... + + + Transfers + Трансфери + + + Torrent file association + Асоцириње Торент фајла + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent није подразумевана апликација за отварање Торент фајлова или Magnet линкова. +Да ли желите да асоцирате qBittorrent за Торент фајлове и Magnet линкове? + + + UI lock password + Закључавање КИ-а лозинком + + + Please type the UI lock password: + Молим упишите лозинку закључавања КИ-а: + + + Password update + Обнављање лозинке + + + The UI lock password has been successfully updated + Закључавање КИ-а лозинком је успешно обновљено + + + RSS + RSS + + + Search + Претраживање + + + Transfers (%1) + Трансфери (%1) + + + Download completion + Комплетно преузет + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 је завршио преузимање. + + + I/O Error + i.e: Input/Output Error + И/О Грешка + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Нека И/О грешка се догодила са торентом %1. + Разлог: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Потврда поновног преузимања + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Торент %1 садржи торент фајлове, да ли желите да наставите њихово преузимање? + + + Yes + Да + + + No + Не + + + Never + Никада + + + Url download error + Url грешка преузимања + + + Couldn't download file at url: %1, reason: %2. + Немогуће преузети фајл са url: %1, разлог: %2. + + + Global Upload Speed Limit + Општи лимит брзине слања + + + Global Download Speed Limit + Општи лимит брзине преузимања + + + Invalid password + Погрешна лозинка + + + The password is invalid + Лозинка је погрешна + + + Exiting qBittorrent + Излазак из qBittorrent-а + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Неки фајлови се тренутно преносе. +Да ли сте сигурни да желите да прекинете qBittorrent? + + + Always + Увек + + + Open Torrent Files + Отвори Торент фајлове + + + Torrent Files + Торент Фајлови + + + Options were saved successfully. + Опције када је сачуван успешно. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + ПР брзина: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + СЛ брзина: %1 KiB/s + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Преуз: %2/s, Сл: %3/s) + + + A newer version is available + Нова верзија је доступна + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Нова верзија qBittorrent-а је доступна на Sourceforge-u. +Да ли желите да ажурирате qBittorrent на верзију %1? + + + Impossible to update qBittorrent + Није могуће ажурирање qBittorrent-а + + + qBittorrent failed to update, reason: %1 + qBittorrent грешка при ажурирању, разлог: %1 + + + &Add torrent file... + &Додај торент фајл... + + + Add &link to torrent... + Додај &линк у торент... + + + Import existing torrent... + Увези постојећи торент... + + + Execution &Log + Дневник &Дешавања + + + Execution Log + Дневник догађаја + + + Auto-Shutdown on downloads completion + Ауто-Искључење по комплетном преузимању + + + Exit qBittorrent + Изађи из qBittorrent-а + + + Suspend system + Суспендуј рачунар + + + Shutdown system + Искључи рачунар + + + Disabled + Онемогућено + + + The password should contain at least 3 characters + Лозинка мора имати најмање 3 карактера + + + + PeerAdditionDlg + + Invalid IP + Погрешан IP + + + The IP you provided is invalid. + IP адреса коју сте унели није исправна. + + + + PeerListDelegate + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + Клијент + + + Progress + i.e: % downloaded + н.пр.: % преузето + Напредак + + + Down Speed + i.e: Download speed + Брзина Преузимања + + + Up Speed + i.e: Upload speed + Брзина Слања + + + Downloaded + i.e: total data downloaded + Преузето + + + Uploaded + i.e: total data uploaded + Послато + + + Ban peer permanently + peer-учесник, активна веза + Забрани(бануј) peer трајно + + + Peer addition + peer-учесник, активна веза + Додавање (peer-a) учесника + + + The peer was added to this torrent. + Peer (учесник) је додат у овај торент. + + + The peer could not be added to this torrent. + Peer (учесник) не може бити додат у овај торент. + + + Are you sure? -- qBittorrent + Да ли сте сигурни? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + Да ли сте сигурни да желите да забраните изабране учеснике трајно? + + + &Yes + &Да + + + &No + &Не + + + Manually banning peer %1... + peer-учесник, активна веза + Ручно забрани(бануј) peer %1... + + + Upload rate limiting + Ограничење брзине слања + + + Download rate limiting + Ограничење брзине преузимања + + + Add a new peer... + Додај нов peer (учесник-а)... + + + Limit download rate... + Ограничење брзине преузимања... + + + Limit upload rate... + Ограничење брзине слања... + + + Copy IP + Копирај IP + + + Connection + Конекције + + + + Preferences + + UI + User Interface + КИ (Кориснички Интерфејс) + КИ + + + Downloads + Преузимање + + + Connection + Конекције + + + Speed + Брзина + + + Bittorrent + Бит-торент + + + Proxy + Прокси + + + Web UI + Web UI (Веб Кориснички Интерфејс) + Веб КИ + + + Advanced + Напредно + + + Language: + Језик: + + + (Requires restart) + (Захтева рестарт) + + + Visual style: + Изглед: + + + Transfer list + Листа преноса + Трансфер листа + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Користи различите боје за приказ редова + + + File system + Фајл систем + + + Copy .torrent files to: + Копирај .torrent фајлове у: + + + Torrent queueing + Торент опслуживање + + + Maximum active downloads: + Максимум активних преузимања: + + + Maximum active uploads: + Максимум активних слања: + + + Maximum active torrents: + Максимум активних торента: + + + When adding a torrent + Када додајете неки торент + + + Display torrent content and some options + Прикажи садржај торента и неке опције + + + Listening port + Надгледај порт + + + Port used for incoming connections: + Порт коришћен за долазне конекције: + + + Random + Случајан + + + Enable UPnP port mapping + Омогући UPnP мапирање порта + + + Enable NAT-PMP port mapping + Омогући NAT-PMP мапирање порта + + + Connections limit + Конекциона ограничења + + + Global maximum number of connections: + Општи максимални број конекција: + + + Maximum number of connections per torrent: + Максимални број конекција по торенту: + + + Maximum number of upload slots per torrent: + Максимални број слотова за слање по торенту: + + + Upload: + Слање: + + + Download: + Преузимање: + + + KiB/s + KiB/s + + + Global speed limits + Глобална ограничења брзине + + + Alternative global speed limits + Алтернатива глобалног ограничења брзине + + + to + time1 to time2 + до + + + Every day + Сваки дан + + + Week days + Радним данима + + + Week ends + Викендом + + + Bittorrent features + Бит-торент карактеристике + + + Enable DHT network (decentralized) + Омогући DHT мрежу (децентализовано) + + + Use a different port for DHT and Bittorrent + Користи различит порт за DHT и Бит-торент + + + DHT port: + DHT порт: + + + Enable Peer Exchange / PeX (requires restart) + Рестарт је потребан за старт PeX подршке + Омогући Peer Exchange / PeX (захтева рестарт) + + + Enable Local Peer Discovery + Омогући откривање локалних веза Peer (учесника) + + + Enabled + Омогући + + + Forced + Форсирано + + + Disabled + Онемогући + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP Комуникације (пратиоци, Веб донори, претраживачки модул) + + + Host: + Домаћин: + + + Peer Communications + Peer (учесничке) Комуникације + + + SOCKS4 + SOCKS4 + + + Type: + Тип: + + + Remove folder + фолдер-фасцикла-директоријум + Уклони фолдер + + + (None) + (Ниједан) + + + HTTP + HTTP + + + Port: + Порт: + + + Authentication + Аутентификација + + + Username: + Корисничко име: + + + Password: + Лозинка: + + + SOCKS5 + SOCKS5 + + + Filter path (.dat, .p2p, .p2b): + Филтер, путања фајла (.dat, .p2p, .p2b): + + + HTTP Server + HTTP Сервер + + + No action + Без дејства + + + Options + Опције + + + Visual Appearance + Изглед + Визуелни приказ + + + Action on double-click + Дејство при двоструком клику + + + Downloading torrents: + Преузимање торента: + + + Start / Stop + Старт/Стоп + + + Open destination folder + Отвори одредишну фасциклу + + + Completed torrents: + Завршени торенти: + + + Desktop + Desktop-Радни простор + Радна површина + + + Show splash screen on start up + Прикажи уводни екран при пократању + + + Start qBittorrent minimized + Стартуј qBittorrent минимизовано + + + Show qBittorrent icon in notification area + Прикажи qBittorrent икону на системској палети + + + Minimize qBittorrent to notification area + Минимизуј qBittorrent на системску палету + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Затвори qBittorrent на системску палету + + + Do not start the download automatically + The torrent will be added to download list in pause state + Немој аутоматски да стартујеш преузимање + + + Save files to location: + Сачувај фајлове на локацији: + + + Append the label of the torrent to the save path + Додај ознаку торента у путању чувања + + + Pre-allocate disk space for all files + Додели простор на диску за све фајлове + + + Keep incomplete torrents in: + Задржи некомплетне торенте у: + + + Append .!qB extension to incomplete files' names + Додај .!qB екстензију у некомплетна имена фајлова + + + Automatically add torrents from: + Аутоматски додај торенте из: + + + Add folder... + Додај фолдер... + + + IP Filtering + IP Филтрирање + + + Schedule the use of alternative speed limits + Распоред коришћења алтернативног ограничења брзине + + + from + from (time1 to time2) + од + + + When: + Када: + + + Look for peers on your local network + peer-пир-учесник + Потражите peer-ове на вашој локалној мрежи + + + Protocol encryption: + Протокол шифровања: + + + Enable Web User Interface (Remote control) + Омогући Веб Кориснички Интерфејс (Даљински приступ) + + + Share ratio limiting + Ограничење индекса дељења + + + Seed torrents until their ratio reaches + Донирај торенте док не достигнеш тражени ниво + + + then + затим + + + Pause them + Паузирај их + + + Remove them + Уклони их + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + peer-пир-учесник + Размењуј peer-ове са компатибилним Bittorrent клијентима (µTorrent, Vuze, ...) + + + Email notification upon download completion + Обавештење Е-поштом након комплетног преузимања + + + Destination email: + Адреса за Е-пошту: + + + SMTP server: + SMTP сервер: + + + Run an external program on torrent completion + Покрени екстерни програм по завршетку торента + + + Use %f to pass the torrent path in parameters + Користи %f за пролаз торент путање у параметрима + + + Proxy server + Прокси сервер + + + BitTorrent + Бит-торент + + + Start / Stop Torrent + Старт / Стоп Торент + + + Use UPnP / NAT-PMP port forwarding from my router + Користи UPnP / NAT-PMP преусмерење порта са мог рутера + + + Privacy + Приватност + + + Enable DHT (decentralized network) to find more peers + Омогући DHT (децентализовану мрежу) за налажење додатних учесника + + + Use a different port for DHT and BitTorrent + Користи различит порт за DHT и Бит-торент + + + Enable Peer Exchange (PeX) to find more peers + Омогући Peer Exchange (PeX) за налажење додатних учесника + + + Enable Local Peer Discovery to find more peers + Омогући откривање локалних веза за налажење додатних учесника + + + Encryption mode: + Режим шифровања: + + + Prefer encryption + Предложи шифровање + + + Require encryption + Захтевај шифровање + + + Disable encryption + Онемогући шифровање + + + User Interface + Кориснички интерфејс + + + Reload the filter + Поново учитај филтер + + + Behavior + Понашање + + + Language + Језик + + + Power Management + Управљање напајањем + + + Inhibit system sleep when torrents are active + Спречи стање мировања када су торенти активни + + + Bypass authentication for localhost + Заобиђи аутентификацију за localhost-а + + + Ask for program exit confirmation + Захтевај потврду за излазак из програма + + + Use monochrome system tray icon (requires restart) + Користи једнобојну икону на системској палети (захтева рестарт) + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Следећи параметри су подржани: +<ul> +<li>%f: Torrent путања</li> +<li>%n: Torrent име</li> +</ul> + + + User Interface Language: + Кориснички интерфејс Језик: + + + Transfer List + Трансфер листа + + + Show qBittorrent in notification area + Прикажи qBittorrent на системској палети + + + Tray icon style: + Изглед системске иконе: + + + Normal + Нормалан + + + Monochrome (Dark theme) + Једнобојан (Тамна тема) + + + Monochrome (Light theme) + Једнобојан (Светла тема) + + + Hard Disk + Хард диск + + + This server requires a secure connection (SSL) + Овај сервер захтева безбедну конекцију (SSL) + + + Listening Port + Пријемни порт + + + Connections Limits + Конекциона ограничења + + + Proxy Server + Прокси сервер + + + Global Rate Limits + Општа вредност ограничења + + + Enable bandwidth management (uTP) + Омогући управљање пропусног опсега (uTP) + + + Apply rate limit to uTP connections + Примени ведност ограничења на uTP конекције + + + Apply rate limit to transport overhead + Примени ведносна ограничења код прекорачење преноса + + + Alternative Global Rate Limits + Алтернатива општег ограничења брзине + + + Schedule the use of alternative rate limits + Распоред коришћења алтернативног ограничења брзине + + + Torrent Queueing + Опслуживање Торета + + + Share Ratio Limiting + Ограничење индекса дељења + + + Use UPnP / NAT-PMP to forward the port from my router + Користи UPnP / NAT-PMP преусмерење порта са мог рутера + + + Update my dynamic domain name + Обнови име мог динамичког домена + + + Service: + Сервис: + + + Register + Регистар + + + Domain name: + Име домена: + + + Otherwise, the proxy server is only used for tracker connections + tracker-пратилац + У супротном, прокси сервер се једино користи за конекције tracker-а(пратилаца) + + + Use proxy for peer connections + peer-учесник + Користи прокси за peer(учесничке) конекције + + + Append .!qB extension to incomplete files + Додај .!qB екстензију у некомплетне фајлове + + + Use HTTPS instead of HTTP + Користи HTTPS уместо HTTP + + + Import SSL Certificate + Увоз SSL сертификата + + + Import SSL Key + Увоз SSL кључа + + + Certificate: + Сертификат: + + + Key: + Кључ: + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + PreviewSelect + + Name + Име + + + Size + Величина + + + Progress + Напредак + + + Preview impossible + Приказ немогућ + + + Sorry, we can't preview this file + Жалим не могу да прикажем овај фајл + + + + ProgramUpdater + + Could not create the file %1 + Није могуће креирати датотеку %1 + + + Failed to download the update at %1 + %1 is an URL + Неуспешно преузимање ажурирања са %1 + + + + PropListDelegate + + Not downloaded + Не преузимај + + + Normal + Normal (priority) + Нормалан + + + High + High (priority) + Висок + + + Maximum + Maximum (priority) + Максималан + + + Mixed + Mixed (priorities + Комбинован + + + + PropTabBar + + General + Опште + + + Trackers + Пратиоци + + + Peers + Peers (учесници) + + + URL Seeds + URL донори + + + Files + Фајлови + + + HTTP Sources + HTTP извори + + + Content + Садржај + + + + PropertiesWidget + + Save path: + Сачувај у: + + + Torrent hash: + hash-контролна сума + Торент hash: + + + Share ratio: + Однос дељења: + + + Downloaded: + Преузето: + + + Availability: + Доступност: + + + Transfer + Трансфер-Пренос + Трансфер + + + Uploaded: + Послато: + + + Wasted: + Потрошено: + + + UP limit: + Ограничење слања + СЛ лимит: + + + DL limit: + Ограничење преузимања + ПР лимит: + + + Time elapsed: + Протекло време: + + + Connections: + Конекције: + + + Information + Информације + + + Created on: + Креирано у: + + + Comment: + Коментар: + + + General + Опште + + + Trackers + Trackers-Трагачи,Пратиоци + Пратиоци + + + Peers + Peers (учесници) + + + URL seeds + донори-seeds + URL донори + + + Files + Фајлови + + + Priority + Приоритет + + + Normal + Нормалан + + + Maximum + Максималан + + + High + Висок + + + this session + ова сесија + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Донирано за %1 + + + %1 max + e.g. 10 max + %1 max + + + I/O Error + И/О Грешка + + + This file does not exist yet. + Овај фајл више не постоји. + + + This folder does not exist yet. + Овај директоријум више не постоји. + + + Rename... + Преименуј... + + + Rename the file + Преименуј фајл + + + New name: + Ново име: + + + The file could not be renamed + Фајл не може бити преименован + + + This file name contains forbidden characters, please choose a different one. + Ово име фајла садржи недозвољене карактере, молим изаберите неко друго. + + + This name is already in use in this folder. Please use a different name. + Ово име је већ у употреби молим изаберите неко друго. + + + The folder could not be renamed + Фолдер не може бити преименован + + + New url seed + New HTTP source + Нови Url донор + + + New url seed: + Нови Url донор: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + Овај Url донор је већ на листи. + + + Choose save path + Изаберите путању чувања + + + Save path creation error + Грешка у путањи за чување + + + Could not create the save path + Не могу да креирам путању за чување фајла + + + Reannounce in: + Поново објави за: + + + Select All + Селектуј све + + + Select None + Деселектуј + + + Do not download + Не преузимај + + + Pieces size: + Делови величине: + + + Time active: + Time (duration) the torrent is active (not paused) + Протекло време: + + + Torrent content: + Садржај Торента: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1 достигао је максимални ниво који сте подесили. + + + Removing torrent %1... + Уклањање торента %1... + + + Pausing torrent %1... + Паузирање торента %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent је повезан на порт: TCP/%1 + + + UPnP support [ON] + UPnP подршка [Укључена] + + + UPnP support [OFF] + UPnP подршка [Искључена] + + + NAT-PMP support [ON] + NAT-PMP подршка [Укључена] + + + NAT-PMP support [OFF] + NAT-PMP подршка [Искључена] + + + HTTP user agent is %1 + HTTP кориснички агент је %1 + + + Using a disk cache size of %1 MiB + Користи кеш диска величине %1 MiB + + + DHT support [ON], port: UDP/%1 + DHT подршка [Укључена], порт: UDP/%1 + + + DHT support [OFF] + DHT подршка [Искључена] + + + PeX support [ON] + PeX подршка [Укључена] + + + PeX support [OFF] + PeX подршка [Искључена] + + + Restart is required to toggle PeX support + Потребан је рестарт за активирање PeX подршке + + + Local Peer Discovery [ON] + Претраживање локалних веза [Укључено] + + + Local Peer Discovery support [OFF] + Претраживање локалних веза подршка [Искључено] + + + Encryption support [ON] + Шифровање подршка [Укључена] + + + Encryption support [FORCED] + Шифровање подршка [Форсирано] + + + Encryption support [OFF] + Шифровање подршка [Искључена] + + + Embedded Tracker [ON] + Уграђени пратилац [Укључен] + + + Failed to start the embedded tracker! + Неуспешно покретање уграђеног пратиоца! + + + Embedded Tracker [OFF] + Уграђени пратилац [Искључен] + + + The Web UI is listening on port %1 + Веб КИ надгледа порт %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Веб Кориснички Интерфејс Грешка - Не могу да повежем Веб КИ на порт %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' је уклоњен са трансфер листе и хард диска. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' је уклоњен са трансфер листе. + + + '%1' is not a valid magnet URI. + '%1' није валидан магнет URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' већ је додат на листу за преузимање. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' настави. (брзо настави) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' додат на листу за преузимање. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Није у стању да декодира торент фајл: '%1' + + + This file is either corrupted or this isn't a torrent. + Овај фајл је оштећен или ово није торент. + + + Error: The torrent %1 does not contain any file. + Грешка: Торент %1 не садржи ни један фајл. + + + Note: new trackers were added to the existing torrent. + Напомена: нови пратиоци су додати у постојећи торент. + + + Note: new URL seeds were added to the existing torrent. + Напомена: нови URL донори су додати у постојећи торент. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>је блокиран због вашег IP филтера</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>је одбачен због оштећених делова</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Поновно преузимање фајла %1 омогућено у торенту %2 + + + Unable to decode %1 torrent file. + Није у стању да декодира %1 торент фајл. + + + Torrent name: %1 + Име Торента: %1 + + + Torrent size: %1 + Величина Торента: %1 + + + Save path: %1 + Путања чувања: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Торент ће бити преузет за %1. + + + Thank you for using qBittorrent. + Хвала што користите qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 је завршио преузимање + + + An I/O error occured, '%1' paused. + Нека И/О грешка се догодила, '%1' паузирано. + + + Reason: %1 + Разлог: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Порт мапирање грешка, порука: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Порт мапирање успешно, порука: %1 + + + File sizes mismatch for torrent %1, pausing it. + Величина фајла није одговарајућа за торент %1, паузирајте га. + + + Fast resume data was rejected for torrent %1, checking again... + Брзи наставак података је одбијен за торент %1, покушајте поново... + + + Url seed lookup failed for url: %1, message: %2 + Url преглед донора , грешка url: %1, порука: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Преузимање '%1', молим сачекајте... + + + The network interface defined is invalid: %1 + Мрежни интерфејс који је задат је погрешан: %1 + + + Trying any other network interface available instead. + Пробајте неки други доступни мрежни интрфејс уместо тога. + + + Listening on IP address %1 on network interface %2... + Надгледај IP адресе %1 на мрежном интерфејсу %2... + + + Failed to listen on network interface %1 + Грешка при надгледању мрежног интрфејса %1 + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP подршка [Укључена] + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP подршка [Искључена] + + + Local Peer Discovery support [ON] + Претраживање локалних веза подршка [Укључено] + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Успешна анализа датог IP филтера: %1 правила су примењена. + + + Error: Failed to parse the provided IP filter. + Грешка: Неспешна анализа датог IP филтера. + + + Reporting IP address %1 to trackers... + Пријављивање IP адреса %1 пратиоцима... + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Рачунар ће сада отићи у стање мировања осим ако то не откажете у наредних 15 секунди... + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Рачунар ће сада бити искључен осим ако то не откажете у наредних 15 секунди... + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent ће сада бити искључен осим ако то не откажете у наредних 15 секунди... + + + + RSS + + Search + Претраживање + + + New subscription + Нови допис + + + Mark items read + Означи прочитане ставке + + + Update all + Ажурирај све + + + RSS feeds + feed-допис,порука + RSS поруке + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Торенти:</span> <span style=" font-style:italic;">(двоструки клик за преузимање)</span></p></body></html> + + + Article title + Наслов чланка + + + Feed URL + Оглашавач URL + + + Delete + Обриши + + + Rename + Преименуј + + + Update + Ажурирај + + + Update all feeds + Ажурирај све поруке + + + Download torrent + Преузми Торент + + + Open news URL + Отвори новости URL + + + Copy feed URL + feed-допис,порука + Копирај feed URL + + + Refresh RSS streams + Освежи RSS токове података + + + Rename... + Преименуј... + + + New subscription... + Нови допис... + + + RSS feed downloader... + RSS преузимач порука... + + + New folder... + Нова фасцикла... + + + Manage cookies... + Управљање колачићима... + + + Settings... + Подешавања... + + + RSS Downloader... + RSS преузимач порука... + + + + RSSImp + + Please type a rss stream url + Молим упишите rss ток података url + + + Stream URL: + Ток података URL: + + + Are you sure? -- qBittorrent + Да ли сте сигурни? -- qBittorrent + + + &Yes + &Да + + + &No + &Не + + + Please choose a folder name + фасцикла-фолдер + Молим изаберите име фасцикле + + + Folder name: + фасцикла-фолдер + Име фасцикле: + + + New folder + фасцикла-фолдер + Нова фасцикла + + + Overwrite attempt + Покушај преписивања + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Не можете да препишете myFolder ставку. + Не можете да препишете %1 ставку. + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + Ова RSS порука већ постоји на листи. + + + Are you sure you want to delete these elements from the list? + Јесте ли сигурни да желите да избришете ове елементе из листе? + + + Are you sure you want to delete this element from the list? + Јесте ли сигурни да желите да обришете овај елемент са листе? + + + Please choose a new name for this RSS feed + feed-допис,порука + Молим изаберит ново име за овај RSS допис + + + New feed name: + feed-допис,порука + Ново feed име: + + + Name already in use + Име је већ у употреби + + + This name is already used by another item, please choose another one. + Ово име је већ у употреби молим изаберите неко друго. + + + Date: + Датум: + + + Author: + Аутор: + + + Unread + Непрочитан + + + + RssArticle + + No description available + Нема доступних описа + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + Аутоматски преузми %1 торент са %2 RSS feed-а... + + + + RssItem + + No description available + Нема доступних описа + + + + RssSettings + + RSS Reader Settings + RSS читач Подешавања + + + RSS feeds refresh interval: + RSS поруке интервал освежавања: + + + minutes + минута + + + Maximum number of articles per feed: + Максимални број чланака по допису: + + + + RssSettingsDlg + + RSS Reader Settings + RSS читач Подешавања + + + RSS feeds refresh interval: + RSS поруке интервал освежавања: + + + minutes + минута + + + Maximum number of articles per feed: + Максимални број чланака по допису: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + feed-допис,порука + Аутоматски преузми %1 торент са %2 RSS feed... + + + + ScanFoldersModel + + Watched Folder + Надгледани Фолдер + + + Download here + Преузими одавде + + + + SearchCategories + + All categories + Све категорије + + + Movies + Филмови + + + TV shows + ТВ емисије + + + Music + Музика + + + Games + Игре + + + Anime + Забава + Анимације + + + Software + Софтвер + + + Pictures + Слике + + + Books + Књиге + + + + SearchEngine + + Cut + Исеци + + + Copy + Копирај + + + Paste + Пренеси,Налепи + Додај + + + Clear field + Обриши поље + + + Clear completion history + Обриши комплетну историју + + + Search + Претраживање + + + Empty search pattern + Празано поље претраживања + + + Please type a search pattern first + Унесите прво назив за претраживање + + + Results + Резултати + + + Searching... + Претраживање... + + + Search Engine + Претраживачки модул + + + Search has finished + Претраживање је завршено + + + An error occured during search... + Нека грешка се догодила током претраге... + + + Search aborted + Претраживање прекинуто + + + Search returned no results + Претрага није дала резултате + + + Results + i.e: Search results + Резултати + + + Unknown + Непознат + + + Download error + Грешка преузимања + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Python setup не може бити преузет,разлог: %1. +Молим Вас инсталирајте га ручно. + + + Missing Python Interpreter + Недостаје Python преводилац + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Pithon 2.х је потребан за коришћење претраживачког модула, али изгледа да није инсталиран. +Да ли желите да га инсталирате? + + + Confirmation + Потврђивање + + + Are you sure you want to clear the history? + Да ли сте сигурни да желите да обришете историјат? + + + + SearchTab + + Name + i.e: file name + Име + + + Size + i.e: file size + Величина + + + Seeders + i.e: Number of full sources + Seeders-Донори + Донори + + + Leechers + i.e: Number of partial sources + Leechers-Трагачи + Трагачи + + + Search engine + Претраживачки модул + + + + ShutdownConfirmDlg + + Shutdown confirmation + Потврђивање искључења + + + + SpeedLimitDialog + + KiB/s + KiB/s + + + + StatusBar + + Connection status: + Статус конекције: + + + No direct connections. This may indicate network configuration problems. + Нема директних конекција. То може указивати на проблем мрежне конфигурације. + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + Брзина преузимања: x B/s - Транспортовано: x MiB + П: %1 B/s - T: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + Брзина слања: x B/s - Транспортовано: x MiB + С: %1 B/s - T: %2 + + + DHT: %1 nodes + DHT: %1 чворова + + + Connection Status: + Статус конекције: + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Није на вези. То обично значи да qBittorrent не надгледа изабрани порт за долазне конекције. + + + Online + На вези + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + П: %1/s - T: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + С: %1/s - T: %2 + + + Click to disable alternative speed limits + Кликните да онемогућите алтернативно ограничење брзине + + + Click to enable alternative speed limits + Кликните да омогућите алтернативно ограничење брзине + + + Global Download Speed Limit + Општи лимит брзине преузимања + + + Global Upload Speed Limit + Општи лимит брзине слања + + + qBittorrent needs to be restarted + qBittorrent треба бити рестартован + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent је управо ажуриран и треба бити рестартован, да би' промене имале ефекта. + + + Click to switch to alternative speed limits + Кликните да укључите алтернативно ограничење брзине + + + Click to switch to regular speed limits + Кликните да укључите уобичајено ограничење брзине + + + %1/s + Per second + %1/s + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + Селектујте фасциклу коју додајете у торент + + + Select a file to add to the torrent + Селектујте фајл који додајете у торент + + + Please type an announce URL + Молим упишите URL оглашавача + + + Announce URL: + Tracker URL + Објављени URL: + + + Please type a web seed url + Молим упишите url веб донора + + + Web seed URL: + URL Веб донора: + + + No input path set + Није унета путања + + + Please type an input path first + Молим прво упишите улазну путању + + + Select destination torrent file + Изаберите дестинацију торент фајла + + + Torrent Files + Торент Фајлови + + + Torrent creation + Креирање Торента + + + Torrent creation was unsuccessful, reason: %1 + Креирање Торента је неуспешно, разлог: %1 + + + Created torrent file is invalid. It won't be added to download list. + Креирана Торент датотека је неважећа. Неће бити додата у листу за преузимање. + + + Torrent was created successfully: + Торент је креиран успешно: + + + + TorrentFilesModel + + Name + Име + + + Size + Величина + + + Progress + Напредак + + + Priority + Приоритет + + + + TorrentImportDlg + + Torrent Import + Увоз торента + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Овај асистен ће вам помоћи да делите са qBittorrent-ом торенте које сте већ преузели. + + + Torrent file to import: + Торент фајл за увоз: + + + ... + ... + + + Content location: + Садржај локације: + + + Skip the data checking stage and start seeding immediately + Прескочи проверу података и одмах стартуј донирање + + + Import + Увоз + + + Torrent file to import + Торент фајл за увоз + + + Torrent files (*.torrent) + Торент фајлови (*.torrent) + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 Фајлови + + + Please provide the location of %1 + %1 is a file name + Наведите локацију %1 + + + Please point to the location of the torrent: %1 + Молим Вас укажите на локацију торента: %1 + + + Invalid torrent file + Неисправна торент датотека + + + This is not a valid torrent file. + Ово није валидан торент фајл. + + + + TorrentModel + + Name + i.e: torrent name + Име + + + Size + i.e: torrent size + Величина + + + Done + % Done + Урађено + + + Status + Torrent status (e.g. downloading, seeding, paused) + Статус + + + Seeds + i.e. full sources (often untranslated) + Донори + + + Peers + i.e. partial sources (often untranslated) + Peers (учесници) + + + Down Speed + i.e: Download speed + Брзина Преуз + + + Up Speed + i.e: Upload speed + Брзина Слања + + + Ratio + Share ratio + Однос + + + ETA + i.e: Estimated Time of Arrival / Time left + очекивано време за преузимање + ETA + + + Label + Ознака + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Додато на + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Завршено дана + + + Tracker + Пратилац + + + Down Limit + i.e: Download limit + Преуз. Лимит + + + Up Limit + i.e: Upload limit + Слањ. Лимит + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Износ преузетог + + + Amount left + Amount of data left to download (e.g. in MB) + Преостали износ + + + Time Active + Time (duration) the torrent is active (not paused) + Протекло време + + + + TrackerList + + URL + Url (адреса) + URL + + + Status + Статус + + + Peers + Peers (учесници) + + + Message + Порука + + + [DHT] + [DHT] + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Working + Ради + + + Disabled + Онемогућен + + + This torrent is private + Овај торент је приватан + + + Updating... + Ажурирање... + + + Not working + Не ради + + + Not contacted yet + Није још контактиран + + + Add a new tracker... + Додај нови пратилац... + + + Remove tracker + Уклони пратилац + + + Force reannounce + Форсирано реобјављивање + + + + TrackersAdditionDlg + + Trackers addition dialog + Пратиоци, дијалог додавања + + + List of trackers to add (one per line): + Листа за додавање пратилаца (један по линији): + + + µTorrent compatible list URL: + µTorrent компатибилна листа URL адреса: + + + I/O Error + И/О Грешка + + + Error while trying to open the downloaded file. + Грешка при покушају да се отвори преузета датотека. + + + No change + Без измена + + + No additional trackers were found. + Нису пронађени додатни пратиоци. + + + Download error + Грешка преузимања + + + The trackers list could not be downloaded, reason: %1 + Листа пратилаца не може бити преузета, разлог: %1 + + + + TransferListDelegate + + Downloading + Преузимање + + + Paused + Паузиран + + + Queued + i.e. torrent is queued + Редослед + + + Seeding + Torrent is complete and in upload-only mode + Донирање + + + Stalled + Torrent is waiting for download to begin + Застој + + + Checking + Torrent local data is being checked + Провера + + + /s + /second (.i.e per second) + /s + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + Seeded for %1 + e.g. Seeded for 3m10s + Донирано за %1 + + + + TransferListFiltersWidget + + All + Сви + + + Downloading + Преузимање + + + Completed + Комплетирани + + + Active + Активни + + + Inactive + Неактивни + + + All labels + Све ознаке + + + Unlabeled + Неозначено + + + Remove label + Уклони ознаку + + + New Label + Нова ознака + + + Label: + Label-Ознака,Маркер + Ознака: + + + Invalid label name + Погрешно име ознаке + + + Please don't use any special characters in the label name. + Молимо Вас да не користите специјалне карактере у имену ознаке. + + + Paused + Паузирани + + + Add label... + Додај ознаку... + + + Resume torrents + Настави торенте + + + Pause torrents + Паузирај торенте + + + Delete torrents + Обриши торенте + + + + TransferListWidget + + Down Speed + i.e: Download speed + Брзина Преуз + + + Up Speed + i.e: Upload speed + Брзина Слања + + + ETA + i.e: Estimated Time of Arrival / Time left + н.пр.: Приближно време завршетка + ETA + + + Column visibility + Прегледност колона + + + Name + i.e: torrent name + Име + + + Size + i.e: torrent size + Величина + + + Done + % Done + Урађено + + + Status + Torrent status (e.g. downloading, seeding, paused) + Статус + + + Seeds + i.e. full sources (often untranslated) + Донори + + + Peers + i.e. partial sources (often untranslated) + Peers (учесници) + + + Ratio + Share ratio + Однос + + + Label + Label-Ознака,Маркер + Ознака + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Додато на + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Завршено дана + + + Down Limit + i.e: Download limit + н.пр.: Ограничење преузимања + Преуз. Лимит + + + Up Limit + i.e: Upload limit + н.пр.: Ограничење слања + Слањ. Лимит + + + Torrent Download Speed Limiting + Ограничење брзине преузимања Торента + + + Torrent Upload Speed Limiting + Ограничење брзине слања Торента + + + New Label + Нова ознака + + + Label: + Ознака: + + + Invalid label name + Погрешно име ознаке + + + Please don't use any special characters in the label name. + Молимо Вас да не користите специјалне карактере у имену ознаке. + + + Rename + Преименуј + + + New name: + Ново име: + + + Open destination folder + фасцикла-фолдер + Отвори одредишну фасциклу + + + Force recheck + Форсирано провери + + + Copy magnet link + Копирај магнет линк + + + Super seeding mode + Супер seeding (донирајући) мод + + + Rename... + Преименуј... + + + Download in sequential order + Преузимање у сријском редоследу + + + Download first and last piece first + Преузимање почетних и крајњих делова + + + New... + New label... + Нова... + + + Reset + Reset label + Поништи ознаке + Поништи + + + Choose save path + Изаберите путању чувања + + + Save path creation error + Грешка при креирању путање чувања + + + Could not create the save path + Не могу да креирам путању за чување фајла + + + Set location... + Подесите локацију... + + + Preview file... + Приказ датотеке... + + + Limit upload rate... + Ограничење брзине слања... + + + Limit download rate... + Ограничење брзине преузимања... + + + Move up + i.e. move up in the queue + Премести навише + + + Move down + i.e. Move down in the queue + Премести надоле + + + Move to top + i.e. Move to top of the queue + Премести на врх + + + Move to bottom + i.e. Move to bottom of the queue + Премести на дно + + + Priority + Приоритет + + + Resume + Resume/start the torrent + Настави + + + Pause + Pause the torrent + Пауза + + + Delete + Delete the torrent + Обриши + + + Limit share ratio... + Ограничење односа дељења... + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + Однос ограничења слања/преузимања торента + + + Use global ratio limit + Користи општи однос ограничења + + + buttonGroup + дугмад Група + + + Set no ratio limit + Постави без односа ограничења + + + Set ratio limit to + Постави односа ограничења на + + + + UsageDisplay + + Usage: + Начин употребе: + + + displays program version + прикажи верзију програма + + + disable splash screen + онемогући уводни екран + + + displays this help message + прикажи ову поруку о помоћи + + + changes the webui port (current: %1) + промени Веб КИ порт (тренутно: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [фајлови или urls]:преузимање торента које чини корисник (опционо) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + Желео бих да се захвалим следећим људима који су добровољно превели qBittorrent: + + + Please contact me if you would like to translate qBittorrent into your own language. + Контактирајте ме ако желите да преведете qBittorrent на свој језик. + + + + addPeerDialog + + Peer addition + Додавање (peer)учесника + + + IP + IP + + + Port + Порт + + + + addTorrentDialog + + Torrent addition dialog + Торент дијалог додавања + + + Save path: + Сачувај у: + + + ... + ... + + + Torrent size: + Величина Торента: + + + Unknown + Непознат-а + + + Free disk space: + Слободан простор на диску: + + + Label: + Label-Ознака,Маркер + Ознака: + + + Torrent content: + Садржај Торента: + + + Download in sequential order (slower but good for previewing) + Пренеси секвенционално (споро, али боље за преглед) + + + Skip file checking and start seeding immediately + Прескочи проверу фајла и одмах стартуј донирање + + + Add to download list in paused state + Додај на листу преузимања у стању паузе + + + Add + Додај + + + Cancel + Откажи + + + Normal + Нормалан + + + High + Висок + + + Maximum + Максималан + + + Select All + Селектуј све + + + Select None + Деселектуј + + + Do not download + Не преузимај + + + + authentication + + Tracker authentication + Аутентификација пратилаца + + + Tracker: + Пратилац: + + + Login + Логовање + + + Username: + Корисничко име: + + + Password: + Лозинка: + + + Log in + Логуј се + + + Cancel + Откажи + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + Потврда брисања - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + Да ли сте сигурни да желите да обришете селектоване Торенте са трансфер листе? + + + Remember choice + Запамти избор + + + Also delete the files on the hard disk + Такође избриши датотеке на чврстом диску + + + + createTorrentDialog + + Cancel + Откажи + + + Torrent Creation Tool + Алат креирања Торента + + + Torrent file creation + Креирање Торент фајла + + + Add file + Додај фајл + + + Add folder + фасцикла-фолдер + Додај фасциклу + + + Announce urls (trackers): + trackers-пратиоци + Објави urls (пратиоци): + + + Comment (optional): + Коментар (опционо): + + + Web seeds urls (optional): + Веб донори urls (опционо): + + + File or folder to add to the torrent: + фасцикла-фолдер + Фајл или фасцикла за додавање у Торент: + + + Piece size: + Делови величине: + + + 32 KiB + 32 KiB + + + 64 KiB + 64 KiB + + + 128 KiB + 128 KiB + + + 256 KiB + 256 KiB + + + 512 KiB + 512 KiB + + + 1 MiB + 1 MiB + + + 2 MiB + 2 MiB + + + 4 MiB + 4 MiB + + + Private (won't be distributed on DHT network if enabled) + Приватност (неће бити дистрибуиран на DHT мрежу ако је омогућена) + + + Start seeding after creation + Стартуј донирање после креирања + + + Create and save... + Креирај и сачувај... + + + Progress: + Напредак: + + + Tracker URLs: + URLs-Веб адресе + Пратилац URLs: + + + Web seeds urls: + URL-Веб адреса + Веб донори URLs: + + + Comment: + Коментар: + + + Auto + Аутоматски + + + + createtorrent + + Select destination torrent file + Изаберите дестинацију торент фајла + + + Torrent Files + Торент Фајлови + + + No input path set + Није унета путања + + + Please type an input path first + Молим прво упишите улазну путању + + + Torrent creation + Креирање Торента + + + Torrent was created successfully: + Торент је креиран успешно: + + + Select a folder to add to the torrent + Селектујте фасциклу коју додајете у торент + + + Please type an announce URL + Молим упишите URL оглашавача + + + Torrent creation was unsuccessful, reason: %1 + Креирање Торента је неуспешно, разлог: %1 + + + Announce URL: + Tracker URL + Објављени URL: + + + Please type a web seed url + url-интернет адреса + Молим упишите url веб донора + + + Web seed URL: + URL-интернет адреса + URL Веб донора: + + + Select a file to add to the torrent + Селектујте фајл који додајете у торент + + + Created torrent file is invalid. It won't be added to download list. + Креирана Торент датотека је неважећа. Неће бити додата у листу за преузимање. + + + + downloadFromURL + + Download Torrents from URLs + URL-интенет адреса + Преузимање Торента са URL-а + + + Only one URL per line + URL-интенет адреса + Само један URL по линији + + + Download + Преузми + + + Cancel + Откажи + + + Download from urls + URL-интенет адреса + Преузимање са urls + + + No URL entered + URL-интенет адреса + URL није унет + + + Please type at least one URL. + URL-интенет адреса + Молим упишите најмање један URL. + + + Add torrent links + Додај торент линкове + + + Both HTTP and Magnet links are supported + Оба, HTTP и Magnet линкови су подржани + + + + downloadThread + + I/O Error + И/О Грешка + + + The remote host name was not found (invalid hostname) + Име удаљеног домаћина није пронађено (неважеће hostname) + + + The operation was canceled + Операција је отказана + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Удаљени сервер је прерано затворио конекцију, пре него што је цео одговор примљен и обрађен + + + The connection to the remote server timed out + Конекција на удаљени сервер је временски истекла (покушајте поново) + + + SSL/TLS handshake failed + SSL/TLS управљање неуспешно + + + The remote server refused the connection + Удаљени сервер не прихвата конекцију + + + The connection to the proxy server was refused + Конекција на прокси сервер је одбијена + + + The proxy server closed the connection prematurely + Прокси сервер је превремено затворио конекцију + + + The proxy host name was not found + Назив прокси сервера није пронађен + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Време повезивања са прокси-јем је истекло, или прокси није одговорио када је захтев послат + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Прокси захтева проверу идентитета да би испунио захтев али не прихвата понуђене акредитиве + + + The access to the remote content was denied (401) + Приступ удаљеном садржају је одбијен (401) + + + The operation requested on the remote content is not permitted + Захтевана операција за удаљеним садржајем се не одобрава + + + The remote content was not found at the server (404) + Захтевани садржај, није пронађен на серверу (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Удаљени сервер захтева ауторизацију за слање садржаја, али дати акредитиви нису прихваћени + + + The Network Access API cannot honor the request because the protocol is not known + Мрежни приступ API-ја не може да се прихвати јер протокол није познат + + + The requested operation is invalid for this protocol + Захтевана операција је погрешна за овај протокол + + + An unknown network-related error was detected + Непозната грешка у вези са мрежом је откривена + + + An unknown proxy-related error was detected + Непозната грешка у вези са прокси-јем је откривена + + + An unknown error related to the remote content was detected + Непозната грешка у вези са удаљеним садржајем је откривена + + + A breakdown in protocol was detected + Детектован је проблем са протоколом + + + Unknown error + Непозната грешка + + + + engineSelect + + Search plugins + plugins-додаци + Претраживачки додаци + + + Installed search engines: + Инсталирани претраживачки модули: + + + Name + Име + + + Url + Url (адреса) + + + Enabled + Доступан + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Преузмите нови додатак за претраживање овде: <a href="http:plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + Install a new one + Инсталирајте нови + + + Check for updates + Проверите за надоградњу + + + Close + Затвори + + + Enable + Омогући + + + Disable + Онемогући + + + Uninstall + Деинсталирај + + + + engineSelectDlg + + Uninstall warning + Деинсталационо упозорење + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + додатак-plugins + Неки додаци нису могли бити деинсталирани јер су укључени у qBittorrent. + Само оне које сте додали можете деинсталирати. +Међутим, ови додаци су онемогућени. + + + Uninstall success + Деинсталација успешна + + + Select search plugins + додатак-plugins + Изаберите додатак за претраживач + + + qBittorrent search plugins + додатак-plugins + qBittorrent претраживачки додатак + + + Search plugin install + додатак-plugin + Претраживачки додатак инсталација + + + Yes + Да + + + No + Не + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Новија верзија %1 претраживачких додатака је већ инсталирана. + + + Search plugin update + Претраживачки додаци ажурирање + + + Sorry, update server is temporarily unavailable. + Жао нам је, сервер за ажурирање је привремено недоступан. + + + All your plugins are already up to date. + Сви ваши додаци су већ ажурни. + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 претраживачки додаци нису могли бити ажурирани, задржите стару верзију. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 претраживачки додаци нису могли бити инсталирани. + + + All selected plugins were uninstalled successfully + Сви изабрани додаци су деинсталирани успешно + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 претраживачки додаци су успешно ажурирани. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1 претраживачки додаци су успешно инсталирани. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Жалим, %1 инсталирање претраживачких додатака није успело. + + + New search engine plugin URL + Нови додатак претраживачког модула URL + + + URL: + URL-интернет адреса + URL: + + + + misc + + B + bytes + бајтова + B + + + KiB + kibibytes (1024 bytes) + KiB + + + MiB + mebibytes (1024 kibibytes) + MiB + + + GiB + gibibytes (1024 mibibytes) + GiB + + + TiB + tebibytes (1024 gibibytes) + TiB + + + Unknown + Unknown (size) + Непознат-a (величина) + Непознат-а + + + Unknown + Непознат-а + + + < 1m + < 1 minute + < 1 минута + < 1m + + + %1m + e.g: 10minutes + e.g: 10минута + %1m + + + %1h %2m + e.g: 3hours 5minutes + %1h%2m + + + %1d %2h + e.g: 2days 10hours + %1d %2h + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent ће искључити рачунар сада, јер су сва преузимања завршена. + + + + options_imp + + Choose export directory + Изаберите директоријум за извоз + + + Choose a save directory + Изаберите директоријум за чување + + + Choose an ip filter file + Изаберите неки ip филтер фајл + + + Add directory to scan + Додај директоријум за скенирање + + + Folder is already being watched. + Фолдер-Фасцикла-Директоријум + Фолдер је већ надгледан. + + + Folder does not exist. + Фолдер-Фасцикла-Директоријум + Фолдер не постоји. + + + Folder is not readable. + Фолдер-Фасцикла-Директоријум + Фолдер се не може прочитати. + + + Failure + Неуспешно + + + Failed to add Scan Folder '%1': %2 + Неуспешно додавање Фолдера Скенирања '%1': %2 + + + Filters + Филтери + + + Parsing error + Анализа грешака + + + Failed to parse the provided IP filter + Неспешна анализа датог IP филтера + + + Succesfully refreshed + Успешно обновљени + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Успешна анализа датог IP филтера: %1 правила су примењена. + + + Successfully refreshed + Успешно обновљен + + + SSL Certificate (*.crt) + SSL Сертификат (*.crt) + + + SSL Key (*.key) + SSL Кључ (*.key) + + + Invalid key + Погрешан кључ + + + This is not a valid SSL key. + Ово није валидан SSL кључ. + + + Invalid certificate + Неважећи сертификат + + + This is not a valid SSL certificate. + Ово није валидан SSL сертификат. + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + + pluginSourceDlg + + Plugin source + додатак-plugin + Додатак сорс + + + Search plugin source: + додатак-plugin + Претраживачки додатак сорс: + + + Local file + Локални фајл + + + Web link + Веб линк + + + + preview + + Preview selection + Избор приказа + + + File preview + Приказ датотеке + + + The following files support previewing, <br>please select one of them: + Следећи фајлови подржавају приказ, <br>молим изаберите један од њих: + + + Preview + Прикажи + + + Cancel + Откажи + + + + previewSelect + + Preview impossible + Приказ немогућ + + + Sorry, we can't preview this file + Жалим не могу да прикажем овај фајл + + + Name + Име + + + Size + Величина + + + Progress + Напредак + + + + search_engine + + Search + Претраживање + + + Status: + Статус: + + + Stopped + Стопиран + + + Download + Преузимање + + + Search engines... + Претраживачки модули... + + + Go to description page + Иди на веб страну са описом + + + + torrentAdditionDialog + + Unable to decode magnet link: + Не могу да декодирам магнет линк: + + + Magnet Link + Магнет Линк + + + Unable to decode torrent file: + Не могу да декодирам Торент фајл: + + + Rename... + Преименуј... + + + Rename the file + Преименуј фајл + + + New name: + Ново име: + + + The file could not be renamed + Фајл не може бити преименован + + + This file name contains forbidden characters, please choose a different one. + Ово име фајла садржи недозвољене карактере, молим изаберите неко друго. + + + This name is already in use in this folder. Please use a different name. + Ово име је већ у употреби у овом фолдеру. Молим изаберите неко друго. + + + The folder could not be renamed + Фолдер не може бити преименован + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 остаје након преузетог Торента) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 више је потребно ради преузимања) + + + Choose save path + Изабери путању чувања + + + Empty save path + Празна путања чувања + + + Please enter a save path + Молим унесите путању за чување фајла + + + Save path creation error + Грешка креирања путање чувања + + + Could not create the save path + Не могу да креирам путању за чување фајла + + + Invalid label name + Погрешно име ознаке + + + Please don't use any special characters in the label name. + Молимо Вас да не користите специјалне карактере у имену ознаке. + + + Seeding mode error + Грешка у режиму донирања + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Висте изабрали да прескочите проверу датотеке. Међутим, локални фајлови изгледа не постоје у одредишном директоријуму. Молим онемогућите ову функцију или ажурирајте путању фајла. + + + Invalid file selection + Погрешан избор датотеке + + + You must select at least one file in the torrent + Морате изабрати бар једну датотеку за Торент + + + Priority + Приоритет + + + diff --git a/src/lang/qbittorrent_sv.qm b/src/lang/qbittorrent_sv.qm new file mode 100644 index 0000000000000000000000000000000000000000..792c68a84f6d1910cba01e65042733dc5c11f2b9 GIT binary patch literal 118572 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 literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_sv.ts b/src/lang/qbittorrent_sv.ts new file mode 100644 index 000000000..79ab54bb2 --- /dev/null +++ b/src/lang/qbittorrent_sv.ts @@ -0,0 +1,5568 @@ + + + + + AboutDlg + + About qBittorrent + Om qBittorrent + + + About + Om + + + Author + Upphovsman + + + Name: + Namn: + + + Country: + Land: + + + E-mail: + E-post: + + + Christophe Dumez + Christophe Dumez + + + France + Frankrike + + + Translation + Översättning + + + License + Licens + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + chris@qbittorrent.org + chris@qbittorrent.org + + + Thanks to + Tack till + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">En Bittorrent-klient programmerad i C++, baserad på Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">och libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Webbplats:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent på Freenode</span></p></body></html> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">En avancerad BitTorrent-klient programmerad i C++, baserad på Qt4 toolkit och libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Webbplats:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Felhantering:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent på Freenode</span></p></body></html> + + + + AdvancedSettings + + Property + Egenskap + + + Value + Värde + + + Ignore transfer limits on local network + Ignorera överföringsgränser på lokalt nätverk + + + Include TCP/IP overhead in transfer limits + Inkludera TCP/IP-overhead i överföringsgränser + + + Disk write cache size + Storlek för diskskrivningscache + + + MiB + MiB + + + Outgoing ports (Min) [0: Disabled] + Utgående portar (Min) [0: Inaktiverat] + + + Outgoing ports (Max) [0: Disabled] + Utgående portar (Max) [0: Inaktiverat] + + + Recheck torrents on completion + Kontrollera torrentfiler igen vid färdigställande + + + Transfer list refresh interval + Uppdateringsintervall för överföringslista + + + ms + milliseconds + ms + + + Resolve peer countries (GeoIP) + Slå upp klienternas länder (GeoIP) + + + Resolve peer host names + Slå upp klienternas värdnamn + + + Maximum number of half-open connections [0: Disabled] + Maximalt antal halvöppna anslutningar [0: inaktiverat] + + + Strict super seeding + Strikt "super seeding" + + + Network Interface (requires restart) + Nätverksgränssnitt (kräver omstart) + + + Any interface + i.e. Any network interface + Valfritt gränssnitt + + + Display program notification balloons + Visa programnotifieringar som ballonger + + + Enable embedded tracker + Aktivera inbäddad bevakare + + + Embedded tracker port + Port för inbäddad bevakare + + + Check for software updates + Leta efter programuppdateringar + + + Use system icon theme + Använd systemets ikontema + + + Confirm torrent deletion + Bekräfta borttagning av torrent + + + IP Address to report to trackers (requires restart) + IP-adress att rapportera till bevakare (kräver omstart) + + + Display program on-screen notifications + Visa programmet på skärmnotifieringar + + + Setting + Inställning + + + Value + Value set for this setting + Värde + + + Exchange trackers with other peers + + + + + AutomatedRssDownloader + + Automated RSS Downloader + Automatiserad RSS-hämtning + + + Enable the automated RSS downloader + Aktivera automatisk RSS-hämtning + + + Download rules + Hämtningsregler + + + Rule definition + Regeldefinition + + + Must contain: + Måste innehålla: + + + Must not contain: + Får inte innehålla: + + + ... + ... + + + Assign label: + Tilldela etikett: + + + Apply rule to feeds: + Tillämpa regel på webbkanaler: + + + Matching RSS articles + Matchande RSS-inlägg + + + Save to a different directory + Spara till en annan katalog + + + Save to: + Spara till: + + + Import... + Importera... + + + Export... + Exportera... + + + New rule name + Namn för ny regel + + + Please type the name of the new download rule. + Ange namnet för den nya hämtningsregeln. + + + Rule name conflict + Namnkonflikt för regler + + + A rule with this name already exists, please choose another name. + En regel med denna namn finns redan. Välj ett annat namn. + + + Are you sure you want to remove the download rule named %1? + Är du säker på att du vill ta bort hämtningsregeln %1? + + + Are you sure you want to remove the selected download rules? + Är du säker på att du vill ta bort de markerade hämtningsreglerna? + + + Rule deletion confirmation + Bekräfta regelborttagning + + + Destination directory + Målkatalog + + + Invalid action + Ogiltig åtgärd + + + The list is empty, there is nothing to export. + Listan är tom. Det finns ingenting att exportera. + + + Where would you like to save the list? + Var vill du spara listan? + + + Rules list (*.rssrules) + Regellista (*.rssrules) + + + I/O Error + In-/Ut-fel + + + Failed to create the destination file + Misslyckades med att skapa målfilen + + + Please point to the RSS download rules file + Peka ut regelfilen för RSS-hämtning + + + Rules list (*.rssrules *.filters) + Regellista (*.rssrules *.filters) + + + Import Error + Importfel + + + Failed to import the selected rules file + Misslyckades med att importera den valda regelfilen + + + Add new rule... + Lägg till ny regel... + + + Delete rule + Ta bort regel + + + Rename rule... + Byt namn på regel... + + + Delete selected rules + Ta bort markerade regler + + + Rule renaming + Byt namn på regel + + + Please type the new rule name + Ange det nya regelnamnet + + + Use regular expressions + Använd reguljära uttryck + + + Regex mode: use Perl-like regular expressions + Regex-läge: använd Perl-liknande reguljära uttryck + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + Jokerteckensläge: du kan använda<ul><li>? för att matcha ett enda tecken</li><li>* för att matcha noll eller flera tecken</li><li>Blanksteg räknas som AND-operatorer</li></ul> + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + Jokerteckensläge: du kan använda<ul><li>? för att matcha ett enda tecken</li><li>* för att matcha noll eller flera tecken</li><li>| använd som OR-operator</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 har nått maximalt angivet förhållande. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent är bunden till port: TCP/%1 + + + UPnP support [ON] + UPnP-stöd [PÅ] + + + UPnP support [OFF] + UPnP-stöd [AV] + + + NAT-PMP support [ON] + NAT-PMP-stöd [PÅ] + + + NAT-PMP support [OFF] + NAT-PMP-stöd [AV] + + + DHT support [ON], port: UDP/%1 + DHT-stöd [PÅ], port: UDP/%1 + + + DHT support [OFF] + DHT-stöd [AV] + + + PeX support [ON] + PeX-stöd [PÅ] + + + Local Peer Discovery [ON] + Identifiering av lokala klienter [PÅ] + + + Local Peer Discovery support [OFF] + Stöd för identifiering av lokala klienter [AV] + + + Encryption support [ON] + Krypteringsstöd [PÅ] + + + Encryption support [FORCED] + Krypteringsstöd [TVINGAD] + + + Encryption support [OFF] + Krypteringsstöd [AV] + + + Web User Interface Error - Unable to bind Web UI to port %1 + Fel i webbgränssnitt - Kunde inte binda webbgränssnittet till port %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + "%1" togs bort från överföringslistan och hårddisken. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + "%1" togs bort från överföringslistan. + + + '%1' is not a valid magnet URI. + "%1" är inte en giltig magnet-URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + "%1" finns redan i hämtningslistan. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + "%1" återupptogs. (snabbt läge) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + "%1" lades till i hämtningslistan. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Kunde inte avkoda torrent-fil: "%1" + + + This file is either corrupted or this isn't a torrent. + Denna fil är antingen skadad eller så är den inte en torrent-fil. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>blockerades på grund av ditt IP-filter</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>har bannlysts på grund av skadade delar</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekursiv hämtning av filen %1 inbäddad i torrentfilen %2 + + + Unable to decode %1 torrent file. + Kunde inte avkoda torrentfilen %1. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Fel i portmappning, meddelande: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Portmappning lyckades, meddelande: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Snabb återupptagning av data nekades för torrent-filen %1, kontrollerar igen... + + + Url seed lookup failed for url: %1, message: %2 + Uppslag av distributions-url misslyckades för: %1, meddelande: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Hämtar "%1", vänta... + + + Using a disk cache size of %1 MiB + Använder en diskcachestorlek på %1 MiB + + + PeX support [OFF] + PeX-stöd [AV] + + + Restart is required to toggle PeX support + Omstart krävs för att växla PeX-stöd + + + The Web UI is listening on port %1 + Webbgränssnittet lyssnar på port %1 + + + HTTP user agent is %1 + HTTP-användaragent är %1 + + + Reason: %1 + Anledning: %1 + + + Note: new trackers were added to the existing torrent. + Observera: nya bevakare lades till i den befintliga torrentfilen. + + + Note: new URL seeds were added to the existing torrent. + Observera: nya URL-distributörer lades till i den befintliga torrentfilen. + + + An I/O error occured, '%1' paused. + Ett in-/ut-fel inträffade, "%1" har pausats. + + + Removing torrent %1... + Tar bort torrentfilen %1... + + + Pausing torrent %1... + Pausar torrentfilen %1... + + + Error: The torrent %1 does not contain any file. + Fel: Torrentfilen %1 innehåller inte någon fil. + + + File sizes mismatch for torrent %1, pausing it. + Filstorleken stämmer inte för torrentfilen %1, pausar den. + + + + ConsoleDlg + + General + Allmänt + + + Blocked IPs + Blockerade IP + + + qBittorrent log viewer + Loggvisare för qBittorrent + + + + CookiesDlg + + Cookies management + Hantera kakor + + + Key + As in Key/Value pair + Nyckel + + + Value + As in Key/Value pair + Värde + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Vanliga nycklar för kakor är : '%1', '%2'. +Du kan få denna information från inställningarna i din webbläsare. + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + Din dynamiska DNS uppdaterades. + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + Fel i dynamisk DNS: Tjänsten är tillgänglig för tillfället, nytt försök igen om 30 minuter. + + + Dynamic DNS error: hostname supplied does not exist under specified account. + Fel i dynamisk DNS: angivet värdnamn finns inte under angivet konto. + + + Dynamic DNS error: Invalid username/password. + Fel i dynamisk DNS: Ogiltigt användarnamn/lösenord. + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + Fel i dynamisk DNS: qBittorrent svartlistades av tjänsten. Rapportera detta fel på http://bugs.qbittorrent.org. + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + Fel i dynamisk DNS: %1 returnerades av tjänsten. Rapportera detta fel på http://bugs.qbittorrent.org. + + + Dynamic DNS error: Your username was blocked due to abuse. + Fel i dynamisk DNS: Ditt användarnamn blockerades på grund av missbruk. + + + Dynamic DNS error: supplied domain name is invalid. + Fel i dynamisk DNS: angivet domännamn är ogiltigt. + + + Dynamic DNS error: supplied username is too short. + Fel i dynamisk DNS: angivet användarnamn är för kort. + + + Dynamic DNS error: supplied password is too short. + Fel i dynamisk DNS: angivet lösenord är för kort. + + + + DownloadThread + + I/O Error + In-/ut-fel + + + The remote host name was not found (invalid hostname) + Fjärrvärdnamnet hittades inte (ogiltigt värdnamn) + + + The operation was canceled + Åtgärden avbröts + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Fjärrservern stängde anslutningen i förtid innan hela svaret togs emot och behandlades + + + The connection to the remote server timed out + Anslutningen till fjärrservern översteg tidsgränsen + + + SSL/TLS handshake failed + SSL/TLS-handskakning misslyckades + + + The remote server refused the connection + Fjärrservern nekade anslutningen + + + The connection to the proxy server was refused + Anslutningen till proxyservern nekades + + + The proxy server closed the connection prematurely + Proxyservern stängde anslutningen i förtid + + + The proxy host name was not found + Proxyserverns värdnamn hittades inte + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Anslutningen till proxyservern översteg tidsgränsen eller så svarade inte proxyservern på skickad begäran i tid + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Proxyservern kräver autentisering för att kunna ta emot begäran men accepterade inte inloggningsuppgifterna + + + The access to the remote content was denied (401) + Åtkomst till fjärrinnehåll nekades (401) + + + The operation requested on the remote content is not permitted + Begärd åtgärd för fjärrinnehållet tillåts inte + + + The remote content was not found at the server (404) + Fjärrinnehållet hittades inte på servern (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Fjärrservern kräver autentisering för att servera innehållet men angivna inloggningsuppgifter accepterades inte + + + The Network Access API cannot honor the request because the protocol is not known + API för nätverksåtkomst kan inte behandla begäran därför att protokollet inte är känt + + + The requested operation is invalid for this protocol + Begärd åtgärd är ogiltig för detta protokoll + + + An unknown network-related error was detected + Ett okänt nätverksrelaterat fel upptäcktes + + + An unknown proxy-related error was detected + En okänt fel relaterat till proxyservern upptäcktes + + + An unknown error related to the remote content was detected + Ett okänt fel relaterat till fjärrinnehållet upptäcktes + + + A breakdown in protocol was detected + Ett haveri i protokollet upptäcktes + + + Unknown error + Okänt fel + + + + EventManager + + %1/s + e.g. 120 KiB/s + %1/s + + + Working + Fungerar + + + Updating... + Uppdaterar... + + + Not working + Fungerar inte + + + Not contacted yet + Inte kontaktad ännu + + + this session + denna session + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Distribuerad i %1 + + + %1 max + e.g. 10 max + %1 max + + + + ExecutionLog + + Form + Formulär + + + General + Allmänt + + + Blocked IPs + Blockerade IP + + + + FeedDownloader + + RSS Feed downloader + Hämta RSS-kanal + + + RSS feed: + RSS-kanal: + + + Feed name + Kanalnamn + + + Automatically download torrents from this feed + Hämta automatiskt torrentfiler från denna kanal + + + Download filters + Hämtningsfilter + + + Filters: + Filter: + + + Filter settings + Filterinställningar + + + Matches: + Matchar: + + + Does not match: + Matchar inte: + + + Destination folder: + Målmapp: + + + ... + ... + + + Filter testing + Testa filter + + + Torrent title: + Torrent-titel: + + + Result: + Resultat: + + + Test + Testa + + + Import... + Importera... + + + Export... + Exportera... + + + Rename filter + Byt namn på filter + + + Remove filter + Ta bort filter + + + Add filter + Lägg till filter + + + + FeedDownloaderDlg + + New filter + Nytt filter + + + Please choose a name for this filter + Välj ett namn för detta filter + + + Filter name: + Filternamn: + + + Invalid filter name + Ogiltigt filternamn + + + The filter name cannot be left empty. + Filternamnet får inte lämnas tomt. + + + This filter name is already in use. + Detta filternamn används redan. + + + Filter testing error + Fel vid test av filter + + + Please specify a test torrent name. + Ange ett torrentnamn för test. + + + matches + matchar + + + does not match + matchar inte + + + Select file to import + Välj en fil att importera + + + Filters Files + Filtrerar filer + + + Import successful + Import lyckades + + + Filters import was successful. + Filterimport lyckades. + + + Import failure + Importfel + + + Filters could not be imported due to an I/O error. + Filter kunde inte importeras på grund av ett in-/ut-fel. + + + Select destination file + Välj målfil + + + Export successful + Export lyckades + + + Filters export was successful. + Filterexport lyckades. + + + Export failure + Fel vid export + + + Filters could not be exported due to an I/O error. + Filter kunde inte exporteras på grund av ett in-/ut-fel. + + + Choose save path + Välj sökväg att spara i + + + + FeedList + + Unread + Oläst + + + + FeedListWidget + + RSS feeds + RSS-kanaler + + + Unread + Oläst + + + + GUI + + Open Torrent Files + Öppna Torrent-filer + + + Torrent Files + Torrent-filer + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Hämtning: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Sändning: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 har hämtats färdigt. + + + I/O Error + i.e: Input/Output Error + In/Ut-fel + + + Search + Sök + + + RSS + RSS + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Fel vid url-hämtning + + + Couldn't download file at url: %1, reason: %2. + Kunde inte hämta fil från url:en: %1, anledning: %2. + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Ett in-/ut-fel inträffade för torrentfilen %1. + Anledning: %2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Options were saved successfully. + Inställningarna sparades. + + + Transfers + Överföringar + + + Download completion + Hämtningen är färdig + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Ett antal filer håller fortfarande på att överföras. +Är du säker på att du vill avsluta qBittorrent? + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Allmän hastighetsgräns för sändning + + + Global Download Speed Limit + Allmän hastighetsgräns för hämtning + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Ned: %2/s, Upp: %3/s) + + + Recursive download confirmation + Bekräfta rekursiv hämtning + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrentfilen %1 innehåller flera torrentfiler. Vill du fortsätta med att hämta ner dem? + + + Torrent file association + Associering av torrentfiler + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent är inte standardprogrammet för att öppna torrentfiler eller Magnet-länkar. +Vill du associera qBittorrent med torrentfiler och Magnet-länkar? + + + Transfers (%1) + Överföringar (%1) + + + Yes + Ja + + + No + Nej + + + Never + Aldrig + + + Always + Alltid + + + Exiting qBittorrent + Avslutar qBittorrent + + + + GeoIP + + Australia + Australien + + + Argentina + Argentina + + + Austria + Österrike + + + United Arab Emirates + Förenade arabemiraten + + + Brazil + Brasilien + + + Bulgaria + Bulgarien + + + Belarus + Vitryssland + + + Belgium + Belgien + + + Bosnia + Bosnien + + + Canada + Kanada + + + Czech Republic + Tjeckien + + + China + Kina + + + Costa Rica + Costa Rica + + + Switzerland + Schweiz + + + Germany + Tyskland + + + Denmark + Danmark + + + Algeria + Algeriet + + + Spain + Spanien + + + Egypt + Egypten + + + Finland + Finland + + + France + Frankrike + + + United Kingdom + Storbritannien + + + Greece + Grekland + + + Georgia + Georgien + + + Hungary + Ungern + + + Croatia + Kroatien + + + Italy + Italien + + + India + Indien + + + Israel + Israel + + + Ireland + Irland + + + Iceland + Island + + + Indonesia + Indonesien + + + Japan + Japan + + + South Korea + Sydkorea + + + Luxembourg + Luxemburg + + + Malaysia + Malaysia + + + Mexico + Mexiko + + + Serbia + Serbien + + + Morocco + Marocko + + + Netherlands + Nederländerna + + + Norway + Norge + + + New Zealand + Nya Zealand + + + Portugal + Portugal + + + Poland + Polen + + + Pakistan + Pakistan + + + Philippines + Filippinerna + + + Russia + Ryssland + + + Romania + Rumänien + + + France (Reunion Island) + Frankrike (Reunion Island) + + + Sweden + Sverige + + + Slovakia + Slovakien + + + Singapore + Singapore + + + Slovenia + Slovenien + + + Taiwan + Taiwan + + + Turkey + Turkiet + + + Thailand + Thailand + + + USA + USA + + + Ukraine + Ukraina + + + South Africa + Sydafrika + + + Saudi Arabia + Saudiarabien + + + + HeadlessLoader + + Information + Information + + + To control qBittorrent, access the Web UI at http://localhost:%1 + För att styra qBittorrent, gå in på webbgränssnittet på http://localhost:%1 + + + The Web UI administrator user name is: %1 + Administratörsnamnet för webbgränssnittet är: %1 + + + The Web UI administrator password is still the default one: %1 + Lösenordet för administratören på webbgränssnittet är standardlösenordet: %1 + + + This is a security risk, please consider changing your password from program preferences. + Detta är en säkerhetsrisk så överväg att ändra ditt lösenord från programinställningarna. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + Din IP-adress har bannlysts efter för många felaktiga autentiseringsförsök. + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + H: %1/s - Ö: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + S: %1/s - Ö: %2 + + + + HttpServer + + File + Arkiv + + + Edit + Redigera + + + Help + Hjälp + + + Delete from HD + Ta bort från hårddisk + + + Download Torrents from their URL or Magnet link + Hämta torrent-filer från deras URL eller Magnet-länkar + + + Only one link per line + Endast en länk per rad + + + Download + Hämta + + + Download local torrent + Hämta lokal torrent + + + Torrent files were correctly added to download list. + Torrent-filerna lades till i hämtningslistan. + + + Point to torrent file + Peka till torrent-filen + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Är du säker på att du vill ta bort de markerade torrent-filerna från överföringslistan och hårddisken? + + + Download rate limit must be greater than 0 or disabled. + Hämtningsgränsen måste vara större än 0 eller inaktiverad. + + + Upload rate limit must be greater than 0 or disabled. + Sändningsgränsen måste vara större än 0 eller inaktiverad. + + + Maximum number of connections limit must be greater than 0 or disabled. + Gräns för maximalt antal anslutningar måste vara större än 0 eller inaktiverad. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Gräns för maximalt antal anslutningar per torrent måste vara större än 0 eller inaktiverad. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Gräns för maximalt antal sändningsplatser per torrent måste vara större än 0 eller inaktiverad. + + + Unable to save program preferences, qBittorrent is probably unreachable. + Kunde inte spara programinställningarna. qBittorrent är antagligen inte nåbar. + + + Language + Språk + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Porten som används för inkommande anslutningar måste vara större än 1024 och mindre än 65535. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Porten som används för webbgränssnittet måste vara större än 1024 och mindre än 65535. + + + The Web UI username must be at least 3 characters long. + Användarnamnet för webbgränssnittet måste vara minst 3 tecken långt. + + + The Web UI password must be at least 3 characters long. + Lösenordet för webbgränssnittet måste vara minst 3 tecken långt. + + + Downloaded + Is the file downloaded or not? + Hämtad + + + Save + Spara + + + qBittorrent client is not reachable + qBittorrent-klienten är inte nåbar + + + HTTP Server + HTTP-server + + + Torrent path + Torrentsökväg + + + Torrent name + Torrentnamn + + + The following parameters are supported: + Följande parametrar stöds: + + + + LegalNotice + + Legal Notice + Juridisk information + + + Legal notice + Juridisk information + + + Cancel + Avbryt + + + I Agree + Jag godkänner + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent är ett fildelarprogram. När du kör en torrent så kommer dess data att göras tillgängligt för andra. Och så klart, allt innehåll som du delar ut är fullständigt på ditt ansvar. + +Detta meddelande kommer inte att visas igen. + + + Press %1 key to accept and continue... + Tryck på %1-tangenten för att godkänna och fortsätta... + + + + LineEdit + + Clear the text + Töm texten + + + + MainWindow + + &Edit + R&edigera + + + &File + &Arkiv + + + &Help + &Hjälp + + + Preview file + Förhandsvisa fil + + + Clear log + Töm logg + + + Decrease priority + Sänk prioriteten + + + Increase priority + Öka prioriteten + + + &Tools + Ver&ktyg + + + &View + &Visa + + + &Add File... + &Lägg till fil... + + + E&xit + A&vsluta + + + &Options... + A&lternativ... + + + Add &URL... + Lägg till &URL... + + + Torrent &creator + S&kapa torrent + + + Set upload limit... + Ställ in sändningsgräns... + + + Set download limit... + Ställ in hämtningsgräns... + + + Set global download limit... + Ställ in allmän hämtningsgräns... + + + Set global upload limit... + Ställ in allmän sändningsgräns... + + + &Log viewer... + &Loggvisare... + + + Top &tool bar + Övre ver&ktygsrad + + + Display top tool bar + Visa övre verktygsrad + + + &Speed in title bar + &Hastighet i titellisten + + + Show transfer speed in title bar + Visa överföringshastighet i titellisten + + + Alternative speed limits + Alternativa hastighetsgränser + + + &About + &Om + + + &Pause + &Paus + + + &Delete + &Ta bort + + + P&ause All + P&ausa alla + + + Visit &Website + Besök &webbplatsen + + + Report a &bug + Rapportera ett &fel + + + &Documentation + &Dokumentation + + + &RSS reader + &RSS-läsare + + + Search &engine + Sök&motor + + + Log viewer + Loggvisare + + + Lock qBittorrent + Lås qBittorrent + + + Ctrl+L + Ctrl+L + + + &Resume + &Återuppta + + + R&esume All + Återu&ppta alla + + + Exit + Avsluta + + + Import torrent... + Importera torrent... + + + Donate money + Donera pengar + + + If you like qBittorrent, please donate! + Donera om du tycker om qBittorrent! + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + Ställ in lösenordet... + + + Transfers + Överföringar + + + Torrent file association + Associering av torrentfiler + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent är inte standardprogrammet för att öppna torrentfiler eller Magnet-länkar. +Vill du associera qBittorrent med torrentfiler och Magnet-länkar? + + + UI lock password + Lösenord för gränssnittslåsning + + + Please type the UI lock password: + Ange lösenord för gränssnittslåsning: + + + Password update + Lösenordet har uppdaterats + + + The UI lock password has been successfully updated + Lösenordet för gränssnittslåsning har uppdaterats + + + RSS + RSS + + + Search + Sök + + + Transfers (%1) + Överföringar (%1) + + + Download completion + Hämtningen är färdig + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 har hämtats färdigt. + + + I/O Error + i.e: Input/Output Error + In-/ut-fel + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Ett in-/ut-fel inträffade för torrentfilen %1. + Anledning: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Bekräfta rekursiv hämtning + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrentfilen %1 innehåller flera torrentfiler. Vill du fortsätta med att hämta ner dem? + + + Yes + Ja + + + No + Nej + + + Never + Aldrig + + + Url download error + Fel vid url-hämtning + + + Couldn't download file at url: %1, reason: %2. + Kunde inte hämta fil från url:en: %1. Anledning: %2. + + + Global Upload Speed Limit + Allmän hastighetsgräns för sändning + + + Global Download Speed Limit + Allmän hastighetsgräns för hämtning + + + Invalid password + Ogiltigt lösenord + + + The password is invalid + Lösenordet är ogiltigt + + + Exiting qBittorrent + Avslutar qBittorrent + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Ett antal filer håller fortfarande på att överföras. +Är du säker på att du vill avsluta qBittorrent? + + + Always + Alltid + + + Open Torrent Files + Öppna torrent-filer + + + Torrent Files + Torrent-filer + + + Options were saved successfully. + Inställningarna har sparats. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Hämtning: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Sändning: %1 KiB/s + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Ned: %2/s, Upp: %3/s) + + + A newer version is available + En nyare version finns tillgänglig + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + En nyare version av qBittorrent finns tillgänglig på Sourceforge. +Vill du uppdatera qBittorrent till version %1? + + + Impossible to update qBittorrent + Omöjligt att uppdatera qBittorrent + + + qBittorrent failed to update, reason: %1 + Ett fel uppstod vid uppdatering av qBittorrent. Anledning: %1 + + + &Add torrent file... + &Lägg till torrent-fil... + + + Add &link to torrent... + Lägg till lä&nk till torrent... + + + Import existing torrent... + Importera befintlig torrent-fil... + + + Execution &Log + Körnings&logg + + + Execution Log + Körningslogg + + + Auto-Shutdown on downloads completion + Stäng av automatiskt vid färdig hämtning + + + Exit qBittorrent + Avsluta qBittorrent + + + Suspend system + Försätt datorn i vänteläge + + + Shutdown system + Stäng av datorn + + + Disabled + Inaktiverad + + + The password should contain at least 3 characters + Lösenordet bör innehålla minst 3 tecken + + + + PeerAdditionDlg + + Invalid IP + Ogiltig IP-adress + + + The IP you provided is invalid. + IP-adressen som du angav är inte giltig. + + + + PeerListDelegate + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + Klient + + + Progress + i.e: % downloaded + Förlopp + + + Down Speed + i.e: Download speed + Hämtningshastighet + + + Up Speed + i.e: Upload speed + Sändningshastighet + + + Downloaded + i.e: total data downloaded + Hämtat + + + Uploaded + i.e: total data uploaded + Skickat + + + Ban peer permanently + Bannlys klient permanent + + + Peer addition + Lägg till klient + + + The peer was added to this torrent. + Klienten lades till för denna torrent-fil. + + + The peer could not be added to this torrent. + Klienten kunde inte läggas till för denna torrent-fil. + + + Are you sure? -- qBittorrent + Är du säker? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + Är du säker på att du vill bannlysa de markerade klienterna permanent? + + + &Yes + &Ja + + + &No + &Nej + + + Manually banning peer %1... + Bannlyser klienten %1 manuellt... + + + Upload rate limiting + Begränsar sändningsfrekvens + + + Download rate limiting + Begränsar hämtningsfrekvens + + + Add a new peer... + Lägg till en ny klient... + + + Limit download rate... + Begränsa hämtningshastighet... + + + Limit upload rate... + Begränsa sändningshastighet... + + + Copy IP + Kopiera IP + + + Connection + Anslutning + + + + Preferences + + UI + User Interface + Användargränssnitt + + + Downloads + Hämtningar + + + Connection + Anslutning + + + Bittorrent + Bittorrent + + + Proxy + Proxyserver + + + Web UI + Webbgränssnitt + + + Language: + Språk: + + + (Requires restart) + (Kräver omstart) + + + Visual style: + Visuell stil: + + + Transfer list + Överföringslista + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Använd olika radfärger + + + File system + Filsystem + + + Torrent queueing + Köhantering av torrenter + + + Maximum active downloads: + Maximalt aktiva hämtningar: + + + Maximum active uploads: + Maximalt aktiva sändningar: + + + Maximum active torrents: + Maximalt aktiva torrenter: + + + When adding a torrent + När en torrent läggs till + + + Display torrent content and some options + Visa torrentens innehåll och alternativ + + + Listening port + Lyssningsport + + + Port used for incoming connections: + Port som används för inkommande anslutningar: + + + Random + Slumpmässig + + + Enable UPnP port mapping + Aktivera UPnP-portmappning + + + Enable NAT-PMP port mapping + Aktivera NAT-PMP-portmappning + + + Connections limit + Anslutningsgräns + + + Global maximum number of connections: + Allmänt maximalt antal anslutningar: + + + Maximum number of connections per torrent: + Maximalt antal anslutningar per torrent: + + + Maximum number of upload slots per torrent: + Maximalt antal sändningsplatser per torrent: + + + Upload: + Sändning: + + + Download: + Hämtning: + + + KiB/s + KiB/s + + + Bittorrent features + Bittorrent-funktioner + + + Enable DHT network (decentralized) + Aktivera DHT-nätverk (decentraliserat) + + + Use a different port for DHT and Bittorrent + Använd en annan port för DHT och Bittorrent + + + DHT port: + DHT-port: + + + Enable Peer Exchange / PeX (requires restart) + Aktivera Peer Exchange / PeX (kräver omstart) + + + Enable Local Peer Discovery + Aktivera identifiering av lokala klienter + + + Enabled + Aktiverad + + + Forced + Tvingad + + + Disabled + Inaktiverad + + + Type: + Typ: + + + (None) + (Ingen) + + + HTTP + HTTP + + + Port: + Port: + + + Authentication + Autentisering + + + Username: + Användarnamn: + + + Password: + Lösenord: + + + SOCKS5 + SOCKS 5 + + + HTTP Server + HTTP-server + + + Filter path (.dat, .p2p, .p2b): + Filtersökväg (.dat, .p2p, .p2b): + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP-kommunikation (bevakare, webbdistribution, sökmotor) + + + Host: + Värd: + + + Peer Communications + Klientanslutningar + + + SOCKS4 + SOCKS 4 + + + Speed + Hastighet + + + Global speed limits + Allmänna hastighetsgränser + + + Alternative global speed limits + Alternativa allmänna hastighetsgränser + + + to + time1 to time2 + till + + + Every day + Varje dag + + + Week days + Veckodagar + + + Week ends + Helger + + + Advanced + Avancerat + + + Copy .torrent files to: + Kopiera .torrent-filer till: + + + Remove folder + Ta bort mapp + + + No action + Ingen åtgärd + + + Options + Alternativ + + + Visual Appearance + Visuellt utseende + + + Action on double-click + Åtgärd vid dubbelklick + + + Downloading torrents: + Hämtning av torrentfiler: + + + Start / Stop + Starta / Stoppa + + + Open destination folder + Öppna målmapp + + + Completed torrents: + Färdiga torrentfiler: + + + Desktop + Skrivbord + + + Show splash screen on start up + Visa startskärm vid uppstart + + + Start qBittorrent minimized + Starta qBittorrent minimerad + + + Show qBittorrent icon in notification area + Visa qBittorrent-ikon i notifieringsytan + + + Minimize qBittorrent to notification area + Minimera qBittorrent till notifieringsytan + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Stäng qBittorrent till notifieringsytan + + + Do not start the download automatically + The torrent will be added to download list in pause state + Påbörja inte hämtningen automatiskt + + + Save files to location: + Spara filer till platsen: + + + Append the label of the torrent to the save path + Lägg till etiketten för torrentfilen till sökvägen vid sparning + + + Pre-allocate disk space for all files + Förallokera diskutrymme för alla filer + + + Keep incomplete torrents in: + Behåll ofullständiga torrentfiler i: + + + Append .!qB extension to incomplete files' names + Lägg till filändelsen .!qB till ofullständiga filers namn + + + Automatically add torrents from: + Lägg automatiskt till torrentfiler från: + + + Add folder... + Lägg till mapp... + + + IP Filtering + IP-filtrering + + + Schedule the use of alternative speed limits + Schemalägg användningen av alternativa hastighetsgränser + + + from + from (time1 to time2) + från + + + When: + När: + + + Look for peers on your local network + Leta efter klienter på ditt lokala nätverk + + + Enable Web User Interface (Remote control) + Aktivera webbgränssnittet (fjärrstyrning) + + + Share ratio limiting + Gräns för utdelningsförhållande + + + Seed torrents until their ratio reaches + Distribuera torrentfiler till deras förhållande når + + + then + sedan + + + Pause them + Pausa dem + + + Remove them + Ta bort dem + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Utväxla klienter med kompatibla Bittorrent-klienter (µTorrent, Vuze, ...) + + + Email notification upon download completion + E-postnotifiering vid färdiga hämtningar + + + Destination email: + Mottagare av e-post: + + + SMTP server: + SMTP-server: + + + Run an external program on torrent completion + Kör ett externt program vid färdiga hämtningar + + + Use %f to pass the torrent path in parameters + Använd %f i parametrarna för att skicka med sökvägen till torrentfilen + + + Proxy server + Proxyserver + + + BitTorrent + BitTorrent + + + Start / Stop Torrent + Starta / Stoppa torrent + + + Use UPnP / NAT-PMP port forwarding from my router + Använd UPnP / NAT-PMP-portomdirigering från min router + + + Privacy + Integritet + + + Enable DHT (decentralized network) to find more peers + Aktivera DHT (decentraliserat nätverk) för att hitta fler klienter + + + Use a different port for DHT and BitTorrent + Använd en annan port för DHT och BitTorrent + + + Enable Peer Exchange (PeX) to find more peers + Aktivera Peer Exchange (PeX) för att hitta fler klienter + + + Enable Local Peer Discovery to find more peers + Aktivera Local Peer Discovery för att hitta fler klienter + + + Encryption mode: + Krypteringsläge: + + + Prefer encryption + Föredra kryptering + + + Require encryption + Kräv kryptering + + + Disable encryption + Inaktivera kryptering + + + User Interface + Användargränssnitt + + + Reload the filter + Läs om filtret + + + Behavior + Beteende + + + Language + Språk + + + Power Management + Strömhantering + + + Inhibit system sleep when torrents are active + Förhindra att systemet försätts i vänteläge när torrentfiler är aktiva + + + Bypass authentication for localhost + Kringgå autentisering för localhost + + + Ask for program exit confirmation + Fråga efter bekräftelse för programavslut + + + Use monochrome system tray icon (requires restart) + Använd monokrom ikon för aktivitetsfält (kräver omstart) + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + Följande parametrar stöds: +<ul> +<li>%f: Torrentsökväg</li> +<li>%n: Torrentnamn</li> +</ul> + + + Tray icon style: + Stil för aktivitetsikon: + + + Normal + Normal + + + Monochrome (Dark theme) + Monokrom (mörkt tema) + + + Monochrome (Light theme) + Monokrom (ljust tema) + + + This server requires a secure connection (SSL) + Denna server kräver en säker anslutning (SSL) + + + User Interface Language: + Språk för användargränssnitt: + + + Transfer List + Överföringslista + + + Show qBittorrent in notification area + Visa qBittorrent i notifieringsytan + + + Hard Disk + Hårddisk + + + Listening Port + Lyssningsport + + + Connections Limits + Anslutningsgränser + + + Proxy Server + Proxyserver + + + Torrent Queueing + Torrentkö + + + Share Ratio Limiting + Begränsning av utdelningsförhållande + + + Use UPnP / NAT-PMP to forward the port from my router + Använd UPnP / NAT-PMP för att vidarebefordra porten från min router + + + Update my dynamic domain name + Uppdatera mitt dynamiska domännamn + + + Service: + Tjänst: + + + Register + Registrera + + + Domain name: + Domännamn: + + + Global Rate Limits + Allmänna hastighetsgränser + + + Apply rate limit to uTP connections + Tillämpa hastighetsgräns till uTP-anslutningar + + + Apply rate limit to transport overhead + Tillämpa hastighetsgräns på transport-overhead + + + Alternative Global Rate Limits + Alternativa allmänna hastighetsgränser + + + Schedule the use of alternative rate limits + Schemalägg användning av alternativa hastighetsgränser + + + Enable bandwidth management (uTP) + Aktivera bandbreddshantering (uTP) + + + Otherwise, the proxy server is only used for tracker connections + Om inte kommer proxyservern endast att användas för anslutningar till bevakare + + + Use proxy for peer connections + Använd proxyserver för klientanslutningar + + + Append .!qB extension to incomplete files + Lägg till filändelsen .!qB till ofullständiga filer + + + Use HTTPS instead of HTTP + Använd HTTPS istället för HTTP + + + Import SSL Certificate + Importera SSL-certifikat + + + Import SSL Key + Importera SSL-nyckel + + + Certificate: + Certifikat: + + + Key: + Nyckel: + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information om certifikat</a> + + + + PreviewSelect + + Name + Namn + + + Size + Storlek + + + Progress + Förlopp + + + Preview impossible + Förhandsvisning inte möjlig + + + Sorry, we can't preview this file + Tyvärr, vi kan inte förhandsvisa den här filen + + + + PropListDelegate + + Normal + Normal (priority) + Normal + + + High + High (priority) + Hög + + + Maximum + Maximum (priority) + Maximal + + + Not downloaded + Inte hämtad + + + Mixed + Mixed (priorities + Blandat + + + + PropTabBar + + General + Allmänt + + + Trackers + Bevakare + + + Peers + Klienter + + + Files + Filer + + + HTTP Sources + HTTP-källor + + + Content + Innehåll + + + + PropertiesWidget + + Save path: + Sökväg att spara i: + + + Torrent hash: + Torrent-hash: + + + Comment: + Kommentar: + + + Share ratio: + Utdelningsförhållande: + + + General + Allmänt + + + Trackers + Bevakare + + + URL seeds + URL-distributörer + + + Files + Filer + + + Priority + Prioritet + + + New url seed + New HTTP source + Ny url-distribution + + + New url seed: + Ny url-distribution: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + Den här url-distributionen finns redan i listan. + + + Choose save path + Välj sökväg att spara i + + + Save path creation error + Fel vid skapandet av sökväg + + + Could not create the save path + Kunde inte skapa sökväg att spara i + + + Downloaded: + Hämtat: + + + Transfer + Överför + + + Uploaded: + Skickat: + + + Wasted: + Förkastat: + + + UP limit: + Sändgräns: + + + DL limit: + Hämtgräns: + + + Time elapsed: + Tid förfluten: + + + Connections: + Anslutningar: + + + Information + Information + + + Created on: + Skapades den: + + + Peers + Klienter + + + Normal + Normal + + + Maximum + Maximal + + + High + Hög + + + this session + denna session + + + %1 max + e.g. 10 max + %1 max + + + Availability: + Tillgänglighet: + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Distribuerad i %1 + + + Rename... + Byt namn... + + + New name: + Nytt namn: + + + The file could not be renamed + Det gick inte att byta namn på filen + + + This name is already in use in this folder. Please use a different name. + Detta namn används redan i denna mapp. Använd ett annat namn. + + + The folder could not be renamed + Det gick inte att byta namn på mappen + + + Rename the file + Byt namn på filen + + + I/O Error + In/Ut-fel + + + This file does not exist yet. + Denna fil finns ännu inte. + + + This folder does not exist yet. + Denna mapp finns inte ännu. + + + This file name contains forbidden characters, please choose a different one. + Detta filnamn innehåller förbjudna tecken. Välj ett annat filnamn. + + + Reannounce in: + Annonsering igen om: + + + Select All + Markera allt + + + Select None + Markera ingen + + + Do not download + Hämta inte + + + Pieces size: + Delstorlek: + + + Time active: + Time (duration) the torrent is active (not paused) + Tid aktiv: + + + Torrent content: + Torrentfilens innehåll: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1 har nått maximalt angivet förhållande. + + + Removing torrent %1... + Tar bort torrentfilen %1... + + + Pausing torrent %1... + Pausar torrentfilen %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent är bunden till port: TCP/%1 + + + UPnP support [ON] + UPnP-stöd [PÅ] + + + UPnP support [OFF] + UPnP-stöd [AV] + + + NAT-PMP support [ON] + NAT-PMP-stöd [PÅ] + + + NAT-PMP support [OFF] + NAT-PMP-stöd [AV] + + + HTTP user agent is %1 + HTTP-användaragent är %1 + + + Using a disk cache size of %1 MiB + Använder en diskcachestorlek på %1 MiB + + + DHT support [ON], port: UDP/%1 + DHT-stöd [PÅ], port: UDP/%1 + + + DHT support [OFF] + DHT-stöd [AV] + + + PeX support [ON] + PeX-stöd [PÅ] + + + PeX support [OFF] + PeX-stöd [AV] + + + Restart is required to toggle PeX support + Omstart krävs för att växla PeX-stöd + + + Local Peer Discovery [ON] + Identifiering av lokala klienter [PÅ] + + + Local Peer Discovery support [OFF] + Stöd för Local Peer Discovery [AV] + + + Encryption support [ON] + Krypteringsstöd [PÅ] + + + Encryption support [FORCED] + Krypteringsstöd [TVINGAD] + + + Encryption support [OFF] + Krypteringsstöd [AV] + + + Embedded Tracker [ON] + Inbäddad bevakare [PÅ] + + + Failed to start the embedded tracker! + Misslyckades med att starta den inbäddade bevakaren! + + + Embedded Tracker [OFF] + Inbäddad bevakare [OFF] + + + The Web UI is listening on port %1 + Webbgränssnittet lyssnar på port %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Fel i webbgränssnitt - Kunde inte binda webbgränssnittet till port %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + "%1" togs bort från överföringslistan och hårddisken. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + "%1" togs bort från överföringslistan. + + + '%1' is not a valid magnet URI. + "%1" är inte en giltig magnet-URI. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + "%1" finns redan i hämtningslistan. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + "%1" återupptogs. (snabbt läge) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + "%1" lades till i hämtningslistan. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Kunde inte avkoda torrent-fil: "%1" + + + This file is either corrupted or this isn't a torrent. + Denna fil är antingen skadad eller så är den inte en torrent-fil. + + + Error: The torrent %1 does not contain any file. + Fel: Torrentfilen %1 innehåller inte någon fil. + + + Note: new trackers were added to the existing torrent. + Observera: nya bevakare lades till i den befintliga torrentfilen. + + + Note: new URL seeds were added to the existing torrent. + Observera: nya URL-distributörer lades till i den befintliga torrentfilen. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>blockerades på grund av ditt IP-filter</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>har bannlysts på grund av skadade delar</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Rekursiv hämtning av filen %1 inbäddad i torrentfilen %2 + + + Unable to decode %1 torrent file. + Kunde inte avkoda torrentfilen %1. + + + Torrent name: %1 + Torrentnamn: %1 + + + Torrent size: %1 + Torrentstorlek: %1 + + + Save path: %1 + Sparningssökväg: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrentfilen hämtades på %1. + + + Thank you for using qBittorrent. + Tack för att du använder qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1 har hämtats färdigt + + + An I/O error occured, '%1' paused. + Ett in-/ut-fel inträffade, "%1" har pausats. + + + Reason: %1 + Anledning: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Fel i portmappning, meddelande: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Portmappning lyckades, meddelande: %1 + + + File sizes mismatch for torrent %1, pausing it. + Filstorleken stämmer inte för torrentfilen %1, pausar den. + + + Fast resume data was rejected for torrent %1, checking again... + Snabb återupptagning av data nekades för torrent-filen %1, kontrollerar igen... + + + Url seed lookup failed for url: %1, message: %2 + Uppslag av distributions-url misslyckades för: %1, meddelande: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Hämtar "%1", vänta... + + + The network interface defined is invalid: %1 + Nätverksgränssnittet som definierats är ogiltigt: %1 + + + Trying any other network interface available instead. + Försöker istället på andra tillgängliga nätverksgränssnitt. + + + Listening on IP address %1 on network interface %2... + Lysnar på IP-adress %1 på nätverksgränssnittet %2... + + + Failed to listen on network interface %1 + Misslyckades med att lyssna på nätverksgränssnittet %1 + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP-stöd [PÅ] + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP-stöd [AV] + + + Local Peer Discovery support [ON] + Stöd för Local Peer Discovery [PÅ] + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Tolkade det angivna IP filtret: %1 regler tillämpades. + + + Error: Failed to parse the provided IP filter. + Fel: Misslyckades med att tolka det angivna IP-filtret. + + + Reporting IP address %1 to trackers... + Rapporterar IP-adressen %1 till bevakare... + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Datorn kommer nu att försättas i viloläge om du inte avbryter inom 15 sekunder... + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Datorn kommer nu att stängas av om du inte avbryter inom 15 sekunder... + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + qBittorrent kommer nu att avslutas om du inte avbryter inom 15 sekunder... + + + + RSS + + Search + Sök + + + Delete + Ta bort + + + Rename + Byt namn + + + Refresh RSS streams + Uppdatera RSS-kanaler + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrentar:</span> <span style=" font-style:italic;">(dubbelklicka för att hämta)</span></p></body></html> + + + Download torrent + Hämta torrent + + + Open news URL + Öppna URL för nyheter + + + Copy feed URL + Kopera URL för kanal + + + New subscription + Ny prenumeration + + + Mark items read + Markera objekt som lästa + + + Update all + Uppdatera alla + + + Update all feeds + Uppdatera alla kanaler + + + RSS feeds + RSS-kanaler + + + Update + Uppdatera + + + Feed URL + URL för kanal + + + Article title + Artikelns titel + + + Rename... + Byt namn... + + + New subscription... + Ny prenumeration... + + + New folder... + Ny mapp... + + + Manage cookies... + Hantera kakor... + + + Settings... + Inställningar... + + + RSS Downloader... + RSS-hämtning... + + + + RSSImp + + Please type a rss stream url + Ange en url för en RSS-kanal + + + Stream URL: + URL för kanal: + + + Are you sure? -- qBittorrent + Är du säker? -- qBittorrent + + + &Yes + &Ja + + + &No + &Nej + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + Den här kanalen finns redan i listan. + + + Date: + Datum: + + + Author: + Upphovsman: + + + Please choose a folder name + Välj ett mappnamn + + + Folder name: + Mappnamn: + + + New folder + Ny mapp + + + Are you sure you want to delete these elements from the list? + Är du säker på att du vill ta bort dessa element från listan? + + + Are you sure you want to delete this element from the list? + Är du säker på att du vill ta bort detta element från listan? + + + Please choose a new name for this RSS feed + Välj ett nytt namn för denna RSS-kanal + + + New feed name: + Nytt kanalnamn: + + + Name already in use + Namnet används redan + + + This name is already used by another item, please choose another one. + Detta namn används redan av ett annat objekt. Välj ett annat namn. + + + Overwrite attempt + Överskrivningsförsök + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Du kan inte skriva över %1 objekt. + + + Unread + Oläst + + + + RssArticle + + No description available + Ingen beskrivning tillgänglig + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + Hämtar automatiskt torrentfilen %1 från RSS-kanalen %2... + + + + RssItem + + No description available + Ingen beskrivning tillgänglig + + + + RssSettings + + RSS feeds refresh interval: + Uppdateringsintervall för RSS-kanaler: + + + minutes + minuter + + + Maximum number of articles per feed: + Maximalt antal inlägg per RSS-kanal: + + + + RssSettingsDlg + + RSS Reader Settings + Inställningar för RSS-läsare + + + RSS feeds refresh interval: + Uppdateringsintervall för RSS-kanaler: + + + minutes + minuter + + + Maximum number of articles per feed: + Maximalt antal inlägg per RSS-kanal: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Hämtar automatiskt torrentfilen %1 från RSS-kanalen %2... + + + + ScanFoldersModel + + Watched Folder + Bevakad mapp + + + Download here + Hämta hit + + + + SearchCategories + + All categories + Alla kategorier + + + Movies + Filmer + + + TV shows + TV-program + + + Music + Musik + + + Games + Spel + + + Anime + Anime + + + Software + Programvara + + + Pictures + Bilder + + + Books + Böcker + + + + SearchEngine + + Cut + Klipp ut + + + Copy + Kopiera + + + Paste + Klistra in + + + Clear field + Töm fältet + + + Clear completion history + Töm kompletteringshistorik + + + Empty search pattern + Tomt sökmönster + + + Please type a search pattern first + Ange ett sökmönster först + + + Results + Resultat + + + Searching... + Söker... + + + Search Engine + Sökmotor + + + Search has finished + Sökningen är färdig + + + An error occured during search... + Ett fel inträffade under sökningen... + + + Search aborted + Sökningen avbröts + + + Search returned no results + Sökningen returnerade inga resultat + + + Results + i.e: Search results + Resultat + + + Unknown + Okänt + + + Search + Sök + + + Download error + Hämtningsfel + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Python-installationen kunde inte hämtas. Anledning: %1. +Installera den manuellt. + + + Missing Python Interpreter + Python-tolk saknas + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x krävs för att använda sökmotorn men det verkar som om den inte är installerad. +Vill du installera den nu? + + + Confirmation + Bekräftelse + + + Are you sure you want to clear the history? + Är du säker på att du vill tömma historiken? + + + + SearchTab + + Name + i.e: file name + Namn + + + Size + i.e: file size + Storlek + + + Seeders + i.e: Number of full sources + Distributörer + + + Leechers + i.e: Number of partial sources + Reciprokörer + + + Search engine + Sökmotor + + + + ShutdownConfirmDlg + + Shutdown confirmation + Bekräfta avstängning + + + + SpeedLimitDialog + + KiB/s + KiB/s + + + + StatusBar + + Connection status: + Anslutningsstatus: + + + No direct connections. This may indicate network configuration problems. + Inga direktanslutningar. Detta kan betyda problem med nätverkskonfigurationen. + + + DHT: %1 nodes + DHT: %1 noder + + + Connection Status: + Anslutningsstatus: + + + Online + Ansluten + + + Global Download Speed Limit + Allmän hastighetsgräns för hämtning + + + Global Upload Speed Limit + Allmän hastighetsgräns för sändning + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + H: %1/s - Ö: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + S: %1/s - Ö: %2 + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + H: %1 B/s - Ö: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + S: %1 B/s - Ö: %2 + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Frånkopplad. Detta betyder oftast att qBittorrent misslyckades med att lyssna på den valda porten för inkommande anslutningar. + + + Click to disable alternative speed limits + Klicka för att inaktivera alternativa hastighetsgränser + + + Click to enable alternative speed limits + Klicka för att aktivera alternativa hastighetsgränser + + + qBittorrent needs to be restarted + qBittorrent behöver startas om + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent har uppdaterats och behöver startas om för att ändringarna ska bli aktiva. + + + Click to switch to alternative speed limits + Klicka för att växla till alternativa hastighetsgränser + + + Click to switch to regular speed limits + Klicka för att växla till vanliga hastighetsgränser + + + %1/s + Per second + %1/s + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + Välj en mapp att lägga till i torrent-filen + + + Select a file to add to the torrent + Välj en fil att lägga till i torrent-filen + + + Please type an announce URL + Ange en annonserings-url + + + Announce URL: + Tracker URL + Annonserings-url: + + + Please type a web seed url + Ange en url för webbdistribution + + + Web seed URL: + Url för webbdistribution: + + + No input path set + Ingen sökväg inställd för indata + + + Please type an input path first + Ange en sökväg för indata först + + + Select destination torrent file + Välj mål för torrent-fil + + + Torrent Files + Torrent-filer + + + Torrent creation + Skapa torrent + + + Torrent creation was unsuccessful, reason: %1 + Skapandet av torrent-fil misslyckades. Anledning: %1 + + + Created torrent file is invalid. It won't be added to download list. + Den skapade torrentfilen är ogiltig. Den kommer inte att läggas till i hämtningslistan. + + + Torrent was created successfully: + Torrentfilen skapades: + + + + TorrentFilesModel + + Name + Namn + + + Size + Storlek + + + Progress + Förlopp + + + Priority + Prioritet + + + + TorrentImportDlg + + Torrent Import + Importera torrent + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Denna guide hjälper dig att dela ut en redan hämtad torrent-fil med qBittorrent. + + + Torrent file to import: + Torrent-fil att importera: + + + ... + ... + + + Content location: + Plats för innehållet: + + + Skip the data checking stage and start seeding immediately + Hoppa över datakontrollen och börja distribuera direkt + + + Import + Importera + + + Torrent file to import + Torrent-fil att importera + + + Torrent files (*.torrent) + Torrent-filer (*.torrent) + + + %1 Files + %1 is a file extension (e.g. PDF) + %1-filer + + + Please provide the location of %1 + %1 is a file name + Ange platsen för %1 + + + Please point to the location of the torrent: %1 + Peka ut platsen för torrent-filen: %1 + + + Invalid torrent file + Ogiltig torrentfil + + + This is not a valid torrent file. + Detta är inte en giltig torrentfil. + + + + TorrentModel + + Name + i.e: torrent name + Namn + + + Size + i.e: torrent size + Storlek + + + Done + % Done + Färdig + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + Seeds + i.e. full sources (often untranslated) + Distributörer + + + Peers + i.e. partial sources (often untranslated) + Klienter + + + Down Speed + i.e: Download speed + Hämtningshastighet + + + Up Speed + i.e: Upload speed + Sändningshastighet + + + Ratio + Share ratio + Förhållande + + + ETA + i.e: Estimated Time of Arrival / Time left + Färdig om + + + Label + Etikett + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Lades till + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Färdigställdes + + + Tracker + Bevakare + + + Down Limit + i.e: Download limit + Hämtningsgräns + + + Up Limit + i.e: Upload limit + Sändningsgräns + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Data hämtat + + + Amount left + Amount of data left to download (e.g. in MB) + Data kvar + + + Time Active + Time (duration) the torrent is active (not paused) + Tid aktiv + + + + TrackerList + + URL + URL + + + Status + Status + + + Peers + Klienter + + + Message + Meddelande + + + [DHT] + [DHT] + + + Working + Fungerar + + + Disabled + Inaktiverad + + + This torrent is private + Denna torrent-fil är privat + + + Updating... + Uppdaterar... + + + Not working + Fungerar inte + + + Not contacted yet + Inte kontaktad ännu + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Add a new tracker... + Lägg till en ny bevakare... + + + Remove tracker + Ta bort bevakare + + + Force reannounce + Tvinga annonsering igen + + + + TrackersAdditionDlg + + Trackers addition dialog + Lägg till bevakare + + + List of trackers to add (one per line): + Lista över bevakare att lägga till (en per rad): + + + µTorrent compatible list URL: + URL för µTorrent-kompatibel lista: + + + I/O Error + In-/ut-fel + + + Error while trying to open the downloaded file. + Fel vid försök att öppna den hämtade filen. + + + No change + Ingen ändring + + + No additional trackers were found. + Inga ytterligare bevakare hittades. + + + Download error + Hämtningsfel + + + The trackers list could not be downloaded, reason: %1 + Listan över bevakare kunde inte hämtas. Anledning: %1 + + + + TransferListDelegate + + Downloading + Hämtar + + + Paused + Pausad + + + Queued + i.e. torrent is queued + Kölagd + + + Seeding + Torrent is complete and in upload-only mode + Distribuerar + + + Stalled + Torrent is waiting for download to begin + Avstannad + + + Checking + Torrent local data is being checked + Kontrollerar + + + /s + /second (.i.e per second) + /s + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + Seeded for %1 + e.g. Seeded for 3m10s + Distribuerad i %1 + + + + TransferListFiltersWidget + + All + Alla + + + Downloading + Hämtar + + + Completed + Färdiga + + + Active + Aktiva + + + Inactive + Inaktiva + + + All labels + Alla etiketter + + + Unlabeled + Ingen etikett + + + Remove label + Ta bort etikett + + + New Label + Ny etikett + + + Label: + Etikett: + + + Invalid label name + Ogiltigt etikettnamn + + + Please don't use any special characters in the label name. + Använd inte några specialtecken i etikettnamnet. + + + Paused + Pausad + + + Add label... + Lägg till etikett... + + + Resume torrents + Återuppta torrentfiler + + + Pause torrents + Gör paus i torrentfiler + + + Delete torrents + Ta bort torrentfiler + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + Färdig om + + + Column visibility + Kolumnsynlighet + + + Open destination folder + Öppna målmapp + + + Force recheck + Tvinga återkontroll + + + Copy magnet link + Kopiera magnetlänk + + + Down Speed + i.e: Download speed + Hämtningshastighet + + + Up Speed + i.e: Upload speed + Sändningshastighet + + + Name + i.e: torrent name + Namn + + + Size + i.e: torrent size + Storlek + + + Done + % Done + Färdig + + + Status + Torrent status (e.g. downloading, seeding, paused) + Status + + + Seeds + i.e. full sources (often untranslated) + Distributörer + + + Peers + i.e. partial sources (often untranslated) + Klienter + + + Ratio + Share ratio + Förhållande + + + Torrent Download Speed Limiting + Hastighetsgräns för torrenthämtning + + + Torrent Upload Speed Limiting + Hastighetsgräns för torrentsändning + + + Super seeding mode + Superdistributionsläge + + + Download in sequential order + Hämta i sekventiell ordning + + + Download first and last piece first + Hämta första och sista delen först + + + Label + Etikett + + + New Label + Ny etikett + + + Label: + Etikett: + + + New... + New label... + Ny... + + + Reset + Reset label + Återställ + + + Rename + Byt namn + + + New name: + Nytt namn: + + + Rename... + Byt namn... + + + Invalid label name + Ogiltigt etikettnamn + + + Please don't use any special characters in the label name. + Använd inte några specialtecken i etikettnamnet. + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Lades till + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Färdigställdes + + + Down Limit + i.e: Download limit + Hämtningsgräns + + + Up Limit + i.e: Upload limit + Sändningsgräns + + + Choose save path + Välj sökväg att spara i + + + Save path creation error + Fel vid skapandet av sökväg + + + Could not create the save path + Kunde inte skapa sökväg att spara i + + + Set location... + Ange plats... + + + Preview file... + Förhandsgranska fil... + + + Limit upload rate... + Begränsa sändningshastighet... + + + Limit download rate... + Begränsa hämtningshastighet... + + + Move up + i.e. move up in the queue + Flytta uppåt + + + Move down + i.e. Move down in the queue + Flytta nedåt + + + Move to top + i.e. Move to top of the queue + Flytta överst + + + Move to bottom + i.e. Move to bottom of the queue + Flytta nederst + + + Priority + Prioritet + + + Resume + Resume/start the torrent + Återuppta + + + Pause + Pause the torrent + Gör paus + + + Delete + Delete the torrent + Ta bort + + + Limit share ratio... + Begränsa utdelningsförhållande... + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + Gränser för sändning/hämtning + + + Use global ratio limit + Använd allmän förhållandegräns + + + buttonGroup + knappGrupp + + + Set no ratio limit + Ställ inte in någon förhållandegräns + + + Set ratio limit to + Ställ in förhållandegräns till + + + + UsageDisplay + + Usage: + Användning: + + + displays program version + visar programversionen + + + disable splash screen + inaktivera startbilden + + + displays this help message + visar detta hjälpmeddelande + + + changes the webui port (current: %1) + ändrar port för webbgränssnitt (aktuell: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [filer eller url:er]: hämtar de torrenter som skickats av användaren (valfri) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + Jag vill tacka följande personer som bidragit med att översätta qBittorrent: + + + Please contact me if you would like to translate qBittorrent into your own language. + Kontakta mig om du vill översätta qBittorrent till ditt språk. + + + + addPeerDialog + + Peer addition + Lägg till klient + + + IP + IP + + + Port + Port + + + + addTorrentDialog + + Torrent addition dialog + Lägg till torrent-fil + + + Save path: + Sökväg att spara i: + + + ... + ... + + + Torrent content: + Innehåll: + + + Add to download list in paused state + Lägg till i hämtningslistan i pausat tillstånd + + + Add + Lägg till + + + Cancel + Avbryt + + + Normal + Normal + + + High + Hög + + + Maximum + Maximalt + + + Torrent size: + Torrentstorlek: + + + Unknown + Okänd + + + Free disk space: + Ledigt diskutrymme: + + + Download in sequential order (slower but good for previewing) + Hämta i sekventiell ordning (långsammare men bra för förhandsvisning) + + + Skip file checking and start seeding immediately + Hoppa över filkontroll och börja distribuera direkt + + + Label: + Etikett: + + + Select All + Markera allt + + + Select None + Markera ingen + + + Do not download + Hämta inte + + + + authentication + + Tracker authentication + Autentisering för bevakare + + + Tracker: + Bevakare: + + + Login + Inloggning + + + Username: + Användarnamn: + + + Password: + Lösenord: + + + Log in + Logga in + + + Cancel + Avbryt + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + Bekräfta borttagning - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + Är du säker på att du vill ta bort de markerade torrent-filerna från överföringslistan? + + + Remember choice + Kom ihåg mitt val + + + Also delete the files on the hard disk + Ta även bort filerna på hårddisken + + + + createTorrentDialog + + Cancel + Avbryt + + + Torrent Creation Tool + Verktyg för att skapa torrent + + + Torrent file creation + Skapa torrent-fil + + + Announce urls (trackers): + Annonserings-url:er (bevakare): + + + Comment (optional): + Kommentar (valfritt): + + + Web seeds urls (optional): + Url:er för webbdistribution (valfritt): + + + File or folder to add to the torrent: + Fil eller mapp att lägga till i torrent: + + + Piece size: + Delstorlek: + + + 32 KiB + 32 KiB + + + 64 KiB + 64 KiB + + + 128 KiB + 128 KiB + + + 256 KiB + 256 KiB + + + 512 KiB + 512 KiB + + + 1 MiB + 1 MiB + + + 2 MiB + 2 MiB + + + 4 MiB + 4 MiB + + + Private (won't be distributed on DHT network if enabled) + Privat (kommer inte att distribueras på DHT-nätverk om aktiverat) + + + Start seeding after creation + Börja distribuera efter den skapats + + + Create and save... + Skapa och spara... + + + Progress: + Förlopp: + + + Add file + Lägg till fil + + + Add folder + Lägg till mapp + + + Tracker URLs: + URL:er för bevakare: + + + Web seeds urls: + URL:er för webbdistribution: + + + Comment: + Kommentar: + + + Auto + Automatiskt + + + + createtorrent + + Select destination torrent file + Välj mål för torrent-fil + + + Torrent Files + Torrent-filer + + + No input path set + Ingen sökväg inställd för indata + + + Please type an input path first + Ange en sökväg för indata först + + + Torrent creation + Skapa torrent + + + Torrent was created successfully: + Torrentfilen skapades: + + + Select a folder to add to the torrent + Välj en mapp att lägga till i torrent-filen + + + Please type an announce URL + Ange en annonserings-url + + + Torrent creation was unsuccessful, reason: %1 + Skapandet av torrent-fil misslyckades, anledning: %1 + + + Announce URL: + Tracker URL + Annonserings-url: + + + Please type a web seed url + Ange en url för webbdistribution + + + Web seed URL: + Url för webbdistribution: + + + Select a file to add to the torrent + Välj en fil att lägga till i torrent + + + Created torrent file is invalid. It won't be added to download list. + Skapad torrentfil är ogiltig. Den kommer inte att läggas till i hämtningslistan. + + + + downloadFromURL + + Download from urls + Hämta från url:er + + + Download Torrents from URLs + Hämta torrent-filer från url:er + + + Only one URL per line + Endast en url per rad + + + Download + Hämta + + + Cancel + Avbryt + + + No URL entered + Ingen URL angavs + + + Please type at least one URL. + Ange åtminstone en url. + + + Add torrent links + Lägg till torrentlänkar + + + Both HTTP and Magnet links are supported + Både HTTP och Magnet-länkar stöds + + + + downloadThread + + I/O Error + In/Ut-fel + + + The remote host name was not found (invalid hostname) + Fjärrvärdnamnet hittades inte (ogiltigt värdnamn) + + + The operation was canceled + Åtgärden avbröts + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Fjärrservern stängde anslutningen i förtid innan hela svaret togs emot och behandlades + + + The connection to the remote server timed out + Anslutningen till fjärrservern översteg tidsgränsen + + + SSL/TLS handshake failed + SSL/TLS-handskakning misslyckades + + + The remote server refused the connection + Fjärrservern nekade anslutningen + + + The connection to the proxy server was refused + Anslutningen till proxyservern nekades + + + The proxy server closed the connection prematurely + Proxyservern stängde anslutningen i förtid + + + The proxy host name was not found + Proxyserverns värdnamn hittades inte + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Anslutningen till proxyservern översteg tidsgränsen eller så svarade inte proxyservern på skickad begäran i tid + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Proxyservern kräver autentisering för att kunna ta emot begäran men accepterade inte inloggningsuppgifterna + + + The access to the remote content was denied (401) + Åtkomst till fjärrinnehåll nekades (401) + + + The operation requested on the remote content is not permitted + Begärd åtgärd för fjärrinnehållet tillåts inte + + + The remote content was not found at the server (404) + Fjärrinnehållet hittades inte på servern (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Fjärrservern kräver autentisering för att servera innehållet men angivna inloggningsuppgifter accepterades inte + + + The Network Access API cannot honor the request because the protocol is not known + API för nätverksåtkomst kan inte behandla begäran därför att protokollet inte är känt + + + The requested operation is invalid for this protocol + Begärd åtgärd är ogiltig för detta protokoll + + + An unknown network-related error was detected + Ett okänt nätverksrelaterat fel upptäcktes + + + An unknown proxy-related error was detected + En okänt fel relaterat till proxyservern upptäcktes + + + An unknown error related to the remote content was detected + Ett okänt fel relaterat till fjärrinnehållet upptäcktes + + + A breakdown in protocol was detected + Ett haveri i protokollet upptäcktes + + + Unknown error + Okänt fel + + + + engineSelect + + Search plugins + Sökinsticksmoduler + + + Installed search engines: + Installerade sökmotorer: + + + Name + Namn + + + Url + Url + + + Enabled + Aktiverad + + + Install a new one + Installera ett nytt instick + + + Check for updates + Leta efter uppdateringar + + + Close + Stäng + + + Enable + Aktivera + + + Disable + Inaktivera + + + Uninstall + Avinstallera + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Du kan hitta nya instick för sökmotorer här: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + engineSelectDlg + + Uninstall warning + Varning vid avinstallation + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Vissa insticksmoduler kunde inte avinstalleras därför att de är inkluderade i qBittorrent. +Endast de som du själv har lagt till kan avinstalleras. +Dock har dessa insticksmoduler blivit inaktiverade. + + + Uninstall success + Avinstallation lyckades + + + Select search plugins + Välj sökinsticksmoduler + + + qBittorrent search plugins + Sökinsticksmoduler för qBittorrent + + + Search plugin install + Installation av sökinsticksmoduler + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + En senare version av sökmotorinsticket %1 är redan installerat. + + + Search plugin update + Uppdatering av sökinstick + + + Sorry, update server is temporarily unavailable. + Tyvärr, uppdateringsservern är inte tillgänglig för tillfället. + + + All your plugins are already up to date. + Alla dina insticksmoduler är redan uppdaterade. + + + All selected plugins were uninstalled successfully + Alla markerade insticksmoduler avinstallerades + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + Insticksmodulen för sökmotorn %1 kunde inte uppdateras, behåller gammal version. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Insticksmodulen för sökmotorn %1 kunde inte installeras. + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + Insticksmodulen för sökmotorn %1 uppdaterades. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Insticksmodulen för sökmotorn %1 installerades. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Tyvärr, installationen av sökinsticket %1 misslyckades. + + + New search engine plugin URL + Url för nytt sökmotorinstick + + + URL: + Url: + + + Yes + Ja + + + No + Nej + + + + misc + + B + bytes + B + + + KiB + kibibytes (1024 bytes) + KiB + + + MiB + mebibytes (1024 kibibytes) + MiB + + + GiB + gibibytes (1024 mibibytes) + GiB + + + TiB + tebibytes (1024 gibibytes) + TiB + + + Unknown + Unknown (size) + Okänd + + + < 1m + < 1 minute + < 1 min + + + %1m + e.g: 10minutes + %1 min + + + Unknown + Okänt + + + %1h %2m + e.g: 3hours 5minutes + %1h %2m + + + %1d %2h + e.g: 2days 10hours + %1d %2h + + + qBittorrent will shutdown the computer now because all downloads are complete. + qBittorrent kommer nu att stänga av datorn därför att alla hämtningar är färdiga. + + + + options_imp + + Choose a save directory + Välj en katalog att spara i + + + Choose an ip filter file + Välj en IP-filterfil + + + Filters + Filter + + + Choose export directory + Välj exportkatalog + + + Add directory to scan + Lägg till katalog att söka av + + + Folder is already being watched. + Mappen bevakas redan. + + + Folder does not exist. + Mappen finns inte. + + + Folder is not readable. + Mappen är inte läsbar. + + + Failure + Fel + + + Failed to add Scan Folder '%1': %2 + Misslyckades med att lägga till mapp att söka av "%1": %2 + + + Parsing error + Tolkningsfel + + + Failed to parse the provided IP filter + Misslyckades med att tolka angivet IP-filter + + + Succesfully refreshed + Uppdateringen lyckades + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Tolkningen av angivet IP-filter lyckades: %1 regler har tillämpats. + + + Successfully refreshed + Uppdaterades + + + Invalid key + + + + This is not a valid SSL key. + + + + Invalid certificate + + + + This is not a valid SSL certificate. + + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + + pluginSourceDlg + + Plugin source + Insticksmodulkälla + + + Search plugin source: + Sök insticksmodulkälla: + + + Local file + Lokal fil + + + Web link + Webblänk + + + + preview + + Preview selection + Förhandsvisa markering + + + File preview + Förhandsvisa fil + + + The following files support previewing, <br>please select one of them: + Följande filer har stöd för förhandsvisning. <br>välj en av dem: + + + Preview + Förhandsvisa + + + Cancel + Avbryt + + + + previewSelect + + Preview impossible + Förhandsvisning inte möjlig + + + Sorry, we can't preview this file + Tyvärr, vi kan inte förhandsvisa den här filen + + + Name + Namn + + + Size + Storlek + + + Progress + Förlopp + + + + search_engine + + Search + Sök + + + Status: + Status: + + + Stopped + Stoppad + + + Download + Hämta + + + Search engines... + Sökmotorer... + + + Go to description page + Gå till beskrivningssidan + + + + torrentAdditionDialog + + Unable to decode torrent file: + Kunde inte avkoda torrent-fil: + + + Choose save path + Välj sökväg att spara i + + + Empty save path + Tom sökväg för att spara i + + + Please enter a save path + Ange en sökväg att spara i + + + Save path creation error + Fel vid skapandet av sökväg + + + Could not create the save path + Kunde inte skapa sökväg att spara i + + + Invalid file selection + Ogiltig filmarkering + + + You must select at least one file in the torrent + Du måste välja åtminstone en fil i torrent-filen + + + Priority + Prioritet + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 kvar efter torrenthämtning) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (%1 ytterligare krävs för att hämta) + + + Seeding mode error + Fel i distributionsläge + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Du valde att hoppa över filkontroll. Dock verkar lokala filerna inte finnas i den aktuella destinationsmappen. Inaktivera denna funktion eller uppdatera sökvägen. + + + Rename... + Byt namn... + + + New name: + Nytt namn: + + + The file could not be renamed + Det gick inte att byta namn på filen + + + This name is already in use in this folder. Please use a different name. + Detta namn används redan i denna mapp. Välj ett annat namn. + + + The folder could not be renamed + Det gick inte att byta namn på mappen + + + Rename the file + Byt namn på filen + + + Unable to decode magnet link: + Kunde inte avkoda magnet-länk: + + + Magnet Link + Magnet-länk + + + This file name contains forbidden characters, please choose a different one. + Detta filnamn innehåller förbjudna tecken. Välj ett annat filnamn. + + + Invalid label name + Ogiltigt etikettnamn + + + Please don't use any special characters in the label name. + Använd inte några specialtecken i etikettnamnet. + + + diff --git a/src/lang/qbittorrent_tr.qm b/src/lang/qbittorrent_tr.qm new file mode 100644 index 0000000000000000000000000000000000000000..ff729ddbe36c4fc9809747e034a312d4dab019ab GIT binary patch literal 79455 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 + + + + AboutDlg + + About qBittorrent + qBittorrent Hakkında + + + About + Hakkında + + + Author + Yazar + + + Name: + Ad: + + + Country: + Ülke: + + + E-mail: + E-posta: + + + Christophe Dumez + Christophe Dumez + + + France + Fransa + + + Translation + Çeviri + + + License + Lisans + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + chris@qbittorrent.org + + + + Thanks to + Teşekkürler + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + + AdvancedSettings + + Property + Özellik + + + Value + Değer + + + Ignore transfer limits on local network + Yerel ağda tarım sınırlarını yoksay + + + Include TCP/IP overhead in transfer limits + Aktarım sınırı içine TCP/IP ek yükünü kat + + + Disk write cache size + Yazılabilir disk ön arabellek boyutu + + + MiB + MB + + + Outgoing ports (Min) [0: Disabled] + Giden portlar (Min) [0: Etkisiz] + + + Outgoing ports (Max) [0: Disabled] + Giden portlar (Maks) [0: Etkisiz] + + + Recheck torrents on completion + Tamamlanmış torentleri yeniden denetle + + + Transfer list refresh interval + Aktarım listesi yenilenme aralığı + + + ms + milliseconds + milisaniye + ms + + + Resolve peer countries (GeoIP) + Eş ülkelerini çözümle (GeoIP) + + + Resolve peer host names + Ana makina adı eşlerini çöz + + + Maximum number of half-open connections [0: Disabled] + Yarı açık bağlantıların azami sayısı [0: Etkisiz] + + + Strict super seeding + Süper gönderme kipi + + + Network Interface (requires restart) + Ağ arayüzü (yeniden başlatma gerektirir) + + + Any interface + i.e. Any network interface + örn. Herhangi bir ağ arayüzü + Herhangi bir arayüz + + + Enable embedded tracker + + + + Embedded tracker port + + + + Check for software updates + + + + Use system icon theme + + + + Confirm torrent deletion + + + + IP Address to report to trackers (requires restart) + + + + Setting + + + + Value + Value set for this setting + Değer + + + Display program on-screen notifications + + + + Exchange trackers with other peers + + + + + AutomatedRssDownloader + + Automated RSS Downloader + + + + Enable the automated RSS downloader + + + + Download rules + + + + Rule definition + + + + Must contain: + + + + Must not contain: + + + + ... + ... + + + Assign label: + + + + Apply rule to feeds: + + + + Matching RSS articles + + + + Save to a different directory + + + + Save to: + + + + Import... + İçe aktar... + + + Export... + Dışa aktar... + + + New rule name + + + + Please type the name of the new download rule. + + + + Rule name conflict + + + + A rule with this name already exists, please choose another name. + + + + Are you sure you want to remove the download rule named %1? + + + + Are you sure you want to remove the selected download rules? + + + + Rule deletion confirmation + + + + Destination directory + + + + Invalid action + + + + The list is empty, there is nothing to export. + + + + Where would you like to save the list? + + + + Rules list (*.rssrules) + + + + I/O Error + + + + Failed to create the destination file + + + + Please point to the RSS download rules file + + + + Rules list (*.rssrules *.filters) + + + + Import Error + + + + Failed to import the selected rules file + + + + Add new rule... + + + + Delete rule + + + + Rename rule... + + + + Delete selected rules + + + + Rule renaming + + + + Please type the new rule name + + + + Use regular expressions + + + + Regex mode: use Perl-like regular expressions + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1, ayarladığınız azami orana ulaştı. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent'in bağlı olduğu port: TCP/%1 + + + UPnP support [ON] + UPnP desteği [ON] + + + UPnP support [OFF] + UPnP desteği [OFF] + + + NAT-PMP support [ON] + NAT-PMP desteği [ON] + + + NAT-PMP support [OFF] + NAT-PMP desteği [OFF] + + + DHT support [ON], port: UDP/%1 + DHT desteği [ON], port: UDP/%1 + + + DHT support [OFF] + DHT desteği [OFF] + + + PeX support [ON] + EşD desteği [ON] + + + Local Peer Discovery [ON] + Yerel Eş Keşfi [ON] + + + Local Peer Discovery support [OFF] + Yerel Eş Keşfi desteği [OFF] + + + Encryption support [ON] + Şifreleme desteği [ON] + + + Encryption support [FORCED] + Şifreleme desteği [FORCED] + + + Encryption support [OFF] + Şifreleme desteği [OFF] + + + Web User Interface Error - Unable to bind Web UI to port %1 + Web Kullanıcı Arayüzü Hatası - Web arayüzü bağlanamadı, port %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1', aktarım listesinden ve sabit diskten kaldırıldı. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1', aktarım listesinden kaldırıldı. + + + '%1' is not a valid magnet URI. + '%1' geçerli bir adres değil. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1', zaten indirme listesinde. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1', devam edildi. (hızlı devam) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1', indirme listesine eklendi. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Torrent dosyası çözümlenemiyor: '%1' + + + This file is either corrupted or this isn't a torrent. + Bu dosya bozuk ya da torrent dosyası değil. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font>, <i>IP süzgeciniz tarafından engellendi</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font>, <i>bozuk parçalar sebebiyle engellendi</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + %1 dosyasının özyineli indirmesi %2 torenti içine gömülü + + + Unable to decode %1 torrent file. + %1 torent dosyası çözümlenemiyor. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port adresleme hatası, ileti: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port adresleme başarılı, ileti: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Hızlı devam verisi %1 torrenti için reddedildi, yeniden denetleniyor... + + + Url seed lookup failed for url: %1, message: %2 + Url gönderme araştırması başarısız: %1, ileti: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + '%1', indiriliyor, lütfen bekleyin... + + + Using a disk cache size of %1 MiB + %1 MB'lık disk önbelleği kullanılıyor + + + PeX support [OFF] + PeX desteği [KAPALI] + + + Restart is required to toggle PeX support + PeX desteğini açmak/kapatmak için yeniden başlatmak gerekir + + + The Web UI is listening on port %1 + Ağ arayüzünün kullandığı port: %1 + + + HTTP user agent is %1 + HTTP istemcisi: %1 + + + Reason: %1 + Sebep: %1 + + + Note: new trackers were added to the existing torrent. + Not: yeni izleyiciler varolan torente eklendi. + + + Note: new URL seeds were added to the existing torrent. + Not: yeni URL eşleri varolan torente eklendi. + + + An I/O error occured, '%1' paused. + Bir G/Ç hatası meydana geldi, '%1' duraklatıldı. + + + Removing torrent %1... + Torent kaldırılıyor: %1... + + + Pausing torrent %1... + Torent duraklatılıyor: %1... + + + Error: The torrent %1 does not contain any file. + Hata: %1 torenti herhangi bir dosya içermiyor. + + + File sizes mismatch for torrent %1, pausing it. + %1 torentinin dosya boyutu eşleşmiyor, duraklatılıyor. + + + + ConsoleDlg + + General + Genel + + + Blocked IPs + Engellenmiş IP'ler + + + qBittorrent log viewer + qBittorrent kayıt görüntüleyici + + + + CookiesDlg + + Cookies management + Çerez yönetimi + + + Key + As in Key/Value pair + Anahtar + + + Value + As in Key/Value pair + Değer + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Çerezler için yaygın anahtarlar: '%1', '%2'. +Bu bilgiyi ağ tarayıcınızın yeğlenenler kısmından almalısınız. + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + + + + Dynamic DNS error: Invalid username/password. + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + + + + Dynamic DNS error: Your username was blocked due to abuse. + + + + Dynamic DNS error: supplied domain name is invalid. + + + + Dynamic DNS error: supplied username is too short. + + + + Dynamic DNS error: supplied password is too short. + + + + + DownloadThread + + I/O Error + + + + The remote host name was not found (invalid hostname) + Uzak makina adı bulunamadı (geçersiz makina adı) + + + The operation was canceled + İşlem iptal edildi + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Uzak sunucu, yanıt alınmadan ve işlenmeden bağlantıyı kapattı + + + The connection to the remote server timed out + Uzak sunucuya bağlantı zaman aşımına uğradı + + + SSL/TLS handshake failed + SSL/TLS başarısız + + + The remote server refused the connection + Uzak sunucu bağlantıyı reddetti + + + The connection to the proxy server was refused + Vekil sunucuya bağlantı reddedildi + + + The proxy server closed the connection prematurely + Vekil sunucu bağlantıyı beklenmeyen şekilde kapattı + + + The proxy host name was not found + Vekil makina adı bulunamadı + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Vekille olan bağlantı zaman aşımına uğradı ya da vekil gönderilen isteğe zamanında yanıt vermedi + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Vekil, isteği gerçekleştirmek için yetkilendirme gerektiriyor ancak sunulan kimliklerin hiçbirini kabul etmedi + + + The access to the remote content was denied (401) + Uzak içeriğe giriş reddedildi (401) + + + The operation requested on the remote content is not permitted + Uzak içerikteki işlem isteğine izin verilmedi + + + The remote content was not found at the server (404) + Uzak içerik sunucuda bulunamadı (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Uzak sunucu, içeriğin uygunluğu için yetkilendirme istiyor ancak istenen kimlik kabul edilmedi + + + The Network Access API cannot honor the request because the protocol is not known + Ağ Girişi API isteği gerçekleştiremedi çünkü protokol bilinmiyor + + + The requested operation is invalid for this protocol + İstenen işlem bu protokol için geçersiz + + + An unknown network-related error was detected + Bilinmeyen ağla ilgili bir hata belirlendi + + + An unknown proxy-related error was detected + Bilinmeyen vekille ilgili bir hata belirlendi + + + An unknown error related to the remote content was detected + Bilinmeyen uzak içerikle ilgili bir hata belirlendi + + + A breakdown in protocol was detected + Protokolde bir hata belirlendi + + + Unknown error + Bilinmeyen hata + + + + EventManager + + %1/s + e.g. 120 KiB/s + %1/s + + + Working + Çalışıyor + + + Updating... + Güncelleniyor... + + + Not working + Çalışmıyor + + + Not contacted yet + Daha bağlanılamadı + + + this session + bu oturum + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Gönderme zamanı: %1 + + + %1 max + e.g. 10 max + azami: %1 + + + + ExecutionLog + + General + Genel + + + Blocked IPs + Engellenmiş IP'ler + + + + FeedDownloader + + RSS Feed downloader + RSS Besleme indirici + + + RSS feed: + RSS beslemesi: + + + Feed name + Besleme adı + + + Automatically download torrents from this feed + Bu beslemeden torentleri kendiliğinden indir + + + Download filters + İndirme süzgeçleri + + + Filters: + Süzgeçler: + + + Filter settings + Süzgeç ayarları + + + Matches: + Eşleşmeler: + + + Does not match: + Eşleşmeyen: + + + Destination folder: + Hedef klasör: + + + ... + ... + + + Filter testing + Süzgeç sınama + + + Torrent title: + Torent başlığı: + + + Result: + Sonuç: + + + Test + Sına + + + Import... + İçe aktar... + + + Export... + Dışa aktar... + + + Rename filter + Süzgeci yeniden adlandır + + + Remove filter + Süzgeci kaldır + + + Add filter + Süzgeç ekle + + + + FeedDownloaderDlg + + New filter + Yeni süzgeç + + + Please choose a name for this filter + Lütfen bu süzgeç için yeni bir ad seçin + + + Filter name: + Süzgeç adı: + + + Invalid filter name + Geçersiz süzgeç adı + + + The filter name cannot be left empty. + Süzgeç adı boş bırakılamaz. + + + This filter name is already in use. + Bu süzgeç adı kullanımda. + + + Filter testing error + Süzgeç sınama hatası + + + Please specify a test torrent name. + Lütfen bir sınama torenti adı belirtin. + + + matches + eşleşmeler + + + does not match + eşleşme yok + + + Select file to import + İçe aktarmak için dosya seçin + + + Filters Files + Süzgeç Dosyaları + + + Import successful + İçe aktarma başarılı + + + Filters import was successful. + Süzgeçler başarıyla içe aktarıldı. + + + Import failure + İçe aktarma başarısız + + + Filters could not be imported due to an I/O error. + Süzgeçler bir Girdi/Çıktı hatası sebebiyle içe aktarılamadı. + + + Select destination file + Hedef dosyayı seçin + + + Export successful + Dışa aktarım başarılı + + + Filters export was successful. + Süzgeçler dışa başarıyla aktarıldı. + + + Export failure + Dışa aktarım başarısız + + + Filters could not be exported due to an I/O error. + Süzgeçler bir Girdi/Çıktı hatası sebebiyle dışa aktarılamadı. + + + Choose save path + Kayıt yolunu seç + + + + FeedList + + Unread + Okunmadı + + + + FeedListWidget + + RSS feeds + RSS beslemeleri + + + Unread + Okunmadı + + + + GUI + + Open Torrent Files + Torrent Dosyasını Aç + + + Torrent Files + Torrent Dosyaları + + + qBittorrent + qBittorrent + + + Transfers + Aktarımlar + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + İND hızı: %1 KB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + GÖN hızı: %1 KB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 indirildi. + + + I/O Error + i.e: Input/Output Error + I/O Hatası + + + Search + Arama + + + RSS + RSS + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + G/Ç: Girdi/Çıktı + %1 torrenti için bir G/Ç hatası meydana geldi. + Sebep: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Adres indirme hatası + + + Couldn't download file at url: %1, reason: %2. + Adresteki dosya indirilemedi: %1, neden: %2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Options were saved successfully. + Seçenekler başarıyla kaydedildi. + + + Download completion + İndirme durumu + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Bazı dosyalar hala aktarılıyor. +qBittorrent'ten çıkmak istediğinize emin misiniz? + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Genel Gönderme Hızı Sınırı + + + Global Download Speed Limit + Genel İndirme Hızı Sınırı + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (İND: %2KB/s, GÖN: %3KB/s) + + + Recursive download confirmation + Özyineli indirilen doğrulama + + + The torrent %1 contains torrent files, do you want to proceed with their download? + %1 , torent dosyaları içeriyor, bunların indirilmesini birlikte yürütmek istiyor musunuz? + + + Transfers (%1) + Aktarımlar: (%1) + + + Torrent file association + Torent dosyası ilişkisi + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent torent dosyaranı ve benzer bağlantıları açmak için varsayılan uygulama değil. +qBittorrent'u bunlarla ilişkilendirmek ister misiniz? + + + Yes + Evet + + + No + Hayır + + + Never + Asla + + + Always + Her zaman + + + Exiting qBittorrent + qBittorrent'ten çıkılıyor + + + + GeoIP + + Australia + Avustralya + + + Argentina + Arjantin + + + Austria + Avusturya + + + United Arab Emirates + Birleşik Arap Emirlikleri + + + Brazil + Brezilye + + + Bulgaria + Bulgaristan + + + Belarus + Beyaz Rusya + + + Belgium + Belçika + + + Bosnia + Bosna Hersek + + + Canada + Kanada + + + Czech Republic + Çek Cumhuriyeti + + + China + Çin + + + Costa Rica + Kosta Rika + + + Switzerland + İsviçre + + + Germany + Almanya + + + Denmark + Danimarka + + + Algeria + Cezayir + + + Spain + İspanya + + + Egypt + Mısır + + + Finland + Finlandiya + + + France + Fransa + + + United Kingdom + Birleşik Krallık + + + Greece + Yunanistan + + + Georgia + Gürcistan + + + Hungary + Macaristan + + + Croatia + Hırvatistan + + + Italy + İtalya + + + India + Hindistan + + + Israel + İsrail + + + Ireland + İrlanda + + + Iceland + İzlanda + + + Indonesia + Endonezya + + + Japan + Japonya + + + South Korea + Güney Kore + + + Luxembourg + Lüksemburg + + + Malaysia + Malezya + + + Mexico + Meksika + + + Serbia + Sırbistan + + + Morocco + Fas + + + Netherlands + Hollanda + + + Norway + Norveç + + + New Zealand + Yeni Zelanda + + + Portugal + Portekiz + + + Poland + Polonya + + + Pakistan + Pakistan + + + Philippines + Filipinler + + + Russia + Rusya + + + Romania + Romanya + + + France (Reunion Island) + Fransa (Birleşik Ada) + + + Sweden + İsveç + + + Slovakia + Slovakya + + + Singapore + Singapur + + + Slovenia + Slovenya + + + Taiwan + Tayvan + + + Turkey + Türkiye + + + Thailand + Tayland + + + USA + ABD + + + Ukraine + Ukrayna + + + South Africa + Güney Afrika + + + Saudi Arabia + Suudi Arabistan + + + + HeadlessLoader + + Information + Bilgi + + + To control qBittorrent, access the Web UI at http://localhost:%1 + qBittorrent'i kontrol etmek için, Web Arayüzü'ne giriş yolu: http://localhost:%1 + + + The Web UI administrator user name is: %1 + Web Arayüzü yöneticisinin kullanıcı adı: %1 + + + The Web UI administrator password is still the default one: %1 + Web Arayüzü yöneticisinin parolası hala varsayılan: %1 + + + This is a security risk, please consider changing your password from program preferences. + Bu bir güvenlik riskidir, lütfen program yeğlenenlerinden parolanızı değiştirin. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + IP adresiniz çok fazla yetkilendirme denemesi başarısızlığı nedeniyle yasaklandı. + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + İndirme hızı: x KB/s - Aktarılan: x MB + İND: %1/s - Top: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Gönderme hızı: x KB/s - Aktarılan: x MB + GÖN: %1/s - Top: %2 + + + + HttpServer + + File + Dosya + + + Edit + Düzenle + + + Help + Yardım + + + Delete from HD + Sabit diskten sil + + + Download Torrents from their URL or Magnet link + Torrentleri bir adresten ya da ilgili bağlantıdan indir + + + Only one link per line + Her satıra bir bağlantı + + + Download + İndir + + + Download local torrent + Yerel torrenti indir + + + Torrent files were correctly added to download list. + Torrent dosyaları indirme listesine başarılı bir şekilde eklendi. + + + Point to torrent file + Torrent dosyasını gösterir + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Seçili torrentleri aktarım listesinden ve sabit diskinizden silmek istediğinize emin misiniz? + + + Download rate limit must be greater than 0 or disabled. + İndirme oranı 0 büyük ya da etkisiz olmalı. + + + Upload rate limit must be greater than 0 or disabled. + Gönderme oranı 0'dan büyük ya da etkisiz olmalı. + + + Maximum number of connections limit must be greater than 0 or disabled. + En yüksek sayıdaki bağlantı sınırı 0'dan büyük ya da etkisiz olmalı. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Torrent başına en yüksek sayıdaki bağlantı sınırı 0'dan büyük ya da etkisiz olmalı. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Torrent başına en yüksek sayıdaki gönderme yuvası sınırı 0'dan yüksek ya da etkisiz olmalı. + + + Unable to save program preferences, qBittorrent is probably unreachable. + Program yeğlenenleri kaydedilemedi, qBittorrent'e muhtemelen ulaşılamıyor. + + + Language + Dil + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Gelen bağlantıların portu 1024'ten büyük, 65535'ten küçük olmalı. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Web Arayüzü için kullanılan port 1024'ten büyük, 65535'ten küçük olmalı. + + + The Web UI username must be at least 3 characters long. + Web arayüzü kullanıcı adı en az 3 karakter uzunluğunda olmalı. + + + The Web UI password must be at least 3 characters long. + Web arayüzü parolası en az 3 karakter uzunluğunda olmalı. + + + Downloaded + Is the file downloaded or not? + Dosya indirildi mi indirilmedi mi? + İndirilen + + + Save + + + + qBittorrent client is not reachable + + + + HTTP Server + HTTP Sunucu + + + Torrent path + + + + Torrent name + + + + The following parameters are supported: + + + + + LegalNotice + + Legal Notice + Yasal Not + + + Legal notice + Yasal not + + + Cancel + Vazgeç + + + I Agree + Katılıyorum + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent bir dosya paylaşım programıdır. Bir torent çalıştırdığınızda başkaları tarafından kopyalanabilecektir. Paylaştığınız tüm içerik sizin sorumluluğunuzdadır. + +Başka bir bildiri yayınlanmayacaktır. + + + Press %1 key to accept and continue... + + + + + LineEdit + + Clear the text + + + + + MainWindow + + &Edit + D&üzen + + + &File + &Dosya + + + &Help + &Yardım + + + Preview file + Dosya önizleme + + + Clear log + Günlüğü temizle + + + Decrease priority + Önceliği düşür + + + Increase priority + Önceliği arttır + + + &Tools + &Araçlar + + + &View + &Görünüm + + + &Add File... + &Dosya Ekle... + + + E&xit + Çı&kış + + + &Options... + &Seçenekler... + + + Add &URL... + &URL ekle... + + + Torrent &creator + Torent &oluşturucu + + + Set upload limit... + Gönderim sınırı ayarla... + + + Set download limit... + İndirme sınırı ayarla... + + + Set global download limit... + Genel indirme sınırı ayarla... + + + Set global upload limit... + Genel gönderim sınırı ayarla... + + + &Log viewer... + &Kayıt görüntüleyici... + + + Top &tool bar + Üst &araç çubuğu + + + Display top tool bar + Üst araç çubuğunu göster + + + &Speed in title bar + Başlık çubuğunda &hızı göster + + + Show transfer speed in title bar + Aktarım hızını başlık çubuğunda göster + + + Alternative speed limits + Akıllı hız sınırları + + + &About + &Hakkında + + + &Pause + &Duraklat + + + &Delete + &Sil + + + P&ause All + Tümünü D&uraklat + + + Visit &Website + S&iteyi Ziyaret Et + + + Report a &bug + Bir hata &bildir + + + &Documentation + B&elgeleme + + + &RSS reader + &RSS okuyucu + + + Search &engine + Arama &motoru + + + Log viewer + Kayıt görüntüleyici + + + Lock qBittorrent + + + + Ctrl+L + + + + &Resume + + + + R&esume All + + + + Exit + + + + Import torrent... + + + + Donate money + + + + If you like qBittorrent, please donate! + + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + + + + Transfers + Aktarımlar + + + Torrent file association + Torent dosyası ilişkisi + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent torent dosyaranı ve benzer bağlantıları açmak için varsayılan uygulama değil. +qBittorrent'u bunlarla ilişkilendirmek ister misiniz? + + + UI lock password + + + + Please type the UI lock password: + + + + Password update + + + + The UI lock password has been successfully updated + + + + RSS + RSS + + + Search + + + + Transfers (%1) + Aktarımlar: (%1) + + + Download completion + İndirme durumu + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 indirildi. + + + I/O Error + i.e: Input/Output Error + + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + %1 torrenti için bir G/Ç hatası meydana geldi. + Sebep: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Özyineli indirilen doğrulama + + + The torrent %1 contains torrent files, do you want to proceed with their download? + %1 , torent dosyaları içeriyor, bunların indirilmesini birlikte yürütmek istiyor musunuz? + + + Yes + Evet + + + No + Hayır + + + Never + Asla + + + Url download error + Adres indirme hatası + + + Couldn't download file at url: %1, reason: %2. + Adresteki dosya indirilemedi: %1, neden: %2. + + + Global Upload Speed Limit + Genel Gönderme Hızı Sınırı + + + Global Download Speed Limit + Genel İndirme Hızı Sınırı + + + Invalid password + + + + The password is invalid + + + + Exiting qBittorrent + qBittorrent'ten çıkılıyor + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Bazı dosyalar hala aktarılıyor. +qBittorrent'ten çıkmak istediğinize emin misiniz? + + + Always + Her zaman + + + Open Torrent Files + Torrent Dosyasını Aç + + + Torrent Files + Torrent Dosyaları + + + Options were saved successfully. + Seçenekler başarıyla kaydedildi. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + İND hızı: %1 KB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + GÖN hızı: %1 KB/s + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (İND: %2KB/s, GÖN: %3KB/s) + + + A newer version is available + + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + + + + Impossible to update qBittorrent + + + + qBittorrent failed to update, reason: %1 + + + + &Add torrent file... + + + + Add &link to torrent... + + + + Import existing torrent... + + + + Execution &Log + + + + Execution Log + + + + Auto-Shutdown on downloads completion + + + + Exit qBittorrent + + + + Suspend system + + + + Shutdown system + + + + Disabled + Etkisiz + + + The password should contain at least 3 characters + + + + + PeerAdditionDlg + + Invalid IP + Geçersiz IP + + + The IP you provided is invalid. + Sunduğunuz IP geçersiz. + + + + PeerListDelegate + + /s + /second (i.e. per second) + /saniye (örn. saniye başı) + /s + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + İstemci + + + Progress + i.e: % downloaded + İlerleme + + + Down Speed + i.e: Download speed + İndirme Hızı + + + Up Speed + i.e: Upload speed + Gönderme Hızı + + + Downloaded + i.e: total data downloaded + İndirilen + + + Uploaded + i.e: total data uploaded + Gönderilen + + + Ban peer permanently + Eşi kalıcı olarak yasakla + + + Peer addition + Eş ekleme + + + The peer was added to this torrent. + Eş, bu torrente eklendi. + + + The peer could not be added to this torrent. + Eş, bu torrente eklenemedi. + + + Are you sure? -- qBittorrent + Emin misiniz? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + Seçili eşleri kalıcı olarak silmek istediğinizden emin misiniz? + + + &Yes + &Evet + + + &No + &Hayır + + + Manually banning peer %1... + Elle yasaklanan eş: %1... + + + Upload rate limiting + Gönderme oranını sınırla + + + Download rate limiting + İndirme oranını sınırla + + + Add a new peer... + Yeni bir eş ekle... + + + Limit download rate... + İndirme oranını sınırla... + + + Limit upload rate... + Gönderme oranını sınırla... + + + Copy IP + + + + Connection + Bağlantı + + + + Preferences + + UI + User Interface + Arayüz + + + Downloads + İndirilenler + + + Connection + Bağlantı + + + Bittorrent + Bittorrent + + + Proxy + Vekil + + + Web UI + Web Arayüzü + + + Language: + Dil: + + + (Requires restart) + (Yeniden başlatma gerektirir) + + + Visual style: + Görsel biçem: + + + Transfer list + Aktarım listesi + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Aktarım listesinde, her iki sırada bir gri artalan olacak. + Başka sıra renkleri kullan + + + File system + Dosya sistemi + + + Torrent queueing + Torent kuyruğu + + + Maximum active downloads: + Azami etkin indirilen: + + + Maximum active uploads: + Azami etkin gönderilen: + + + Maximum active torrents: + Azami etkin torent: + + + When adding a torrent + Bir torent eklerken + + + Display torrent content and some options + Torent içeriğini ve bazı seçenekleri göster + + + Listening port + Kullanılan port + + + Port used for incoming connections: + Gelen bağlantılar için kullanılacak port: + + + Random + Rastgele + + + Enable UPnP port mapping + UPnP port haritalamayı etkinleştir + + + Enable NAT-PMP port mapping + NAT-PMP port haritalamayı etkinleştir + + + Connections limit + Bağlantı sınırı + + + Global maximum number of connections: + Genel azami bağlantı sayısı: + + + Maximum number of connections per torrent: + Torent başına azami bağlantı sayısı: + + + Maximum number of upload slots per torrent: + Torent başına azami gönderme yuvası sayısı: + + + Upload: + Gönderme: + + + Download: + İndirme: + + + KiB/s + KB/s + + + Bittorrent features + Bittorrent özellikleri + + + Enable DHT network (decentralized) + DHT ağını etkinleştir (dağıtılmış) + + + Use a different port for DHT and Bittorrent + DHT ve Bittorrent için farklı bir port kullan + + + DHT port: + DHT portu: + + + Enable Peer Exchange / PeX (requires restart) + Eş Değişimini Etkinleştir / PeX (yeniden başlatmak gerekir) + + + Enable Local Peer Discovery + Yerel Eş Keşfini Etkinleştir + + + Enabled + Etkin + + + Forced + Zorlandı + + + Disabled + Etkisiz + + + Type: + Tip: + + + (None) + (Hiçbiri) + + + HTTP + HTTP + + + Port: + Port: + + + Authentication + Kimlik Denetimi + + + Username: + Kullanıcı adı: + + + Password: + Parola: + + + SOCKS5 + SOCKS5 + + + HTTP Server + HTTP Sunucu + + + Filter path (.dat, .p2p, .p2b): + Süzgeç yolu (.dat, .p2p, .p2b): + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP İletişimi (izleyiciler, Web eşleri, arama motoru) + + + Host: + Ana Makina: + + + Peer Communications + Eş İletişimi + + + SOCKS4 + SOCKS4 + + + Speed + Hız + + + Global speed limits + Genel hız sınırları + + + Alternative global speed limits + Akıllı genel hız sınırları + + + to + time1 to time2 + zaman1'den zaman2'ye + > + + + Every day + Her gün + + + Week days + Hafta içi + + + Week ends + Haftasonu + + + Advanced + Gelişmiş + + + Copy .torrent files to: + .torrent dosyasını kopyala: + + + Remove folder + Klasörü kaldır + + + No action + Hiçbir şey yapma + + + Options + Seçenekler + + + Visual Appearance + Görsel Özellikler + + + Action on double-click + Çift tıklama eylemi + + + Downloading torrents: + Torent indiriliyor: + + + Start / Stop + Başlat / Durdur + + + Open destination folder + Hedef klasörü aç + + + Completed torrents: + Tamamlanan torentler: + + + Desktop + Masaüstü + + + Show splash screen on start up + Açılış ekranını başlangıçta göster + + + Start qBittorrent minimized + qBittorrent'i küçültülmüş başlat + + + Show qBittorrent icon in notification area + qBittorrent simgesini bildirim alanında göster + + + Minimize qBittorrent to notification area + qBittorrent'i bildirim alanına küçült + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + örn. Sistem tepsisi simgesi ana pencere kapatıldığında görünür. + qBittorrent'i bildirim alanına kapat + + + Do not start the download automatically + The torrent will be added to download list in pause state + Torent, indirme listesine duraklatılmış durumda eklenir + İndirmeyi kendiliğinden olarak başlatma + + + Save files to location: + Dosyaların kaydedileceği yer: + + + Append the label of the torrent to the save path + Kayıt yoluna toren etiketini de ekle + + + Pre-allocate disk space for all files + Tüm dosyalar için disk alanı tahsisi yap + + + Keep incomplete torrents in: + Tamamlanmamış torentlerin tutulacağı yer: + + + Append .!qB extension to incomplete files' names + Tamamlanmamış dosya adlarına .!qB eklentisini ekle + + + Automatically add torrents from: + Torentlerin kendiliğinden ekleneceği yer: + + + Add folder... + Klasör ekle... + + + IP Filtering + IP Süzgeci + + + Schedule the use of alternative speed limits + Akıllı hız sınırlarının kullanım zamanı + + + from + from (time1 to time2) + Başlangıç + + + When: + Zaman: + + + Look for peers on your local network + Yerel ağda eş ara + + + Protocol encryption: + İletişim kuralı şifreleme: + + + Enable Web User Interface (Remote control) + Web Kullanıcı Arayüzünü Etkinleştir (Uzaktan Kontrol) + + + Share ratio limiting + Paylaşım oranı sınırlama + + + Seed torrents until their ratio reaches + Torentleri paylaşım oranlarına ulaşıncaya kadar gönder + + + then + sonra + + + Pause them + Duraklat + + + Remove them + Kaldır + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Eşleri uyumlu Bittorrent istemcileri ile değiştir (µTorrent, Vuze, ...) + + + Email notification upon download completion + + + + Destination email: + + + + SMTP server: + + + + Run an external program on torrent completion + + + + BitTorrent + + + + Start / Stop Torrent + + + + Use UPnP / NAT-PMP port forwarding from my router + + + + Privacy + + + + Enable DHT (decentralized network) to find more peers + + + + Use a different port for DHT and BitTorrent + + + + Enable Peer Exchange (PeX) to find more peers + + + + Enable Local Peer Discovery to find more peers + + + + Encryption mode: + + + + Prefer encryption + + + + Require encryption + + + + Disable encryption + + + + Reload the filter + + + + Behavior + + + + Language + Dil + + + Power Management + + + + Inhibit system sleep when torrents are active + + + + Bypass authentication for localhost + + + + Ask for program exit confirmation + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + + + + Tray icon style: + + + + Normal + Normal + + + Monochrome (Dark theme) + + + + Monochrome (Light theme) + + + + This server requires a secure connection (SSL) + + + + User Interface Language: + + + + Transfer List + + + + Show qBittorrent in notification area + + + + Hard Disk + + + + Listening Port + + + + Connections Limits + + + + Proxy Server + + + + Torrent Queueing + + + + Share Ratio Limiting + + + + Use UPnP / NAT-PMP to forward the port from my router + + + + Update my dynamic domain name + + + + Service: + + + + Register + + + + Domain name: + + + + Global Rate Limits + + + + Apply rate limit to uTP connections + + + + Apply rate limit to transport overhead + + + + Alternative Global Rate Limits + + + + Schedule the use of alternative rate limits + + + + Enable bandwidth management (uTP) + + + + Otherwise, the proxy server is only used for tracker connections + + + + Use proxy for peer connections + + + + Append .!qB extension to incomplete files + + + + Use HTTPS instead of HTTP + + + + Import SSL Certificate + + + + Import SSL Key + + + + Certificate: + + + + Key: + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + PreviewSelect + + Name + Ad + + + Size + Boyut + + + Progress + İlerleme + + + Preview impossible + Önizleme yapılamıyor + + + Sorry, we can't preview this file + Üzgünüz, bu dosyanın önizlemesi yapılamıyor + + + + PropListDelegate + + Normal + Normal (priority) + Normal (öncelik) + Normal + + + High + High (priority) + Yüksek (öncelik) + Yüksek + + + Maximum + Maximum (priority) + En yüksek (öncelik) + En yüksek + + + Not downloaded + İndirilmedi + + + Mixed + Mixed (priorities + + + + + PropTabBar + + General + Genel + + + Trackers + İzleyiciler + + + Peers + + + + Files + Dosyalar + + + HTTP Sources + + + + Content + + + + + PropertiesWidget + + Save path: + Kayıt Yolu: + + + Torrent hash: + Torrent adresleme: + + + Comment: + Yorum: + + + Share ratio: + Paylaşım oranı: + + + General + Genel + + + Trackers + İzleyiciler + + + URL seeds + URL eşler + + + Files + Dosyalar + + + Priority + Öncelik + + + New url seed + New HTTP source + Yeni gönderen adresi + + + New url seed: + Yeni gönderen adresi: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + Bu gönderen adresi zaten listede. + + + Choose save path + Kayıt yolunu seçin + + + Save path creation error + Kayıt yolu oluşturulmada hata + + + Could not create the save path + Kayıt yolu oluşturulamadı + + + Downloaded: + İndirilen: + + + Transfer + Aktarım + + + Uploaded: + Gönderilen: + + + Wasted: + Boşa giden: + + + UP limit: + Gönderme Sınırı: + + + DL limit: + İndirme Sınırı: + + + Time elapsed: + Geçen zaman: + + + Connections: + Bağlantı: + + + Information + Bilgi + + + Created on: + Oluşturma: + + + Peers + Eşler + + + Normal + Normal + + + Maximum + En Yüksek + + + High + Yüksek + + + this session + bu oturum + + + %1 max + e.g. 10 max + azami: %1 + + + Availability: + Kullanılırlık: + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + Gönderme zamanı: %1 + + + Rename... + Yeniden adlandır... + + + New name: + Yeni ad: + + + The file could not be renamed + Dosya yeniden adlandırılamadı + + + This name is already in use in this folder. Please use a different name. + Bu ad başka bir öğe tarafından kullanılıyor, Lütfen başka bir ad seçin. + + + The folder could not be renamed + Dosya yeniden adlandırılamadı + + + Rename the file + Dosyayı yeniden adlandır + + + This file name contains forbidden characters, please choose a different one. + Bu dosya adı yasak karakterler içeriyor, lütfen başka bir ad seçin. + + + I/O Error + Girdi/Çıktı Hatası + + + This file does not exist yet. + Bu dosya henüz mevcut değil. + + + This folder does not exist yet. + Bu klasör henüz mevcut değil. + + + Reannounce in: + Yeniden duyuru yeri: + + + Select All + Tümünü Seç + + + Select None + Hiçbirini Seçme + + + Do not download + İndirme + + + Pieces size: + + + + Time active: + Time (duration) the torrent is active (not paused) + + + + Torrent content: + Torrent içeriği: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1, ayarladığınız azami orana ulaştı. + + + Removing torrent %1... + Torent kaldırılıyor: %1... + + + Pausing torrent %1... + Torent duraklatılıyor: %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent'in bağlı olduğu port: TCP/%1 + + + UPnP support [ON] + UPnP desteği [ON] + + + UPnP support [OFF] + UPnP desteği [OFF] + + + NAT-PMP support [ON] + NAT-PMP desteği [ON] + + + NAT-PMP support [OFF] + NAT-PMP desteği [OFF] + + + HTTP user agent is %1 + HTTP istemcisi: %1 + + + Using a disk cache size of %1 MiB + %1 MB'lık disk önbelleği kullanılıyor + + + DHT support [ON], port: UDP/%1 + DHT desteği [ON], port: UDP/%1 + + + DHT support [OFF] + DHT desteği [OFF] + + + PeX support [ON] + EşD desteği [ON] + + + PeX support [OFF] + PeX desteği [KAPALI] + + + Restart is required to toggle PeX support + PeX desteğini açmak/kapatmak için yeniden başlatmak gerekir + + + Local Peer Discovery [ON] + Yerel Eş Keşfi [ON] + + + Local Peer Discovery support [OFF] + Yerel Eş Keşfi desteği [OFF] + + + Encryption support [ON] + Şifreleme desteği [ON] + + + Encryption support [FORCED] + Şifreleme desteği [FORCED] + + + Encryption support [OFF] + Şifreleme desteği [OFF] + + + Embedded Tracker [ON] + + + + Failed to start the embedded tracker! + + + + Embedded Tracker [OFF] + + + + The Web UI is listening on port %1 + Ağ arayüzünün kullandığı port: %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Web Kullanıcı Arayüzü Hatası - Web arayüzü bağlanamadı, port %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1', aktarım listesinden ve sabit diskten kaldırıldı. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1', aktarım listesinden kaldırıldı. + + + '%1' is not a valid magnet URI. + '%1' geçerli bir adres değil. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1', zaten indirme listesinde. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1', devam edildi. (hızlı devam) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1', indirme listesine eklendi. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Torrent dosyası çözümlenemiyor: '%1' + + + This file is either corrupted or this isn't a torrent. + Bu dosya bozuk ya da torrent dosyası değil. + + + Error: The torrent %1 does not contain any file. + Hata: %1 torenti herhangi bir dosya içermiyor. + + + Note: new trackers were added to the existing torrent. + Not: yeni izleyiciler varolan torente eklendi. + + + Note: new URL seeds were added to the existing torrent. + Not: yeni URL eşleri varolan torente eklendi. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font>, <i>IP süzgeciniz tarafından engellendi</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font>, <i>bozuk parçalar sebebiyle engellendi</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + %1 dosyasının özyineli indirmesi %2 torenti içine gömülü + + + Unable to decode %1 torrent file. + %1 torent dosyası çözümlenemiyor. + + + Torrent name: %1 + + + + Torrent size: %1 + + + + Save path: %1 + + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + + + + Thank you for using qBittorrent. + + + + [qBittorrent] %1 has finished downloading + + + + An I/O error occured, '%1' paused. + Bir G/Ç hatası meydana geldi, '%1' duraklatıldı. + + + Reason: %1 + Sebep: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Port adresleme hatası, ileti: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Port adresleme başarılı, ileti: %1 + + + File sizes mismatch for torrent %1, pausing it. + %1 torentinin dosya boyutu eşleşmiyor, duraklatılıyor. + + + Fast resume data was rejected for torrent %1, checking again... + Hızlı devam verisi %1 torrenti için reddedildi, yeniden denetleniyor... + + + Url seed lookup failed for url: %1, message: %2 + Url gönderme araştırması başarısız: %1, ileti: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + '%1', indiriliyor, lütfen bekleyin... + + + The network interface defined is invalid: %1 + + + + Trying any other network interface available instead. + + + + Listening on IP address %1 on network interface %2... + + + + Failed to listen on network interface %1 + + + + UPnP / NAT-PMP support [ON] + + + + UPnP / NAT-PMP support [OFF] + + + + Local Peer Discovery support [ON] + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + + + + Error: Failed to parse the provided IP filter. + + + + Reporting IP address %1 to trackers... + + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + + + + The computer will now be switched off unless you cancel within the next 15 seconds... + + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + + + + + RSS + + Search + Arama + + + Delete + Sil + + + Rename + Yeniden adlandır + + + Refresh RSS streams + RSS akımlarını yenile + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torentler:</span> <span style=" font-style:italic;">(indirmek için çift tıklayın)</span></p></body></html> + + + Download torrent + Torenti indir + + + Open news URL + Haber adresini aç + + + Copy feed URL + Besleme adresini kopyala + + + New subscription + Yeni abonelik + + + Mark items read + Öğeleri okundu olarak işaretle + + + Update all + Tümünü güncelle + + + Update all feeds + Tüm beslemeleri güncelle + + + RSS feeds + RSS beslemeleri + + + Update + Güncelle + + + Feed URL + Besleme adresi + + + Article title + Yazı başlığı + + + Rename... + Yeniden adlandır... + + + New subscription... + Yeni abonelik... + + + RSS feed downloader... + RSS Beslemesi indirici... + + + New folder... + Yeni klasör... + + + Manage cookies... + Çerezleri yönet... + + + Settings... + Ayarlar... + + + RSS Downloader... + + + + + RSSImp + + Please type a rss stream url + Lütfen bir rss akımı adresi yazın + + + Stream URL: + Akım adresi: + + + Are you sure? -- qBittorrent + Emin misiniz? -- qBittorrent + + + &Yes + &Evet + + + &No + &Hayır + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + Bu rss beslemesi zaten listede var. + + + Date: + Tarih: + + + Author: + Yazar: + + + Please choose a folder name + Lütfen bir klasör adı seçin + + + Folder name: + Klasör adı: + + + New folder + Yeni klasör + + + Are you sure you want to delete these elements from the list? + Bu öğeleri listeden silmek istediğinize emin misiniz? + + + Are you sure you want to delete this element from the list? + Bu öğeyi listeden silmek istediğinize emin misiniz? + + + Please choose a new name for this RSS feed + Lütfen bu RSS beslemesi için yeni bir ad seçin + + + New feed name: + Yeni besleme adı: + + + Name already in use + Bu ad kullanımda + + + This name is already used by another item, please choose another one. + Bu ad başka bir öğe tarafından kullanılıyor, lütfen başka bir tane seçin. + + + Overwrite attempt + Üzerine yazma girişimi + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + %1 öğesi üzerine yazamazsınız. + + + Unread + Okunmadı + + + + RssArticle + + No description available + Kullanılır betimleme yok + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + %2 beslemesinden %1 torent kendiliğinden indiriliyor... + + + + RssItem + + No description available + Kullanılır betimleme yok + + + + RssSettings + + RSS Reader Settings + RSS Okuyucu Ayarları + + + RSS feeds refresh interval: + RSS beslemeleri yenileme süresi: + + + minutes + dakika + + + Maximum number of articles per feed: + Besleme başına azami makale sayısı: + + + + RssSettingsDlg + + RSS Reader Settings + RSS Okuyucu Ayarları + + + RSS feeds refresh interval: + RSS beslemeleri yenileme süresi: + + + minutes + dakika + + + Maximum number of articles per feed: + Besleme başına azami makale sayısı: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + %2 beslemesinden %1 torent kendiliğinden indiriliyor... + + + + ScanFoldersModel + + Watched Folder + İzlenen Klasör + + + Download here + Buraya indir + + + + SearchCategories + + All categories + Tüm kategoriler + + + Movies + Filmler + + + TV shows + Televizyon programları + + + Music + Müzik + + + Games + Oyunlar + + + Anime + Canlandırma + + + Software + Yazılım + + + Pictures + Fotoğraflar + + + Books + Kitaplar + + + + SearchEngine + + Empty search pattern + Boş arama örüntüsü + + + Please type a search pattern first + Lütfen önce bir arama örüntüsü girin + + + Results + Sonuçlar + + + Searching... + Aranıyor... + + + Cut + Kes + + + Copy + Kopyala + + + Paste + Yapıştır + + + Clear field + Temizle + + + Clear completion history + Tamamlanma geçmişini temizle + + + Search Engine + Arama Motoru + + + Search has finished + Arama bitti + + + An error occured during search... + Arama yapılırken bir hata oluştu... + + + Search aborted + Arama iptal edildi + + + Search returned no results + Arama sonuç bulamadı + + + Results + i.e: Search results + Sonuçlar + + + Unknown + Bilinmeyen + + + Search + Ara + + + Download error + İndirme hatası + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Python kurulumu indirilemedi, sebep: %1. +Lütfen elle yükleyiniz. + + + Missing Python Interpreter + Python Yorumlayıcısı Eksik + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Python 2.x'nin arama motoruna ihtiyacı var ancak yüklenmemiş görünüyor. +Şimdi yüklemek ister misiniz? + + + Confirmation + Doğrulama + + + Are you sure you want to clear the history? + Geçmişi temizlemek istediğinize emin misiniz? + + + + SearchTab + + Name + i.e: file name + Ad + + + Size + i.e: file size + Boyut + + + Seeders + i.e: Number of full sources + Gönderen + + + Leechers + i.e: Number of partial sources + Çeken + + + Search engine + Arama motoru + + + + ShutdownConfirmDlg + + Shutdown confirmation + + + + + SpeedLimitDialog + + KiB/s + KB/s + + + + StatusBar + + Connection status: + Bağlantı durumu: + + + No direct connections. This may indicate network configuration problems. + Doğrudan bağlantı yok. Bu, ağ yapılandırma problemi olduğunu gösteriyor. + + + DHT: %1 nodes + DHT: %1 düğüm + + + Connection Status: + Bağlantı Durumu: + + + Online + Çevrimiçi + + + Global Download Speed Limit + Genel İndirme Hızı Sınırı + + + Global Upload Speed Limit + Genel Gönderme Hızı Sınırı + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + İND: %1/s - Top: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + GÖN: %1/s - Top: %2 + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + İND: %1 B/s - Top: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + GÖN: %1 B/s - Top: %2 + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Çevrimdışı. Bu genellikle qBittorrent'in gelen bağlantılar için seçilmiş porta bağlanamadığı anlamındadır. + + + Click to disable alternative speed limits + Akıllı hız sınırlarını etkisizleştirmek için tıklayın + + + Click to enable alternative speed limits + Akıllı hız sınırlarını etkinleştirmek için tıklayın + + + qBittorrent needs to be restarted + + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + + + + Click to switch to alternative speed limits + + + + Click to switch to regular speed limits + + + + %1/s + Per second + %1/s + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + Torrente eklemek için bir klasör seçin + + + Select a file to add to the torrent + Torrente eklemek için bir dosya seçin + + + Please type an announce URL + Lütfen bir duyuru adresi yazın + + + Announce URL: + Tracker URL + Duyuru adresi: + + + Please type a web seed url + Lütfen bir ağ göndereni adresi yazın + + + Web seed URL: + Ağ göndereni adresi: + + + No input path set + Ayarlanmış girdi yolu yok + + + Please type an input path first + Lütfen önce bir girdi yolu yazın + + + Select destination torrent file + Hedef Torrent dosyasını seç + + + Torrent Files + Torrent Dosyaları + + + Torrent creation + Torrent oluşturma + + + Torrent creation was unsuccessful, reason: %1 + Torrent oluşturma başarısızlıkla sonuçlandı, neden: %1 + + + Created torrent file is invalid. It won't be added to download list. + Oluşturulmuş torrent dosyası geçersiz. İndirme listesine eklenmeyecek. + + + Torrent was created successfully: + Torrent başarıyla oluşturuldu: + + + + TorrentFilesModel + + Name + Ad + + + Size + Boyut + + + Progress + İlerleme + + + Priority + Öncelik + + + + TorrentImportDlg + + Torrent Import + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + + + + Torrent file to import: + + + + ... + ... + + + Content location: + + + + Skip the data checking stage and start seeding immediately + + + + Import + + + + Torrent file to import + + + + Torrent files (*.torrent) + + + + %1 Files + %1 is a file extension (e.g. PDF) + + + + Please provide the location of %1 + %1 is a file name + + + + Please point to the location of the torrent: %1 + + + + Invalid torrent file + + + + This is not a valid torrent file. + + + + + TorrentModel + + Name + i.e: torrent name + Ad + + + Size + i.e: torrent size + Boyut + + + Done + % Done + Bitti + + + Status + Torrent status (e.g. downloading, seeding, paused) + Durum + + + Seeds + i.e. full sources (often untranslated) + Gönderenler + + + Peers + i.e. partial sources (often untranslated) + + + + Down Speed + i.e: Download speed + İndirme Hızı + + + Up Speed + i.e: Upload speed + Gönderme Hızı + + + Ratio + Share ratio + Oran + + + ETA + i.e: Estimated Time of Arrival / Time left + Kalan Zaman + + + Label + Etiket + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Eklendi + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Tamamlandı + + + Tracker + + + + Down Limit + i.e: Download limit + İnd. Sınırı + + + Up Limit + i.e: Upload limit + Gön. Sınırı + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + + + + Amount left + Amount of data left to download (e.g. in MB) + + + + Time Active + Time (duration) the torrent is active (not paused) + + + + + TrackerList + + URL + URL + + + Status + Durum + + + Peers + Kaynak + + + Message + İleti + + + [DHT] + [DHT] + + + Working + Çalışıyor + + + Disabled + Etkisiz + + + This torrent is private + Bu torrent özel + + + Updating... + Güncelleniyor... + + + Not working + Çalışmıyor + + + Not contacted yet + Daha bağlanılamadı + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Add a new tracker... + Yeni bir izleyici ekle... + + + Remove tracker + İzleyiciyi Kaldır + + + Force reannounce + Yeniden duyurmaya çalış + + + + TrackersAdditionDlg + + Trackers addition dialog + İzleyici ekleme kutusu + + + List of trackers to add (one per line): + Eklemek için izleyici listesi (satır başına bir tane): + + + µTorrent compatible list URL: + µTorrent uyumlu URL listesi: + + + I/O Error + Girdi/Çıktı Hatası + + + Error while trying to open the downloaded file. + İndirilen dosyayı açmaya çalışırken bir hata oluştu. + + + No change + Değişiklik yok + + + No additional trackers were found. + Eklenen izleyiciler bulunamadı. + + + Download error + İndirme hatası + + + The trackers list could not be downloaded, reason: %1 + İzleyici listesi indirilemedi, sebep: %1 + + + + TransferListDelegate + + Downloading + İndiriliyor + + + Paused + Duraklatıldı + + + Queued + i.e. torrent is queued + Sırada + + + Seeding + Torrent is complete and in upload-only mode + Gönderiliyor + + + Stalled + Torrent is waiting for download to begin + Askıda + + + Checking + Torrent local data is being checked + Denetleniyor + + + /s + /second (.i.e per second) + /s + + + KiB/s + KiB/second (.i.e per second) + KB/saniye (örn. saniye başı) + KB/s + + + Seeded for %1 + e.g. Seeded for 3m10s + + + + + TransferListFiltersWidget + + All + Tümü + + + Downloading + İndiriliyor + + + Completed + Tamamlandı + + + Active + Etkin + + + Inactive + Etkisiz + + + All labels + Tüm etiketler + + + Unlabeled + Etiketlenmemiş + + + Remove label + Etiketi kaldır + + + New Label + Yeni etiket + + + Label: + Etiket: + + + Invalid label name + Geçersiz etiket adı + + + Please don't use any special characters in the label name. + Lütfen etiket adı içinde hiçbir özel karakter kullanmayınız. + + + Paused + Duraklatıldı + + + Add label... + Etiket ekle... + + + Resume torrents + + + + Pause torrents + + + + Delete torrents + + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + Kalan Zaman + + + Column visibility + Sütun görünürlüğü + + + Open destination folder + Hedef klasörü aç + + + Force recheck + Yeniden denetlemeye çalış + + + Copy magnet link + Çeken bağlantıyı kopyala + + + Down Speed + i.e: Download speed + İndirme Hızı + + + Up Speed + i.e: Upload speed + Gönderme Hızı + + + Name + i.e: torrent name + Ad + + + Size + i.e: torrent size + Boyut + + + Done + % Done + Bitti + + + Status + Torrent status (e.g. downloading, seeding, paused) + Durum + + + Seeds + i.e. full sources (often untranslated) + Gönderenler + + + Peers + i.e. partial sources (often untranslated) + Eşler + + + Ratio + Share ratio + Oran + + + Torrent Download Speed Limiting + Torren İndirme Hızı Sınırlama + + + Torrent Upload Speed Limiting + Torrent Gönderme Hızı Sınırlama + + + Super seeding mode + Süper gönderme kipi + + + Download in sequential order + Sıralı şekilde indir + + + Download first and last piece first + Önce ilk ve son parçayı indir + + + Label + Etiket + + + New Label + Yeni Etiket + + + Label: + Etiket: + + + New... + New label... + Yeni etiket... + Yeni... + + + Reset + Reset label + Etiketi sıfırla + Sıfırla + + + Rename + Yeniden adlandır + + + New name: + Yeni ad: + + + Rename... + Yeniden adlandır... + + + Invalid label name + Geçersiz etiket adı + + + Please don't use any special characters in the label name. + Lütfen etiket adı içinde hiçbir özel karakter kullanmayınız. + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Torent, 01/01/2010 08:00 tarihinde aktarım listesine eklendi + Eklendi + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Torent, 01/01/2010 08:00 tarihinde tamamlandı + Tamamlandı + + + Down Limit + i.e: Download limit + İnd. Sınırı + + + Up Limit + i.e: Upload limit + Gön. Sınırı + + + Choose save path + Kayıt yolunu seç + + + Save path creation error + Kayıt yolu oluşturulmada hata + + + Could not create the save path + Kayıt yolu oluşturulamadı + + + Set location... + Konum ayarla... + + + Preview file... + Dosya önizleme... + + + Limit upload rate... + Gönderme oranını sınırla... + + + Limit download rate... + İndirme oranını sınırla... + + + Move up + i.e. move up in the queue + + + + Move down + i.e. Move down in the queue + + + + Move to top + i.e. Move to top of the queue + + + + Move to bottom + i.e. Move to bottom of the queue + + + + Priority + Öncelik + + + Resume + Resume/start the torrent + + + + Pause + Pause the torrent + Duraklat + + + Delete + Delete the torrent + Sil + + + Limit share ratio... + + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + + + + Use global ratio limit + + + + buttonGroup + + + + Set no ratio limit + + + + Set ratio limit to + + + + + UsageDisplay + + Usage: + Kullanım: + + + displays program version + program sürümünü gösterir + + + disable splash screen + açılış ekranını etkisizleştirir + + + displays this help message + bu yardım iletisini gösterir + + + changes the webui port (current: %1) + ağ arayüzü portunu değiştirir (şimdiki: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [dosya ya da url]: kullanıcı tarafından seçilen torentleri indirir (seçime bağlı) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + qBittorrent için gönüllü olarak çevirmenlik yapanlara teşekkürlerimi sunarım: + + + Please contact me if you would like to translate qBittorrent into your own language. + Eğer qBittorrent'i kendi dilinize çevirmek isterseniz benimle iletişim kurun. + + + + addPeerDialog + + Peer addition + Eş ekleme + + + IP + IP + + + Port + Port + + + + addTorrentDialog + + Torrent addition dialog + Torrent ekleme kutusu + + + Save path: + Kaydetme yolu: + + + ... + ... + + + Torrent content: + Torrent içeriği: + + + Add to download list in paused state + İndirme listesine duraklatılmış durumda ekle + + + Add + Ekle + + + Cancel + Vazgeç + + + Normal + Normal + + + High + Yüksek + + + Maximum + En Yüksek + + + Torrent size: + Torent boyutu: + + + Unknown + Bilinmeyen + + + Free disk space: + Boş disk alanı: + + + Download in sequential order (slower but good for previewing) + Doğru düzende indir (yavaş ama önizleme için iyi) + + + Skip file checking and start seeding immediately + Dosya denetlemeyi atla ve hemen göndermeye başla + + + Label: + Etiket: + + + Select All + Tümünü Seç + + + Select None + Hiçbirini Seçme + + + Do not download + İndirme + + + + authentication + + Tracker authentication + İzleyici kimlik denetimi + + + Tracker: + İzleyici: + + + Login + Oturum aç + + + Username: + Kullanıcı adı: + + + Password: + Parola: + + + Log in + Giriş + + + Cancel + Vazgeç + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + Silme isteği - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + Seçili torrentleri aktarım listenizden silmek istedğinize emin misiniz? + + + Remember choice + Seçimi hatırla + + + Also delete the files on the hard disk + Ayrıca sabit diskteki dosyaları sil + + + + createTorrentDialog + + Cancel + Vazgeç + + + Torrent Creation Tool + Torrent Oluşturma Aracı + + + Torrent file creation + Torrent dosyası oluşumu + + + Announce urls (trackers): + Duyuru adresleri (izleyiciler): + + + Comment (optional): + Yorum (seçime bağlı): + + + Web seeds urls (optional): + Ağda gönderenlerin adresleri (seçime bağlı): + + + File or folder to add to the torrent: + Torrente eklemek için bir dosya veya klasör: + + + Piece size: + Parça boyutu: + + + 32 KiB + 32 KB + + + 64 KiB + 64 KB + + + 128 KiB + 128 KB + + + 256 KiB + 256 KB + + + 512 KiB + 512 KB + + + 1 MiB + 1 MB + + + 2 MiB + 2 MB + + + 4 MiB + 4 MB + + + Private (won't be distributed on DHT network if enabled) + Özel (etkinleştirildiğinde DHT ağında dağıtılmaz) + + + Start seeding after creation + Oluşturmadan sonra göndermeye başla + + + Create and save... + Oluştur ve kaydet... + + + Progress: + İlerleme: + + + Add file + Dosya ekle + + + Add folder + Klasör ekle + + + Tracker URLs: + + + + Web seeds urls: + + + + Comment: + Yorum: + + + Auto + + + + + createtorrent + + Select destination torrent file + Hedef Torrent dosyasını seç + + + Torrent Files + Torrent Dosyaları + + + No input path set + Ayarlanmış girdi yolu yok + + + Please type an input path first + Lütfen önce bir girdi yolu yazın + + + Torrent creation + Torrent oluşturma + + + Torrent was created successfully: + Torrent başarıyla oluşturuldu: + + + Select a folder to add to the torrent + Torrente eklemek için bir klasör seçin + + + Please type an announce URL + Lütfen bir duyuru adresi yazın + + + Torrent creation was unsuccessful, reason: %1 + Torrent oluşturma başarısızlıkla sonuçlandı, neden: %1 + + + Announce URL: + Tracker URL + Duyuru adresi: + + + Please type a web seed url + Lütfen bir ağ göndereni adresi yazın + + + Web seed URL: + Ağ göndereni adresi: + + + Select a file to add to the torrent + Torrente eklemek için bir dosya seçin + + + Created torrent file is invalid. It won't be added to download list. + Oluşturulmuş torrent dosyası geçersiz. İndirme listesine eklenmeyecek. + + + + downloadFromURL + + Download Torrents from URLs + Adreslerden Torrentleri İndir + + + Only one URL per line + Her satırda bir Adres + + + Download + İndir + + + Cancel + Vazgeç + + + Download from urls + Adreslerden İndir + + + No URL entered + Girilmiş adres yok + + + Please type at least one URL. + Lütfen en az bir adres girin. + + + Add torrent links + + + + Both HTTP and Magnet links are supported + + + + + downloadThread + + I/O Error + Girdi/Çıktı Hatası + + + The remote host name was not found (invalid hostname) + Uzak makina adı bulunamadı (geçersiz makina adı) + + + The operation was canceled + İşlem iptal edildi + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Uzak sunucu, yanıt alınmadan ve işlenmeden bağlantıyı kapattı + + + The connection to the remote server timed out + Uzak sunucuya bağlantı zaman aşımına uğradı + + + SSL/TLS handshake failed + SSL/TLS başarısız + + + The remote server refused the connection + Uzak sunucu bağlantıyı reddetti + + + The connection to the proxy server was refused + Vekil sunucuya bağlantı reddedildi + + + The proxy server closed the connection prematurely + Vekil sunucu bağlantıyı beklenmeyen şekilde kapattı + + + The proxy host name was not found + Vekil makina adı bulunamadı + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Vekille olan bağlantı zaman aşımına uğradı ya da vekil gönderilen isteğe zamanında yanıt vermedi + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Vekil, isteği gerçekleştirmek için yetkilendirme gerektiriyor ancak sunulan kimliklerin hiçbirini kabul etmedi + + + The access to the remote content was denied (401) + Uzak içeriğe giriş reddedildi (401) + + + The operation requested on the remote content is not permitted + Uzak içerikteki işlem isteğine izin verilmedi + + + The remote content was not found at the server (404) + Uzak içerik sunucuda bulunamadı (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Uzak sunucu, içeriğin uygunluğu için yetkilendirme istiyor ancak istenen kimlik kabul edilmedi + + + The Network Access API cannot honor the request because the protocol is not known + Ağ Girişi API isteği gerçekleştiremedi çünkü protokol bilinmiyor + + + The requested operation is invalid for this protocol + İstenen işlem bu protokol için geçersiz + + + An unknown network-related error was detected + Bilinmeyen ağla ilgili bir hata belirlendi + + + An unknown proxy-related error was detected + Bilinmeyen vekille ilgili bir hata belirlendi + + + An unknown error related to the remote content was detected + Bilinmeyen uzak içerikle ilgili bir hata belirlendi + + + A breakdown in protocol was detected + Protokolde bir hata belirlendi + + + Unknown error + Bilinmeyen hata + + + + engineSelect + + Search plugins + Arama eklentileri + + + Installed search engines: + Yüklenmiş arama motorları: + + + Name + Ad + + + Url + Adres + + + Enabled + Etkinleştirildi + + + Install a new one + Yeni bir tane yükle + + + Check for updates + Güncellemeler için denetle + + + Close + Kapat + + + Enable + Etkinleştir + + + Disable + Etkisizleştir + + + Uninstall + Yüklemeyi kaldır + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Yeni arama motoru eklentilerini burada bulabilirsiniz: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + engineSelectDlg + + Uninstall warning + Yüklemeyi kaldırma uyarısı + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Bazı eklentiler kaldırılamadı çünkü bunlar qBittorrent'te kullanılıyor. + Sadece kendi ekledikleriniz kaldırılabilir. +Bununla birlikte, o eklentiler devre dışı. + + + Uninstall success + Yükleme kaldırılması başarılı + + + Select search plugins + Arama eklentilerini seç + + + qBittorrent search plugins + qBittorrent arama eklentileri + + + Search plugin install + Arama eklentisi yüklemesi + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + %1 arama motoru eklentisinin daha güncel sürümü zaten yüklü durumda. + + + Search plugin update + Eklenti güncellemesi ara + + + Sorry, update server is temporarily unavailable. + Üzgünüz, güncelleme sunucusu geçici olarak servis dışı. + + + All your plugins are already up to date. + Bütün eklentileriniz zaten güncel durumda. + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 arama motoru eklentisi güncellenemedi, eski sürüm tutulacak. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 arama motoru eklentisi yüklenemedi. + + + All selected plugins were uninstalled successfully + Bütün seçili eklentiler başarıyla kaldırıldı + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 arama motoru eklentisi başarıyla güncellendi. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1 arama motoru eklentisi başarıyla yüklendi. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Üzgünüz, %1 arama eklenti yüklemesi başarısız oldu. + + + New search engine plugin URL + Yeni arama motoru eklentisi adresi + + + URL: + Adres: + + + Yes + Evet + + + No + Hayır + + + + misc + + B + bytes + B + + + KiB + kibibytes (1024 bytes) + KB + + + MiB + mebibytes (1024 kibibytes) + MB + + + GiB + gibibytes (1024 mibibytes) + GB + + + TiB + tebibytes (1024 gibibytes) + TB + + + Unknown + Bilinmeyen + + + Unknown + Unknown (size) + Bilinmeyen + + + < 1m + < 1 minute + < 1d + + + %1m + e.g: 10minutes + %1d + + + %1h %2m + e.g: 3hours 5minutes + %1sa %2dk + + + %1d %2h + e.g: 2days 10hours + %1gün %2sa + + + qBittorrent will shutdown the computer now because all downloads are complete. + + + + + options_imp + + Choose a save directory + Bir kayıt dizini seçin + + + Choose an ip filter file + Bir ip süzgeç dosyası seçin + + + Filters + Süzgeçler + + + Choose export directory + Dışa aktarım dizini seç + + + Add directory to scan + Taranacak dizin ekle + + + Folder is already being watched. + Bu klasör zaten izleniyor. + + + Folder does not exist. + Klasör mevcut değil. + + + Folder is not readable. + Klasör okunabilir değil. + + + Failure + Hata + + + Failed to add Scan Folder '%1': %2 + Tarama Klasörü '%1' ekleme başarısız: %2 + + + Parsing error + + + + Failed to parse the provided IP filter + + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + + + + Successfully refreshed + + + + Invalid key + + + + This is not a valid SSL key. + + + + Invalid certificate + + + + This is not a valid SSL certificate. + + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + + pluginSourceDlg + + Plugin source + Eklenti kaynağı + + + Search plugin source: + Eklenti kaynağı ara: + + + Local file + Yerel dosya + + + Web link + Ağ bağlantısı + + + + preview + + Preview selection + Önizleme seçimi + + + File preview + Dosya önizlemesi + + + The following files support previewing, <br>please select one of them: + Aşağıdaki dosyalar önizlemeyi destekliyor, <br>lütfen birini seçin: + + + Preview + Önizleme + + + Cancel + Vazgeç + + + + previewSelect + + Preview impossible + Önizleme yapılamıyor + + + Sorry, we can't preview this file + Üzgünüz, bu dosyanın önizlemesi yapılamıyor + + + Name + Ad + + + Size + Boyut + + + Progress + İlerleme + + + + search_engine + + Search + Ara + + + Status: + Durum: + + + Stopped + Durdu + + + Download + İndir + + + Search engines... + Arama motorları... + + + Go to description page + + + + + torrentAdditionDialog + + Unable to decode torrent file: + Torrent dosyası çözülemiyor: + + + Choose save path + Kayıt klasörünü seçin + + + Empty save path + Boş kayıt yolu + + + Please enter a save path + Lütfen bir kayıt yolu girin + + + Save path creation error + Kayıt yolu oluşturulmada hata + + + Could not create the save path + Kayıt yolu oluşturulamıyor + + + Invalid file selection + Geçersiz dosya seçimi + + + You must select at least one file in the torrent + Torrent içinde en az bir dosya seçmek zorundasınız + + + Priority + Öncelik + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (torentin indirilmesinden sonra %1 kalacak) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (indirilmesi için %1 daha gerekli) + + + Seeding mode error + Gönderme kipi hatası + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Dosya denetlemeyi es geçtiniz. Buna rağmen yerel dosyanın mevcut hedef klasör içinde bulunmadığı gözüküyor. Lütfen bu özelliği etkisizleştirin ya da kaydetme yolunu güncelleyin. + + + Rename... + Yeniden adlandır... + + + New name: + Yeni ad: + + + The file could not be renamed + Dosya yeniden adlandırılamadı + + + This name is already in use in this folder. Please use a different name. + Bu ad klasör içinde başka bir öğe tarafından kullanılıyor, Lütfen başka bir ad seçin. + + + The folder could not be renamed + Klasör yeniden adlandırılamadı + + + Rename the file + Dosyayı yeniden adlandır + + + Unable to decode magnet link: + İlişik bağlantı kodu çözümlenemedi: + + + Magnet Link + İlişik Bağlantı + + + Invalid label name + Geçersiz etiket adı + + + Please don't use any special characters in the label name. + Lütfen etiket adı içinde hiçbir özel karakter kullanmayınız. + + + This file name contains forbidden characters, please choose a different one. + Bu dosya adı yasak karakterler içeriyor, lütfen başka bir ad seçin. + + + diff --git a/src/lang/qbittorrent_uk.qm b/src/lang/qbittorrent_uk.qm new file mode 100644 index 0000000000000000000000000000000000000000..597a22c47220bd60d5c88b05cb9fcf82f0e2a322 GIT binary patch literal 103978 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

3%qguM#zt8@~O>^sb^nX;16Gl3Q=)<;LYWL zYvV_OcTdDRA6gxF|26F2O%3v?o$#B$zrTh3n6xDD@uydSANmT!H_w3H`Oku^XZC_W zuPDfCx)FT;)`Cg9KxaMU3Z`AN8T$Pb1=FX$0ef<J0Uz7$D>!!d z!$LdahJwE7kAY9s6~x}b`=2~ru=}K1=mn1#48kX)iDbd4^Fg=&iWYp~0O0-f#RXsb z#@ApU78aa+K@@nqw&2{`CW4Rtq2OyZPr;A1w&2qE?ck@c7F>2G_{VeC6_@I{)~`1y39fc@aOi;3u0g?nzG-Jbg?L_W96)7ypURe|=`biyz{1 zUq8Cw)yFX2{l6~w)6>vXPR%X&=Peh3AO5`HgTMozzk-5~S9QU@`IdVACsFX9^BxxB zzU_s1Ke!ln!=A$8vdba2eo;8X-vB>IPvL@JVqGWSQdssD;M?<^v9zHuPrU31{Lx-`v8)cD#4RP~l(}_HX_b zg?pw|2=SeF3Qv9v{QK=^3s0+oeC|4|@U)*VfxZ$hJmZXKg|@u2@T|Ul(DR=z{95mA zIEN1uUijgK(0jTIFIqDd`q?G&snwlRc?8bq-`@&Z^eGy87;bE#g8CAi;Av(eFyxA zV~cJr#QD78)S|op^{f!@mlZv9Qc!4xzM{u|QUklhn@b5 zql%u7PJ|wIT+#EdcEBIDwCH*I%T}CO^x{3hkMGY#FO9oQXno%=`ptJwMzuqW3Pr`1d?n^#0vg&p9_2eR|_xgn0V=U|{V3 zg75txIBq@8&&9_EXTAIj_>B$-R^A8xRlhs9@ahWCZ(XqJajd8I?%=Z0PvE~=5?u9l z=&7qe4c6{m4!&D1pW4Kx;MyG+ch_%%jURztCL9@DzXR`0J2`mBfzS^Rm>fLhx6sSR zZw(&y%TCDcp9R~dgD&^|2hZohSH2$H`lA`JgL;F<)jtgV{(#_df5!e@a7ZwGCE!>* zOFi%WXE36J4y*nupW3AV1S6YH5#rG7;3>4D3m*)g{wnOT-Y0`+eeoF~9;ggn0sp7C zW2$^=Ybt^_9b$7#`d{Xf4TLC8`FZWKvdHKdO!TUZr0P-j&_`vjE!tXN_ zeBiD@(Cbsd2Uo$a+49HW)1Uqa^6{|XGvA&ewD5VsU$^2MUKtL)azEgIVQ=uAf41W9 ze-HkH{-G^3!S}C)|Dxmf!H=WOLj2^E;3tznhbLYh{4|Vl9-L8}-TD|}LZ=k_hwg%% z^@ZZ%^WG5J(4EEORv!ty>955T>p)jO{e7{d`w!O?&;6e+@V^U-=iP+)zO$BwyO+kREtd;#z{ocFKUZl{yFe^=n2KYUm3@^|0;gxXuuh4E&k_v@RJ8_F8*}j ze9-xC>T_*t)^#jZB0k*3F{)sWGo&JN0T*`9kn%;_;oJ+o>$iq8%Q?v?$kKj6yHIp-`5@Bq>mNwjqz3a)?xm&)_Xa11IeCP zJpIE{eNzGCHea25p#h*z@YMt4rM~6X%VX+$;*mr$*54D>8wUEqd((#r%3&7zw)UT3CqmeeUdJoBjpcozNUzr$zS$C?t9|PM@fK^6ob~Zg zv@@JO#Tef-d~iJ$v)Z@Z^-6A2q%#~%c)Szv<@jpEJl_@vNdD$fU)TenLhM?tZ;5Y< zuiCf50w=${CluY4(33GQhz@zZxv``iS<@NI~I}X4J9M7X!?5#L?ZdI}?)3eV~sz>%-Z4Un28o=laHio|gEUM7ctfZzZPNh7DOK5z&CJD;=X1)kTN& zNHiIacZbxLdc$xeP_GbKh0)gfR$#mp7`YZB*Mj_4;jgRlZwr3sK8*bPVtGiHV*?i9 zbIb9GrM?a38`jFE*7t-vcj?`+xSoi0CkI3Eus+b=6-tJOS#S*i+lB?N0}upoi3M5} zzFUGRouJ86D(Qg;S!hi?r9Kwzj>P*wM3U*~UE$uaNgCc5S>WU9mt${$53HIK*MZE4 z4RgiS0BNIx9ZhVABzEb8@klbPcZND~z7vtX@=$os(dru~7gr0sk+m(u{|fJQz#(Va z=G$cAF%9$FAF>A>pQx7aul8-TmOKxz^!J8_^!|8kXFSxW$D-wl&UiQ+)uXXwq&w0n z&&DvQUnq~`THiX%Pz4A{cZ6x7qzSd>>m;&?2f%O5J+ZN`Biz*$?$VR-Q0K02TTfQFg0QSN&gNA@P3WZMXB5^^?Tx}9iQSEAY)~3h9L=nF;P?pe38ZEvJ6l1zZS^xjx!s8^4MlY_DNuFSCR276qHx#|E*jWr|bxEhdhem)6b6MhE@ z2mZDJa-IglZg3}GBmTM^qNN?b<)>Ej^WrE0fr-D2lcSTK$hm68F&5^RZVv5<^bPds z(E-p)T#t3@J)z$2@>oC4MrSM<4R?|?B=n;eR_i!LB(1JvGOwo{>oM`PRAQJsIR~@4 zc=BhYliAG*pZX?~i|-dx`qqBdypV zWDE|6AsQ_Lo6#Bu?}w-}q>Vfrow2_Dkz`H-w8d@U7^G(73}aHB0>$5{4%XwRI!SLz zAmZGJQn3N5cTDm$o5KK%M67prSnm&m$~&dz7y&ma-4Kp#Y8i%^EXfFl%`VfxuvS0W zHEmBUk<_Em_l6NPWxkofveNLE%H`Dq-#AiGa_S`IDwZY{5NnV_(rzeum89nqy|%i^0%3+!G8GfVGUMTHaOxhVZ|x5CW(H=X zJP2gNWM;}(sB$rGGDrS?DNd-`boD)f+6Hn^pxc(g#H|Tv8$*d?xKEFOiRsCnaNjVh z#~9yaNoFoJZR)mA?*N7gC#9B_?1?1!165U8Z+`jb%&W@5(ZxRtJ=ql%75wxhSWB@! z=y_eOi9|zeFxndnb%oVla~I0rs$TlC2)< zjfX>BLwa}*Y_>$1jzb&*sylmPF+4)hrFuYq{OE{lEyKB@ePaq|rCM`6J8a9epa zi5iRHR`U2(0nKEM+Z>uzBY+~wftZa?Diz+eH&Q?pC1Q?Pgs*EXqFPl40W#VH={i-Fr=KlCnx$kYnBIbHgkMQcVP#;CD^B_I`8QGlHY8VP2uSLyGjfVDT1 zT8$SEp(SOnsb(~5O2B04#2IogE-~VwO5_P!VThFt09Hvfr4~{twYf-9T_O?L2~954 z5mqjP;WoV5@{CZ6z^K^T)%Z&FCw0+^gKvPaY87pw&Dzc>7H`m7+uC%SJB+kfO2Zq5 zdaNl58fff=B`u6J>JrJAQ%9v8NS2|PrBb3Cdu+`#(U{5FDl!x)_=ZCxH;6he*_L7j z_GYE37MLLcb}UUdy$i-cCv=RVkycgeVzR@~q_vWuxe*d;BQBxY(|{vKBNzJY)G^C2 z?0BX_rVx>YVxI7@bixgX-U+^mK&>*UY0SF0YkuP%8eXH|tB3dwG?+@zK;szJxmdua}mN;ztvQBckd?vJDdQ^wQ8 z<}sw8u^q3$O;Ko#kuE(X4bYLco!F#BO!-8o=_ZyXdqD(BB{!RyT zkmQ?b9kvNjVXPoI)USA()T!ZdAxEcD>srZ(8g$csEP{Z$b$z#hvS~L z1~0MQ?3P;t^vbiZgq}sIE_P<4a;h<}@^tXH((P_VVTJ>t6frMawG9vsv~cNmHjXa7 zbKucB9^>R>5`~`2CqlF`)Mxk@hFi!+xHFUw0UlL1=+alS z0AvtH;3mg-?;UQkt_c^abErN223exDseVFT(#go%l*E0J0v3hd(V(!@KF%B2C(s z=iKcQhQZiCZF@FfOlSyoldZaRg8If(qZyZ4eL|tR}w+m!W zqQ~J7^Q3`4k2sazSK(`g2>9koe-82f3F!pujKy}*YszS4wLWjo zqIqTbS~agCa0HzYJrZ*};W3jgqev9tO~vo@?s%+^IF0Mu!yS4@JT{nsr>GxZLK1an zI3dMdpk7U2COwpZ4H765Y{}(OuH-T~R_BrV#=cFH#DW!A1>+E+@u%q4APUjb;VX zj5HwG{}tE~xuw2l3(j%}oJRPq+=NuYJsQY1elFaq4JRA4xB6fQT-fG4L!SYv&ucS! zQBj($NSBmoLb_5rzB-&!ZEa1J?M-cn4@SEZJt45hZfUS*B2StfbbQh*Q$$H$Sjt(j zw(T&=1T(x>*9nf0(Cb<@A$1^1Tc;<6K&w=g83=|?K<@~5h6dnuCh1wnM#&FdQfVf* z=$a)=(jT}M6U&SUfI#tAho{MLoUv)8t)~ELk;2i#ft8HVe~rXA z-Jl0~mY@_NE&w_~>HvK8;H3PVxge8d5{69h!t!y_+4l6YJ&P%QM)g zfp%+|nUKB%29QdtP`UuUZ%Ei61>?I^h)mtg&EAzoNY#mSuOdq-gUB{wY6&f}0piNd zYM_!^Aj4{@T;Di=_&gFJARID*KRX3{sxmTIg|9r8l8P*fnCb?CGzq@Y38!1e3986_ zFsO1?ufz%|(ukXkXTzFqCZ|($Wrb|zK_G>7BX*o|)^j2MDeEQcmvbqd44M{r3R7Wd zP?_R&1@t*ucWMW>OI=##aN%>SCG><9S~h;#A~lK3Z}T&f7ukHtTF)+fJyseGJjgvb z4o2n^PfRS1I3$k@c`Xz*{2jY%Fk75A^N5kD^(PVS8={}Ki-UxE5!RRXNk+^tcg@BO zW7!r@!fNR}QOPXSmr}W!?G>!DS7IEL&R&Eb;WT!0GANc%JP{P@m8zZBf!}7ZRa*m6 z44;(8@6-mQlaJzO4)FPDLjWvs2!JI7)k7z;Xh;uHPp0o!GFr%hB^hNvR~oR&SM2~J zGswtn!D1xco94XfbG36A7CJy*>Hs~%0nke$hJThHpxYrM?Dvlf_7Nz+pb-X|c#4%` zOA3Os4u7L9S|fjpd|CX=)21TmPMb)be{QZyGUQjq?`)na)n%z4*r^RW9rze6*_A;- zf%&8K6P^)#tAvx1sGZ@+ZqO}sDRLUBJDGV|)2J}0c)rqV5In#t$=_4YlC6-IrmxBn z^eLw)6A!;`RA3RI?rgx!Ozi)T1@?I@*2pMKVTIs;a+6IgNNc783@}L^!xW9E%)Ns)RK+L?}~nTxm{Ie@14R-(%`B<B#2x%~@0_W3lNU_91{~Cy{4m`dGDZz7(>G)7vZqijZM1Ga-OS z$erivROZGuW7}!+B1{Fm4~3=EAswV~hC0F>q_}T(SgZvcgK46MKQ;aBNk;xPWfgTJ z9BvotirSErg6X-#a~64HZ~|x#3=r?r{n4D_elOU{AgL|rU zhmc;G3_*7Y1s2oTY>{3lNiqQjXjCVpPd!~`@sL+54~kL`DRz;#Y|&4_I^^8$0v0y4 z7<92G+&Mspe^X4=(9ol^5YAUKvDfB>xf{Y!sJJpqt*|lmy$Mzzk<5&n08gGZZ$5)i zGAl^Z|9Wgi6P(lABVF)>Nk`2jX$h;tt8z}Hl3|UIvo%VmPNvr<$ZS2g>(9nt!6w_y zCP&zaq2M7;G}(z|d$A7-rTT@8V(bFNKI4mY+|u0TzH*oF#9t{o#$li69OP%HuC9fu zDyu1^ZdAp6#HWytkFOko3nF5eOsmpf=+JZ?Z)r%-`L}hG9_m8u062nC0gCMpB@!V2 zE_#2F(9zo~IW6Kfp@CkQdC_pSLDWHyrS&i>Eo*9&^NRYivfxQ2Fha42&$ryvh0LcY z@mvUuWR?Afl?(^-*Wl45;#4-o3PWQti$zfHBQ+T^Bo?=%2Ubml^Dvu%N*dnOuhj-~ z3vuA^liTl0JA%FoMT=$)*$Rix_lS08`{BP3q+sU&$~TbuhDr`Q*$>&^ka|d>g(GMu zJ@wM9Yi*+R^g_bOI*U{Xuh$Nq4K@r-3{a`k2}i`xyJ8Ky4HoRu0cqcvn1CjUv24v& zW=o>NiIsW%@UvIqUoTw9og##1557y_FV!w$UE7W%6ma!8T(ORVxH8M5;~)Vzr;^G3 z>dH!)@=tZRTJd17#mSSY{ddpoS zS<4KZR4RKTj<os=E{iza>nPG+el?y z)si^hw(|;2!<;6-BK%JV4Q_is=$t7 z7r0?*!1RQ`yt}|8WNa)ze6>lV){uUbx=LoN8UdLqV@bcf1|vb0G@kl$uR1RnfO3fW zBxcH{2f~O5vNy360$a(sMUsxD<4slskws7kQplk&r%FmD=}xDwG(pnaRgE0NUkqSj z`H{H3wY7=P$IYRgh%X?H8I|=tsgSGG6oaae_1Wp^^W zn#e_>nM0Z^w-x|V&zLW~f_fhlqdLO+PMPILnx2=ZUZ>LQ&eh7om_eqzE2{NVYggWJ7udnjMm0p2z1PnQK4idetgjXY>CE3vI(= zfmJ=m;s1OXdE|3q#Pmv#3cQ)g|9?1ZPsiCnKg((KL~jgLnEy4TRlsy+StWJ$G@*gt zsU@$4Zp}D~odP;(OBBH<7%);uNO&MEJWpmR6bc3c$fOnPbyHnA>@PPPn%H6`LK=14 zX4Y{kU!vLT$~>}|g^w9PUW{UQios~`eE^xsETnR1vj-(d+$pSP@dz0N6gqUypn^w_ z5R)pIs$;8h%N;hBWm%YV1AcR+f+qFFv_Vi*&8#mJ+`@U`wU#f8Xdw<~?z-2dXyCuI zE?SE+U+*)n>w4*2fx#^mY}qG5R-5o>QUf$CVX|z*oDYj7X?hhtKMwkR zC6WRRdjdWXgMCP=MVVo=Uzo?oUEhekrol!2MHNYfz*H>ROqMg8q4;Ym<8N~8^Aba2 zmU-9-~@7vnnx3&*lUB1<9s4IXiPlu2O1tn!F$WVF2*AW0~(n2|tuBP&wdc=3JXn^VY?%_BEQX>GU%6^3&PFI!bRgu0C z5)EuxEK6F)Tox8fr+_*E+ys^jE8E#!^fk8yb=nCyo0#UwqiMzWyQB*&5*;uT@>8** z-I;0Y(S3=9%SvIQ2gh_ZQuv$VhreGgPq#{pHCYt;Tfm>C%M^H(!HeU9pQ#&}-9r{i zfyVLOdQusFvr^8d*qO=7c#Ke4MIne!D56wpUW(Px&utpHPXAS=gG%_u0nfy-$uK!L z#V~)TAhuUX@vA&xN?9Ze-3VG@N}MvF)xoC#Ha!C>6>Xac$P{443W))W0`arW5{L<< zoX~1RvIsb$Y~X;;v%*-3ep?(r?>v6e+e_^cDZHULC9=T|D|DnpM`bQ_d>{&!uwjFg z>FjcXfKdn);_%nQnD0XsyB^w&j6kwQ(vd6%hx2Vn?+c?n3R{aP^}Ir7BPP06dFbIi zmeb1QZ|O=#qXx#x6aDlwcSL&Og02Vzno)W^5Qmh6i(Q@<2p41SNFp&1?vkuHl|;pK z=!DH769LG>d!!>EuL-I;y#kVb)TH^Ls2-_&WHW7B?GO94 ztd>(MndKCY({ak^kYpuFq6d=D6oU-BNp80p#bVndQT$#`J5?~F7-WR)bqg~)^qVu+ zYWx;RdA$O!Przv)O$}>Rq(lQJ%w?UuX>gJSG17WPEp)kdcTFB0s z+rn&EFI-Q+YxCsC5f6j#aMzp{%w_nJ;YU?H?1f@Uf!Je*5V0oCor@MH*d?!-%P?~( zSs~tawlShjMOH?U#Y4hUL7Se(&uv4K7DNM?#F+#u=m^QW=2Xb0V01PX;>l)-fT}lh zBc(kS>y^Ra)R(!V2VrW5&225oKX+RsJm|R~Nd+prxCT>GnyHvNRcQXCl5E`(?&)=` z?gQUKJ}raXGP-7RO0Q`i2H6lRDFY6pX>o5-!NS`}9*^BK6-w9s@$^VVnbb}W#)>R5PT3NT;Z|#93sIWE+Im$U66-|R8~jJ6 zOBt@UIg2U+dMlhxv8Wl1P2HF-&jujW%g6v#H$O{f01>9P&|;3oMr?*zeMttHW@uX= zNPi1N0cfh1K39v)MbKx(wByH+Zk-5Kp__k5q^N>Jn+Wb=0gcolh-piGmtLnG@{&RHt%XX8{T zF-2QLX=G{=y6b3JLRYsIIJP0oMi{7Z>5oTZ%*5~leT-DVZ2GFT-p@1p^?ALf8d@sx zXNAKgv62uQL557pSLGZ_$wRDRCtz6FOcPyu!3dEdkwHMumJ*iCg;_!FmR__6YiR*l z!xlEgz*}HQz+djUP?od0NtB1hUhen?lfH&O040zClb|oGB`=VDK6pS?WkhNqIB4a9 z>2r}q=7mUo)Poh-gJl>iAop@5DZ|2xuW^qNnM_eH88TpPfFdKb%ER&W^u$<0jp0yE z`RTPDHLP?Dg8)V|?061KtI;9by+*F~jhE^kb37=NRGt{);YMFh%;&}RU}afLn6{x8 zPPksHH_38}mz@smP8tlB>U{no4g<}geGFJOH9 zy!E-PX4ykM^|+ORtEwm%)f&lLp?f$x`a5DN)?nkduwQPwp)Jyl;Hl)Ys#vMG&SHG& zMZ%7CtV*R6k|PN#8#(GLq~(sFex537T(~Dh@BKt0_(D+AE|Er##eDgYDf0 zKA>7@!PFQVKv*9RL}*IK$zGx~3O?oG0Dwh8fQZ=%zQNP6o`6X17PT zBst?K*0M*^bGkugJ5*Gy1$D3tCl!A&Vn?7)(y7XLwS5A^J5Kesp4gzBo~v9mBY9C7 z#xmU#X4WSe3%7;ZjeVqxEpLNrt?YG5&!-ZBWk^{v>_Qa^Y^Mi=8vHbXMZP`ytZLK# zVX`?*X*<-o!jbcQSX&J30O)s6&1=91*-Htrd^4MwVXuln#?)w(3c4&OmFb*fk*Qb> zJ6xv9R&R_3+Xk>nNTAM)&@NDwC0DV;(Mvsk777>MNlo%FRa8~_3JuR`Di+3VC9-HKRcH_oPM{H(lzT(#o&G$-^s}a&-0nEg^o|=9i(VAAEoE$)LL8NI zFn5{ZQPQr--q{m@cD~t<4lXu`t+d=T3l`b8!(=XIOC!cA5tw7ec6#QS7nH}R_00r#QW76yEEt+ z?Eoi`Q_Qi6Z5`@wtTU1^emNy=iw$0HtvTQ9s_$t}lw^7zm}Etfvms5;8c8pmqq@zc zp4$~EXKU2V#sYUtD)aE#B5!A_(lHrGW;TfFVfJ*kZfzNjvsHOGP1TgKw2Wd`xwWlT zjN2OTwGM%b3V5w!HqHU{bOpH?VP^zz5$G7V=+HT54I11QNkE3o-5&11(^Eyw0oOnu z4C|HbBfQPXNh4U#1rFzo7vR&q-v`k+3pRs}QNT~U25KH|Akv_sPcSpJpH;HjjZp(C z9d^~)V)=W!$Ko9K)Ou+HT)PasRN~Tst^N3Jai!|>m`cLiGC@QRg?Ur62~An3#08n| zLEuNJ@eI32z0?Vr>VF0PY6wF|Aj1n?TBbV!&D0%rRgzPOQ8zt+ZVl?Cx2XyTL`ec^ z^h$@I839wIXmnBmEtzJqTe_$OD{5OF%6CQts?Hj29g7O-2y+j|HSso7TzqvGXqnl_ z&Nyw8L(*OD+yo_{~uUrtTj|CCTa3iPQ8SMkk%s>jBf9wyA|Dt+)mE)F9+68`hfb5NohwX2JsF znCT^e;Bcgd-3IlDR@L_Gl&l1#jU@K-G?Y^6(jj6A3JY^yMafU@45$v!&~z>#@N zIbeWJXIu7M8!)EjveK$E1kT}}HPO6s6B?Qd*pl_Z+#w|EifQCw{S@3BRIAP^sv{NQB-+qDm zRaTIoYSl1Yu!~leCRe4X&udZ3GAwEhD5#vNn%-yLl0(y-X3-kGyxe&zNUdIzD)rS1 z6UH7{!%tWzmxcrx$NDl2Tj5ml?#FUK$67XG;G$>s7SyG#lV$dVQ`;MJ3ou zQB_`HUYh4BkG6))t&jB&;fQ4#ZxW-;Qp0y>Bo3#ptYlP?txQ9#h5vOF$r}beI*o`_ z4b!eMwG+c(3ul^mq$q4k6{Z(u_*{%HD>I%N9E&vVx&3jcxS7Bt86>pzIxcq@PB7ZZ zd9FS1o5F!6sL2gK(g;(RNwvv5I%IFsX^G7=*_)Z!f)!d+Hx2!A214-p%Tjm7#>f?* zxec?(=@v6pbEr^6>H#ex*Jka8)jr*8TZ2+{QvMgT3$WnIYhg18cm8&Iv{se3aZ` zoX7F7b2b3Cy#Gw~z9E^Vw9W~_hM@Yyme%c#{unu>&BzmxJ?9Egz+iTfmdeLQyu;Xn zyX%;0mZ|O_^*XQV?nB!i8CTlsb^U1C%*$|`(Ax+kK?RI@1l?20LS%zRl}N)GffwZ}1SVvds7xcpL-XvV(#(&nBMbv$|W4*}l zH5ftKP~#j!G4Ky{%6dJ|yr!9_H|@=B)|*7B0>ms(ply(PFy;Bd?>7Pg=tLu1ill}& zov9ZKarYV>q}1-^JzT6J;18xAE{`x2Az8x}O3Kht8kFpyOCPt{T10J(GTrIOT8k~R z2p!Pz2&ju>q{Cfqqthz0gUvJRaK|wd1&x9U-i#;vfw_WeX#h<(as?@ifix87*=<1W zT$dnn{2X0LJU4&|p6M4$8LUZiPkUqBn?WQnyT^7n=*%f(zjoYQt7`R3G^_R(GB}#H zmT~f|(d)sEE~{yv*u=9g+!NZ3+%-?wCx~_Os&SXY&U!bnE|P3lMw{o`he+i>ZIh`S z(Bxs*A|0ztW-|=c^yWX-oU_&q(e<0!4u%_SHTUrZrb$X{+wN8xqGvW108wEax*qr) z>nnNY%Crib;!aV%SmQTipBh0n3La{-%=CDaUzhPs$ ztVZ^Jb&Bk_hxR5`P7)m@XoX@?N-pl6+l2&3Z`_MUSXF%@B(E?rgaHgg8jCD0Q(hSx znsLsH?9jM2qOKcEL!YX(abFD1MA8OuFo#FT0&<*@0IK7Lh4_%HF!6+U2lykoAw$yi z8`xK`SDEn?Y=xVBP#03gZ%eJBH?Gg4*u{dU)Xp4L&KQO$SOZ2sN`eu(m@0$ugmS&1 zCi1ixncQTafP+?)SGZKM0}5T0_s%ASwq%UHLhwTmnrQEcY?;z zTr#p3%+)J$^g5N?~LZL(tqPgXuG`@hEt|Wm#kQ-1j9(Daf0-@mr`LY1qpdb zyOo9@PH`tLmyOG6;nA$2-*XM*Hq;dvwKa@8{EYLA&{Yd)>u}t{&QJj(xNHFTSvI2F zfL_AgxJR}u4C|#W;loG00XsZ_9|ubD?2k$CL2W95g0#gDB6WXKinGC?5(2i3vA_To z@gaRH8%a9uxNo(uRzXKXZ>y(7RzkAIn_fr{vEY!SV;U`i0Q&0+do!qjY|O~UH?~fi zkIuZ<_^yyl(N8;uXBi$Fk6q<~17NJ%S222~f2;jgYGA4wKqJZMF#sNEQpUY0@m)}e z*oGRny`UI=FO46Ep}5i7b$P~An48Q5dM>kWp=Fxtgz7?oJK-O>*HApm^lbxs!(}=Q zCvT*$hbK>3GFX{%OHh^Psg!I+(sG69f+mnOpzBAUlzzwe9iVbsWE_NuH2V_*x*ol> z0u|PnyuYene(jj=y-&5DtEZDa`5Yt99Zi@ceFJ@ZbfB*Tu)yMioHp(V$slg>q<)3g zXO^t@vDuj?M+-u-kkv{V;aIzWBU@*BzB10}Md?7UHBli#847EL*D{SLlZN6z1;@PP zLe|D()1;k_-)W0j$+E^@%Nd>~=7n9i*p*(PH7rf3hU*r8{r z3+WTR;c&k`$hvxi@Kj0??>SY?n9>$di}(nGl7=1wuo>e~zT@Hbd)gZI22VefQ_HqH zQq{KsFm5PKn>pZ7>*Tk}o6D`ePl*jn3tQc$uZmHl-ZQ$I>WNs&1D%xs?-vi2rT>NPtNl1 z^uB^Jn2FQGTp+V$k-hK*CMcc^i9sWikiAi{&4f&*R3mWP- z#`wFOcZExjrzen80Oat7YOYaL;rTk_9Cmi2O{V!~v4i&}PnY2lujEjq@mUKA$TkkN zM*BP`Un0G2(y0MtLG=JRRKZzE)KQ^gbMI6Nw?UlMg6rM&VH>b{1Fw?xIjudIpM!aS zoPHh(CWli3a8b7MwJXe+Y*oL z4t09#>=UGSoM(-vj~2f(B{-)Q&Y74uG1?ahr;16_A?u~EjcpCfCY^NS!-EHP*AtD? zC0MIKLv;3}Fa&F5s59w!0c;-yEn=^cnzJ0chG|mVX zjkJH=(ubrvT2Yf!YgAqdI88tzW)ZeC_(0+@qf4nOpmMdiyzGG!ig`V48U*}QBr8=)HY0dUO7V-FeUy@2Cj z!0^O5)3Mz+SM~z!4PNG;`#dG|wYXRNye`4Pf!JwZwV6*TvkM1o{r* zb_~h}@mF{g-SJ9Fi8#>Kq7F zp)DDL*sIjr*s;Jc?LB9yb(~1cD#@sdEthCqiyf1NGY`Q{;swRL5kbJ8iG> zVBv8$Y>M=^5A|p8%S@FFZFt{vt_rMs6Y!C80P=cTl{9k6^&RAleCQStWg~MUS~R1d zO*?$OEjau5o%G|VHdqw5qzxi~r_B!iErJhA-`Wyw0p6SI+RIxux2X275TJv&FMuv= z*;Bs{_lw{<&kRzaV9DLuI+p(-U>9dM}~nLc0u2pxXdh~vQo*?H5tY*$NxPd_eW z6eETtrveu;k_@~o0ciCg5miEMb%(}ZC}EX?LZPkxuAB?J>WlcauU(!hfigSq0BN{7 z8~&KySlruhU&4y_VeiASX)GUO%NE4mWI{U2;N`T=R*rO6Zt^@$Oe-)Y(h8u(vBK&!MJAqV_ity6gav|-csM10$xSN%~OC7 zHY9~{mxl##p}M_8wy2ZbCv}KCkRaWcw(Hl=u#@L!gVLkRLViwZzmbO`E!<(}{n8jo z54c8=ek@n1j^pY?xijH-G7?TWa_lpt?gMjaA63aR(B4V*K!#tUy?k`+X$?rD+|kG>U(0$d2uClc~3G<@?zCai+;1U4nXse%|gGy zFfdL?&k1)7P-tg`E1zd37-j-ds)&)Y+=;A$dR8eye>dz1?-3@s?(LB$2it3-JRhCK zWC{H+OOf|=dY(JO17V@J*vNS>51z$B(#XI&fxxvsGl3wi5*)nOH##nuHvQ-AqT~(C z{@tYLJ;rC?&uOdUg^*Oa!Dm1;tRUg{j!kb459+)dVuVdM#!%&pC`O>_Xm-@LWq%<@ zL$5tp(d=pSehzQ+!~e_h8UhRsd#t;%QD7H^VOI}YH+5}>?pTKwyt9<0@9Dd z==Cs*-v8Tdy}?qBJ(aR1y#hEzxOdB9b^)d1n(cVJ2jPW`bUvE{I4v`$!BSuh#Hwb3@hH_BB>Tw`^iUTAV%L+nUC0Ns==b?ik~=tfg9{>h1J zzC8@GYZS7*Wj7XLB7?amT(0vP9vjd(5>QjP%g*99u#^+l{W{*XJ{$D|&YTBYz{=gb zPI{x^igL26_6U-6RjR`QH-RWPm#tDHF0M{C#NQzZ&pDK zgHzUB(j7o|v((b~bf6=5J8nc9RukXft`Xh@GeMracHeeMlIk*dJ3S!nGI#GmqOv!M z48nk}5%s`eTpVm$m)FCr>ZWrvMW{kwRvsQZl5e4fetC>YlrwG6aazz82S>S+S8woe z^ck6MDwrZ~A~7UG;IMVcHq*@rcC`n8Vfos5CO!2O$grkvW%)JC4a-7&usxMr^kM!D^tPE0-JM%tI{LJZ<} z%-QGGvN}K}zT&s`wj5-_L?a2w40X(J zLy|0&M}YE0Wxn#_jye#z%Hc^bA7}!MbW{&_lQYWuECyC3;bk>xTt>lB=O=F|HrSdZ zCmFYZlG!Db7(7wg`d?p$4dU!kfanR-WuiuOqmxqR&H^D|Y4@S1I zUtiM=v87@$tLNdyfO)lZ7S&Ypm$iCLq?Y?)Tsq!0Aa6wCJ$M8C@E}WjwWcysD;=0A ztmdl!^OZAjsS<`Hey~!qN~Sd6tfr^h0xLCXt8W<1>JdlZ1y*Y;UtaEnY+aS~k!ksd z%f4WWtMA`M5KRBJxwIV}R>#n$$&xyc>mJHqfm zEHODsN_j^cesPRNDPtKwObqnPc;Zo8)~`RtYu}qk7=M=JU#=OX2qbTnnOT5lE8uAX zojUtC&2Z1&d<+Z(W^UuK*T#auqM9tWeQW;@t3-W0glquI|Ewh3iR;NLrWG{e~-D&xr8q zQBFpe3`_*9RM~g6j;)>OFG}Gng^y{TNLa8B2 z`BV+uY}Jrxv6WO4QC^BF6%s|DW}dHE&+aaqnnzSi+98)V{em2kDJb;IFNSHvQm?6YI}j*zc`}p?GBd!`%FLTT?K4n`(jY_=5gAD6eUSvZ8+7)ht%O3K3xQbj z+Qka&BAG-zFb7Wppr)coB|t?ySQwo~|L!MK$92jM7JkCO(Tg)|uU>H(k` zj$T!UohHM#3s9%wduj$|5diZaRd`(PJ4AS9IaA_UYidclOcIAIHBCRG4d4L8WS7*L zR3~{Jz%}x4n1Br@i)M}hnzvLs4vdKhj@)jmXcbKe)iL=TWulnfwp6?v3#Mb6*Q1!w zrydA7bzUo5;lB*?G8<-t zmwslD7r;s8<_IoS87Iem0w%KJ!hs9BVOFYg>TLk1Qe`TonJIcK3XVrM0GQ*NM!-1l zEQRLy!x1LhFgj=Oro%~?fNaZs51!rJG=Q+Bx`$1*FHNxuj+Pb1?z<=GR-r18>fWSd z#g3bp5(#n_zjf`2p#s=lo|m+y-%^1RR3=)HDOqxtUU;LY=bS1pw!J`Zi1NfJ@!*=+ zlNct+T7Xee!+Ic79%>w8%57%OfqN?s4U91TlkQP_?G7Ube}@Ci#ffo`D$O#^?PkMl zab#o#WnjIh$UA0&#){d`pZv{fw-O{pR!T)st+J>KLoslSlDe^Gnziz`nOAz- zHw4UYMFAF5ts&^*s$mwh*YV%Zo!C7GiF)l9?}{Z7WeF2tvBjFvFGcN`CAy02SaSxk zdJ>Kdy`!p>f-7@t{c5$tYyGq!Yz|F~Q0UW}Da|s4F+)`+UJQSzL&Vm#S@-b_DMLXy zpVKV`d3j)bfR_}Y{0V^;_OZ?2jc7r_8ZR4XZXJ|LsScT!gi)%vRg`wXOk#wFo*|vx zmLYn3PYAc1(i={dPccVFD!Zq!SdYV&Ay-%u6xmKYh>+PXCfXILN#})mO03N-q0ypp zi%Ct&7~t7}mLlCK-ip)>5CDvkAf?8@0WKXw5SMDDQr+keHcfd`)#NE4E}i&Oc8saC z({ds8lijH@GIa**AemIqByFg)Ia!JaHI;85DM9YkYNXb>5B*jylidiI0I%*dk0QSt z9SRfZ$1md)v2NU(9tBM#k%N)Cho>a3tA-!(%wt0VeHK#^)mmrfXXX{hol&hLUUM-=$3NVbNIuYsU67 z?ZjNC$(y>S;RcoYYZI?Nkbl zJ&x)PgX~7Jxwdsz$*Wc9mOzbdY}Y`)q(}TDHBIw6aGNwe4ZE`>^tO|qw~1uXJ*8fW z2KQ;S;3img)H05O_rYE9)g)-crnB~8mDE(-O}nJ?T`$+|E$U#qH$$g|qB4vc+bWLA zpr#)KD5&D5igS73M2V#35`0FPZZx6Po$_|rdj3%kUH%x7FcPR>UPmJdrp1`z9=yVf za@J*liyn2)q&*vJX>4k?0}u-G4kS!Vdy$x_*4yhdg(n{Z0r2>k7AVC^re3Q=glP}( zd(~fr_K93##U6Ymgv=XZ21!_c<>wa3-&e|!IQtN0 z2;-Cdt{>m=Gv)}Dct3%E3L@3DtryVh;zayE2nZwcv*q|qKVa#^`(%p!fQ7v=2k{Ky zr&ajf$#PAV_@p@}*HVcw?3Hx@+AhGMJ3d8tbSuB59N%%x5kNhJx#ppVLI`V1;5*J@ z=D`r6i0p}1jTJ8h49S$g4`SX3_J{bYmb{Rr{T`6=Gu-zG z-YLh}G0a^pA=o3wcmJI$CI!VXcIHoUhq@)4T#45>q#<)H_GijL6-hwR0jOixon82z zaCKokQUzxu*3A7*|Erpf>#YGsxyMnDHQQKsV|5wE=L~q?ZJojIUoCgv923H2lruPY zh1AC#;rUU!!q$`25S0Ko+sq>+o%~J;YP*}JTZky%-ux7(NTL05^_9S)qE3@;jniog z!L0I{nGIX&+mC2z)Hk+oZqi$}u4~#7E-k|=lq+(%ZWn*)RUec3H z_E%R{4h{}h3@)yS#dlV=w^p_`)|dAr`+AowtV|^1kC~%t8!=>%%{f8T(|WjhAshG`q2c& zwHyP~WdOCLwq1GE6V*TiK8akm^cUpY)sZAJH9PT2X;;j?t$T zL@M`@$^|dLmf5wXvXqmKTIU5jDpaPlE<-CdiA@yAPT<{CBoXLx4K~K%_m@;{y_CZ{ zs?^nc*3@R7bh;&3MM@u+QU_fIfi=dM2BWF7srkF+=0d1+Df2>EXFB9w4F7iFoQAu~dH?|8kyN3790*@UHSkp(psoe+3c@>-bEy1@dpNcn!;=2&e4)@U!AClEQ z){s+;xE{17D75O*h|~+SWPP9O(ufSN)4n&;TJ6mGF)R;E40NC;OvGwCZjC@~TsqGs z0Im^IkTX7YoK*C%H4_JLbd7^v!w4(Q7f!;PVeR_rBH1S{8Xiofkxe=ws7>Upq^%IM zZ7Hyg1@T%rZr0rz)*|Q1PPirvwk=Ppl1+ispcY+?Zw+@N@ZO_ySn$1Ys83doTLVr7 zC8&@{<{GaYRm|riNygnXyqB^fcPXGX@dy{STc4YOZMBo}ohQIe@u;LrGR&1m>p`H* zfiMd-Ia~YD2v=6!S(8n2e-_&m*~AUds4#@M6iJMVRK-GA6686^|ikk*FpSxXNiQD&DTV!?2Xyd3zy zy#`g{=UT-GYgje%8t5ZdOBi7V|L6DQInh;U-Q418T);bDm|IAyb$&d6cpvi=on_)V z4LBC*A65M=RZY3g;++=>6s}kGdeV)ZI#ZRSgOFKklEJtKJkpA`4$SywsAMVia;f8+ zb>?)=nU!}gA@8Va3Q_<_DenoYDldmG1VdS(%mOALU$**yI6{){ofF&{mIl7t=*5RLkerTd7D7m;-sem?EfR=+jF@Vn0 zc{*OI2oxBZQTb|lA_;&Jlt2^ANf_bQc1$+_p<0jNP8@MjB`(?GAa&|VmNwuV(yqTQ zXp@qb%7CoBbJED(v@+mPo(723|5hDpql|QM_vs)r>rh#upmz)*M56*URP?OudXsdF zznK-k&Xv`g(K>}%nT^Ke6xxllssY=gDse|se99e=N7MnK5t^o)kWO*u>}-Caf}-jk z7i!(kCPg`0qo&U4e9dIe5RE{u^6H!7kjIu8(u{jau?LfzVa*bU_x`{mkkEkWIq;(M z_6l{P;r=A{(t-4LC|Xol;Belh5?znQ*;xt)cz{;uHGrCMIz6`@7rubrRo*ue7`zUo z{CjE^=L+}DU8eQLc#ktgLGeAON@|$gFhiNnZA~QB<438l9OBu1iY(Hrleej@@d^)S zb~zY_gNe^h?~jcnp-3n5T-dyuu*lOF1SF<%Xx@2Tkx{GEku=NgR>`*pvaAgnPi};K zHe7qBn`3gLyymEe#4|I~xjpa+fdQ$-*>!>*+u>N`G?V+$;!>Kt%vVP-W5%@=LaU=> z#iati)fVKrXcdWc5UFc=K|4Dw0HAbjrSH|jghpPeHCmBnuOdjUI#;ye6etBCu^CaU zUb*pX0%zKSs-{$hlPMQfYPPgyt#O0fnMw^lq(&lY$9N9RE`l=ApR5Jj#V&IUX*#=# z2kYSdW~b$yu{exiHCQ+l@9e3!ekq|0;AqjC1r67N#9xQbn#Rh!-8wUq|Tursllz>vB0&uvG}L>XV0g*bYwvlGi@onf3TFCnSG;BJL& z@~6fq{A=oNa(NphW*+So-%3gmGSk*l?X?vVH#;uxJ~*Q-0$vx2%laTBrXWT;B(0}( z*lJ;((xH=iHfGJJ3m=s*;rUb{K7;@*5|~miC$ulk(v5jZQ|Z%A^_Z5t9L&!evOo>l z9SQeJ4bN*7Gv9++-CD3ARZ8mwjD6KycVngxqx!nJoPib)KDzz9*Pz^fNVa<)#p0bep;n@jx<#{6@fU2;qVrI3lCgv{N@n(Bc3` zrez3LC+a^~VFgb(zIsniB&#z@x#dK%AGaSUA5A)%+bsh?PcZ=Km*Dv#psFrD#UvO7 z?n>MSfg6ViY{wHBcK=0~)Urpg6vEDgSt_I|h2u|jb=&6)99l&AL*#f^MWr8N+T|Kce#p; zzwkxGuQTwqpHt_TJXd+Gs9Uf=AoaMJ3nKyB@qOCLByNQQ=7`f~rN!zXYH4**s-@L8 zNCb|>iS%y2tYosfdTW%IJqTYAY%N z2E{s1*Js?_E)9|N6Es1VUa+K{1y$-`+YBxjdG`aoNhx>t?j?ZlR#F;=Jp=_ASukq(S| zFp?kbn$=)Igp zWjn|&0VEqt2zJbeF{Co4mWZcyGR^@V;M7MtijIznGnq^$(~Dg7qF24@bf$Ohb!K|q zKc|}6dh6rnD9I$t*+wS$B=oyQJ z;KIc9aK>-0T#(m)7>x(^h6AgG{5!ZKX>q#^ysU=+qyhih!@!cbsqvF{k=XE%X||*| zW8LnkebCL|B|Ll|=P{G020zMQ-eenlvJy>e;NRL-(;kgC2I$R*h(PW$w~f8;v<+HY z$rD(nf<6`M_WJ?;YzFw<&XZve68#9kX=YYp4RH_)r=6K7VFXj;0x-ihS#0Soirt`c zqu+K$aBtv6ZpJxR!lW8Rd=zCvBq3=VHiF!(T%C9U2qG4AK@{rPly=#*lg79k+%Qf( zHh5LV>A!F-C%sfH2;UNn*Jq#L^EgZLvYVEC*)6Fx*ILaB{$2j zHRKhAlqQt-!WSq~i9elj5`PP>dwD*QKhNgl`BBuvtoWW;OL5RXXuW^rchGumv%8CA zd{P(d$9W#bm@A!eM!MTw7w+VUFJz(G5l7IdT7jaYc` zo#;D;vzB^;TsUUHtf3hizo+EG)V@Tk=PQv z)R3x)io6=~72!a#g`iLAsG!*xmm(=iw?_|B9L`3bLm@pz2SqoKrsyGk9&ei|PJcH< zowuO`8EnF-!Y19Bvv7_s+$3OtIZq2=`e-Q={>ccCARHdAE28A8o z7grJk+rb-=cR{Kds_Ib%Y)!n3&FMSPm&D^n+c*4%sXr7s_2~5d#2)`V9gYhU-m+Tt zasB|6#_qOM<2&EFyVrWwXFe5_L0?P2^c#5-vj2G(Jtp(@cTLPW=jaPBF+dvLs@X{- z|JUQ^JSbjw8@Z9%4;cy;pG0Aa&%T3^VH6;*CMJgM7$|RFD1h}-Mt0z7@Qpg{GP-Z` z!P*Tf<5JT@Emhv1%j>Qdbz8IIDNJn&X(B;#H`s7eYZ;Ktdrnn*1W>RdF&LO3&IqFQ zK)o4&(%^#qf^{te7WI4zp=x}AbdfF|-i`<3RR>1g3p7URhI2WU2I+>$BU_@cI?K8; zA{7yKeq=iLiG^sQ##-Q_j}>PAd2Z&)xkwS9h#-@$gjAku!mXA6(%KB+ z9`VTHc=YG^L-&wd22qQYa=0C5UL}YoNCM`Xe6bfmz@sDD@efuv5d>xzGmPM z3IPc$H^72e+y)Tn&5;Vves^9ewKJCM4BoJ@dj%B6kJb37Fm{BhS{QZQO2ktNqJrr6 zIt>@F$5ul$#HYbZV&r+UVp2HhED8CqmtBG@H5=MJ5~2lxM%^QET;)*l7spqyx{oGP9MHx${Qr`2=EpX(Lz;}h~QfyXa0C@j}0>oukYa<*6ubzs@DuM zEq7M~Oq0~}u=F6ra+Oq?qe7s9EbUYuI(L8y3#xDdCY&ZQLmdVb_qB{tii0F}Z2Bn@ zsK=nI>tA(u1Wp8#wnOzYNV-oT(m?7HnOBk%DZO{mKxnfIb*d*0r~Fp_-6Cm#vRse^ z44VL8aF49Cj^Cwd!d!TYzO22VauZ}l{M%x7syesC z7ewOkm!dGX;rPLZfmV`w_O#R65wre48d9M6#M4CmY5TV!nh}eGJY~yN3rR9b&{ZqR zpVobUT8YF9*i9Qw-!7}sCc;LQ#Q~mt#G^`;5&^4i_k>k)mfMks)3Y?wixq@`SQC$u**cL%4YYmXk>(XDZi{R*Zk?N zBEK&Z2csJzA6h=}Hdsq~hi~~O`EtD4ptbz=`8~}&k!sud^=9F;^V*J|Y5Ka9eEn49 zrdc;_VCO8JUpGVrEBO5NE##h7`_a|sVcZ3+qF2E8_^haHu6ZDixLKH@!;7kqUvO}c z&QK#%^)6)+%$=fS!+M+NT_EW(8k`E_0Olp&>uTD zLeIYX*C!-RsnUqR-@&2J$d>cln1;;GJeA+iDGY<6(dBd+b8y=khsGqk5xaThJzwh$(4SDam#UPubcY?T?DanZA@tsdG~ zB{CfjlRMWJa03Sm9Q6BtNn{(x8EKQ-+3kJ}xikyXqz1hE!3SM-WDSxNJ`w82IPI!W z`G_Pw1($Md_^hBPJ&PFZSDX60;hJVp)IzJ}hsyYezJQlWik8<_;OA?|y1NxsK0oxu z+Pc;_&wj2o4ddBSaxg#p_Y(Q_f_v}-P=qe6Hl|OnnL9;{ohm0V+(n;Ul&qL_kSPH& z5jk+_3tCbHY0DG|wMr8tL-cS}S45D(MS&HOw+LeW02p~i$qMx!gbKQU`O7_g_rj+w z0fCrToVbTap(!*-bi|&c#|0L+>Qxu|06=Wzp*-&T**g@aSL-=fDWJfSJ_+(Rd4w3m6!QZ`fi; zb~blG`OcI;mCS{gHfVabv!{z}oJgp~Ei8HN92=P8GY_H1C+#KrQ-`aR0TYcY-0;~! zwtdDRQb{9kRYMkK0`KTfEzi>& zzEU1XO~wi}r-4_KEXS;JQF%C;3gePAE(r;)9`MP(9(IPK2JgT9Xc-Wb)M=&)=O=MU zBhStnm6JVuL}k)%V+w*hV=bHSa4wPHqeBRS`pYp6!3K=D-nc9H8UMmm{*|Z=F}zhG z%qa2psB}3=cf`Dtkg;Hx^ZPl7^bYQ2#IOY&hMP4&g1R(=DHH_JnMTf}`hL)}12BiZ zo;?OgOIc}=rfEuy47Uy-9@FX)W+)p6&iy^Zk(+)6FfpJJP=QCqId#)_x3z2I7<*>M zRox3s)=RF)ND%(LenksrMHftw+|V&rn+*zn#Lg#0#TRZpV%KpBu)!2;c88e)?9Bxu zrZTmQ5u21?D2D69sB%qSeXK6c3DMfm&5uO@N5K2LqD@~lGm0s3R67Nin-FVYqQ(W1 zS*3B!V9z1dZ6`>C6)}D1rbm>(n*Dy)n@49A>3K##H|C?imfZ*&A>_7ro#mIRiRS zjKdGM1zx4}BhKNXoI@H&a0fS6EST=e@9~@32zWq)J$rNWd=_HX@OgLhNk?rKM)7EU zP)8oU6GS8ODIQmldEnOT4Y#&iUv~%HhuvOxPdp{1nXicTEXnJ^%%_2Vp<5&olVQ$yu7EB2K6td+cCU7B4z;vY2zR(aU(=l<5?i^&A_zl-?krX`ssnwqB6Cl|}3v90!~8Ke*}{;2W3Bt!^@ zo;q-e5TQs!{RtJAPU&8o&B>)vBY9M5;4K(gEY#R|Nr;jT&#Q`Bj=xk4kBefU_qDay zHNN8nvJwE-G63)`S8UigWOe)Uxv+LzD*v6(h1E4E(WE1m9e3a4P_Yt{-?v+SxI>j> zoL#e2k_H0ewYk?o{J%2so~I>;k(t|(vur~5R#eNIzFoUS7UaTg(OaIA`CxR=nr%&! zE)^%$Y=e)YX^+^nC=J&%=jrU0HPbq9$tjs_*f`UE1ga9+*&Olf4QxY%GGEW7G{+po zP?D``X|hR(bR*F3UB}#GLt7l+rlt%ls#X=|UXmJNar~GTVQD&k>#S1|9X+-oI}&nH z(+t1=o`pHJP{rb$^tbxI5a>!bO5UM-;vJD&!sGO|P7)q}XvgmFc91=f0zfc$j=1u% z1GY-Q?X$dEX_{|aZLKulDPi$(lS<=(;Z+}kRH}ZJ(kv&0Ytxd-7v-#e{+v-Yj#6zC zcCyYM>7V+ZNVZkRP#KZ=04c{fw%!TBUL&sVZOLs6y+x>e0ZkA|Pz&zyATO*BSviD- z#9?P?vD-%z_@6~=(0EKHUkPlm#EGjxI6=jH)y#fgq>55XoDryWFXO{i;*@2$UNN}p zi7q3cy6R)}0?}d{nU3_7YrYq+ZSKJi4^RB(=0agZp&Z7I zy(lgd_KFB&uynL8bhy&eds%GB?hGd3CA_G-6my}7O(^M%2Nau;0-!%g@9ly|D>)wZ zhPw+aom=y@k@)fyW3|6_s{Y&-A3&df((6Bjb`Tw3_U!(Q|M`JOkWIeV-~M>FukuC? zSk{I~fmM|$&WoFTAZ;qR;H>-=uJfH<`x`NZ|1%nfIOZX)B-c^K+4WH$=)f-+*<8B_ zbj_+=!41bqE4FS%}Rv2|l(TkU= zGBjDoJ^YKJUMM6GOfM&~2C<0V^!}6G_Erle!3HkyzJAj6WvmMr?^`u&wg9ZklBfJK zd(6_4C`;GfB9GAjI&lF|(<6%fSrOJ&1hJ{izbhf1v5HTFtRklN{9$-0-TC}71c}lh zp#};DIWQj>77?I9DclsZVgxHtaCUtL3}XeIi%hf|cM+5^>@jWkE21&5nQh~UypWfB z{byv%JDoma+E8h`-})N1A_Re>2$iO)(7V-x1{;T&ioy2~68MK|jMDzeEZY!Q4kYI2 zgVRWBDFYI z{=?_*-X{hgg_rt1E+tAYKkdCjs+w!&3hj0<&G_+0Im&xm3sW&NM@W(%HgO+m2ZgVT zSqOm9F~tbX5D1EU^Yb5stBTVf&yLyjTT}5B@-S{PcK+5`1)nrcprlx)IGTTezhj6u zf2WizcDlR)SoknDoi|mz!7#Y(h>Mf)<{HJ52Nq6Fp)5+_!^uzHloo*HU0S!Bsx0d% zhd-@jsO7?lX@jsl=Wj=u8s&6&*Nn~(gQ;UPB#+L&z?fHgnWR8`fmF~hB8QWIx2!Xx zRH`E~93?Q*_q{NbF4hdqULB(0TP;Y=jNmznfV^JrJ zL1F2UIIHFOZSW<;84SJxr$SqLjgrnTz`NuGu%46O`U{x2gX;a|Qy*z~%wx{UY!SzJ z-6>a+vAndJa6ZIQn4B1opS&ks49de>qnf$;BbW(oT+7of%K61=FvAQ(ak3eg_2(ST z`C~Z)90oB{I!|r}oFi^lnKlZPGpDdXWLH}i;1Yp(Ul*YJj4j7nxc!JQMjyU zv0Ria7D);ai#nO?=-iboPOgF&s`C#5k~~0)7#1e4R6kWxf{5nx1TeD%IYr?%`Qu{T zr9Laxg{aIMi4_+0&+K`oj5R!}*f`6Sn{?8+P`1z7lpY;rG#jr@PJV-9kn6cNihI-3 zq6u80!OXh0-gL_bHa5A|M+TC}ytzR$i0P+P3-R8+qeB={9>Ih}Ho~GCZ!J3R!zkM} zKya-qz?uPY6=5bcqVtsiM5tTT*ckbFMM`+7v>1nFg=e|w!m?WFyu5(iwpduwN8(06 zPP=IY7jgraEWs04kW<)VTsRDccGp{q;aJ^8Z92G3VOn5pAz<$;bl8}-pu=F2E z2L&jyN%}N+E&J&c!0lLF4HBaC(Qxj1$AFSh6iUr~QmlL#ZFgX$GWJ}DnU-%Tu;*gk zL`0Gra-|daDG-_ZR=G5jx_li`hnj=-eOVr0G_cL^z^{L9&bi zoB3e%v>`crBtQtk7JJyEVeQj?_mP?{3%5Ok64vyP|7>F3k3Y21`lNe<(7d2&&~?dp z4#QRt@G4IwL#I|&ueAPZ#NZhWt*yB_#+s{Wbrxh#U{><#_K&e9)uCrR6;dX`UUhsd zwwqqLuURgwWnXp%%n|+IpxwcOgz8Jk9PyQ|U}xz_bKXtS@{0S5>t0_%Nw&x-eV=wf zWIZ*XIN47uxyNA>v;t6srcMiMB>qLC$#qCv%>AHrps4CtlYeHX5$=l)&F0K%KSr>e zFT2tB{BA?;(Xyy)Ip&@c)-sf=t%-|B({;}R!cdj+Me{w#6M@{(+UWNsbhmh-=c6|m zcy5~U>vNG~Bd;x`x=d8|q`1^6AFdxuo7AboH6AsI6G8VQuJW{>jwWMT%T*0aCp`9f z=b>B;il4xK-;5oXYoxgn%7(i!d6^QU3nKQIFi*nmq$7wz+ghUjn3-p8qk#kVC3?fg z#3U~B4z6hkk0F&oI{olZVE&RZ@J-=?i8aws&%k6Ns9c2G9k%~Bt^OX z1S9k-&IqmTad2lSJB-9ABtZclu_hM|?N!GzNs@^es_UfH+v1q#dC4@9qG(z=O_Q0m zWUE?G1X1VYI(#UOKcYi7dwmUwnXQdka7uB+8vMAakCf2!hUz2f`Z7zbcr4sLXs4wx z9!ziZceSLoOXaov`5G+eD>JIS$evbO8$9N@FT44{tOi=vU8hzOQir^uNKyS`hMB}Q zl@%O1Y{V!KSrV)&@=k9E^FZN_%CWKtQFc|T^XJWc)7=9-e>(>sXcMM7$p7P1S62`P z_d-jn*8O9!v8haYQ}y$$Z4smClD#3$%WDVN5c;W9C3`GQoYU6SJ7|+TbZv>*g7a5s zXUq1vDWkHc)ol3tUBw8w|(Y%548|wEs5g^Mzq}Bz&*H&g51~It*2-q^S*V* zb-z9TtA|}U)W!MAR=G)NpbIEBmD^sL59pA}m5VtRzdDNm`E3Qq@p!XKi>Va9vHE7V9V1;z%E%$< z5YgftlvJ$X7|mi7)?&wT*v^fyw&RLNo@;&8>Fm%Z3+2l^%1U%|JN(E9{A&q8W(0X3K#;gFIN|HAxo0B?K`0Nb_HL0uUeRCnCvlkK_SQI?id zXEyZ`%6CNc6s0Y{GeT(iw7CZFPb!rF_Z%Djz?#$iImlk^NXHdy5iOr!l zCGboW6vnO8GOz5()9a?<|Oi>gLUfk7ea0?2Dm7wtK#N zbIl_mu(q1gn@AXsXx@LU_Yvn}?=R_o5>ttXokt9MpxXm|EAdKECA&A=1pR;~KdQ%k zeg@UAP=%ZB5s2gi37>&k3?K5LgB(3(6Gv7dj;239a|fP((A#qu2(7}yBh(6ZBdN7h zCIe3?o8sb`{6e{u!a|O*S}05`5jC?9I%rHVL6Ee^;%!ups@$$C@Zn6AO5>K@s8i`)SD}tXgDeXE)!eb!6PvU z9G9;VaUfr#17`gFQ+&V0n+xAh%lGkj2j5(&d^2-^5xFbur|D;#xYnwE_I%_>drq8a zVVOy^vxpsS2R~L%S^P!n@;T^yY4I1Sv+kgC)x}>drK@aIR~at`A93 zt^#6274OB!Cv`~&)=-BGfrV9I{oh5*+B0wfyBu|_25gC+Z1HI`Q+(}N6D95 zCU(0ex!4|r?9#b}Z|5<@RUwuW7VBF8ieYOsh==H$leP>h)$h=u$TOpzJ-d!HRt6u5 zw`l$?>czG(1`jh-l9B{CMQu}^U(+NU&NaJOsWO(vX=`&Y=7ohUlL(XpXGse1r-rMC zr@nOCcjurBjeTfcU)t8$H&@OgR(&-K&7FcJgp3to5I7XR3>5|`2r6r21c*O&y$XLA zKM0WQv>~pDAcGL|ue%gs?%sE|k%dNUs*x>&;rSV-I3wDdW{1rAuCv5|5I-~p-y$wu z%zZVSW)HN`>Q{w8`l)#C8_{cA)YiUuU9KNs=hyJS$*Zc(`61~Dki~9GgkS7Lm1i@R zJ2wNqqp%Toj|$?3U0kFZKkU$?@=O~J=hr7s*F6zsDblD=Pcd4>9K|r!ud?uru;xo{ zr&yEWuy96gdP%0XRc#^1E2;lDu(r9=68gpfG!55P&9@p!F|&pu z={-;Lj;RE*4h`Z_$Lx!&enb*YQjUx$L0)gxOzu%t=YfpoGt5p$-(PjQ(RxA zuBNha4tl0esn?PeIq~p$(lJfnrPayE0zHP8ZpuYa3p-?*xt^E{&&H`)I9$N|Sx_Hd zv_xL>z>+!WgHPu0@J_je-`Wr@+PQ*v!YBum+y z37XZMw2s+jh-b&?u+}|eKmradevFJDMmr83?RF)N4MgCHaIwq^Bbth4Mre(P*fBv! z(nz2A^~CY!0(~-*%}EdgIX#ri=t5YC&D!Q=hLwvrVPJn}N9l8B;4KtJrz8`*B*>S< z3Ga~5;zml6bjXTmEyKLbqT?+M9kBoc3mcG-m>1noA^K{mQYnup*ZYA_2;`Nn;8J#@mMOe0skqbt%{h=nnl)&ip_6O8HIKQb;c;1~hD9!N%Q3SCy6IJubz4j@ufEDn z7p<}zDN;&X8`k@t>&P{%^v1rbNF8y}ENiZSRKvvksbkVG&Htm?9u2z;EoSO`P!#}E zpvOb+lP;1)VrUShG45j;yA(*nUf%FB%8#H((0CE6q}BIj(ob;(#J{&P9GY!zNkYWlAWo)VNA#2vs zoxA{t0uiC2$5?A!jiPf^l{IrarDFB=sxE&++h96Z8$NCZj6Lkap@SaTzB1%FIBZ0kMNS0WH*Hvv&{mUm z1}NEz%HMDWzp3p$7#`B{5>#GcIrY*ef3-9D#GD29C+LM640;Ja>avhz(P` z;U#L%9#!&qT;uc~vuDJhU?RnFm}GE19mi_6}^fG|yPz-7aZQmkJi2+ex18A)l5}}I7-U-^%uJS^h>(;#< zq;0?uDy3AUS#K(1k9s*jcj!R;CrZ$t$SdOCV?%Et($=J6j==wutd1y_<021giw%XH oX5NltaOKQ|8u$#424Ue3kRy)HKli7%j{Nz=^AmqMH}k^(0uzw0i2wiq literal 0 HcmV?d00001 diff --git a/src/lang/qbittorrent_uk.ts b/src/lang/qbittorrent_uk.ts new file mode 100644 index 000000000..4337e063e --- /dev/null +++ b/src/lang/qbittorrent_uk.ts @@ -0,0 +1,5659 @@ + + + + + AboutDlg + + About qBittorrent + Про qBittorrent + + + About + Про програму + + + Author + Автор + + + Name: + Ім'я: + + + Country: + Країна: + + + E-mail: + E-mail: + + + Christophe Dumez + Крістоф Думез + + + France + Франція + + + Translation + Переклад + + + License + Ліцензія + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + chris@qbittorrent.org + chris@qbittorrent.org + + + Thanks to + Подяки + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">Bittorrent-клієнт, написаний на C++, на базі Qt4 </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">та libtorrent-rasterbar. <br /><br />Захищено авторським правом ©2006-2009 Крістоф Думез<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Домашня сторінка:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Форум:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent на Freenode</span></p></body></html> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + + AdvancedSettings + + Property + Властивість + + + Value + Значення + + + Disk write cache size + Розмір дискового кешу + + + MiB + МіБ + + + Outgoing ports (Min) [0: Disabled] + Вихідні порти (мін.) [0: Вимкнено] + + + Outgoing ports (Max) [0: Disabled] + Вихідні порти (макс.) [0: Вимкнено] + + + Ignore transfer limits on local network + Ігнорувати ліміти швидкості для локальної мережі + + + Include TCP/IP overhead in transfer limits + Включати заголовки протоколу в ліміти швидкості + + + Recheck torrents on completion + Перепровіряти торренти після завантаження + + + Transfer list refresh interval + Інтервал оновлення списку завантажень + + + ms + milliseconds + мс + + + Resolve peer countries (GeoIP) + Дізнаватись країну сервера (GeoIP) + + + Resolve peer host names + Дізнаватись адресу сервера + + + Maximum number of half-open connections [0: Disabled] + Максимальна кількість напіввідкритих з'єднань [0: Вимкнено] + + + Strict super seeding + Строге супер-сідування + + + Network Interface (requires restart) + Мережевий Інтерфейс (потребує перезапуску) + + + Any interface + i.e. Any network interface + Будь-який інтерфейс + + + Display program notification baloons + Відображати сповіщення програми + + + Display program notification balloons + Відображати сповіщення програми + + + Enable embedded tracker + Увімкнути вбудований трекер + + + Embedded tracker port + Порт вбудованого трекера + + + Check for software updates + Перевірити оновлення програмного забезпечення + + + Use system icon theme + Використовувати системну тему іконок + + + Confirm torrent deletion + Підтвердити видалення торрента + + + IP Address to report to trackers (requires restart) + IP адреса, що повідомляється трекерам (потребує перезапуску) + + + Display program on-screen notifications + Відображати сповіщення програми на екрані + + + Setting + + + + Value + Value set for this setting + Значення + + + Exchange trackers with other peers + + + + + AutomatedRssDownloader + + Automated RSS Downloader + Автоматичний завантажувач RSS + + + Enable the automated RSS downloader + Увімкнути автоматичний завантажувач RSS + + + Download rules + Правила завантаження + + + Rule definition + Означення правила + + + Must contain: + Повинно містити: + + + Must not contain: + Не може містити: + + + ... + ... + + + Assign label: + Призначити мітку: + + + Apply rule to feeds: + Застосувати правило до подач: + + + Matching RSS articles + Підходящі RSS-статті + + + Save to a different directory + Зберегти в іншу папку + + + Save to: + Зберегти у: + + + Import... + Імпорт... + + + Export... + Експорт... + + + New rule name + Нова назва правила + + + Please type the name of the new download rule. + Будь ласка, введіть назву нового правила завантаження. + + + Rule name conflict + Конфлікт назв правил + + + A rule with this name already exists, please choose another name. + Правило з цією назвою вже існує, будь ласка, оберіть іншу назву. + + + Are you sure you want to remove the download rule named %1? + Ви випевнені, що хочете видалити правило "%1"? + + + Are you sure you want to remove the selected download rules? + Ви дійсно хочете видалити вибрані правила завантаження? + + + Rule deletion confirmation + Підтвердження видалення правила + + + Destination directory + Папка призначення + + + Invalid action + Неправильна дія + + + The list is empty, there is nothing to export. + Список пустий, нічого експортувати. + + + Where would you like to save the list? + Де б ви хотіли зберегти список? + + + Rules list (*.rssrules) + Список правил (*.rssrules) + + + I/O Error + Помилка вводу/виводу + + + Failed to create the destination file + Не вдалося створити папку призначення + + + Please point to the RSS download rules file + Будь ласка, вкажіть файл правил завантаження RSS + + + Rules list (*.rssrules *.filters) + Список правил (*.rssrules *.filters) + + + Import Error + Помилка імпорту + + + Failed to import the selected rules file + Не вдалось імпортувати вибраний файл правил + + + Add new rule... + Додати нове правило... + + + Delete rule + Видалити правило + + + Rename rule... + Перейменувати правило... + + + Delete selected rules + Видалити позначені правила + + + Rule renaming + Перейменування правила + + + Please type the new rule name + Будь ласка, введіть нову назву правила + + + Use regular expressions + + + + Regex mode: use Perl-like regular expressions + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 досяг максимального коефіцієнта, налаштованого вами. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent використовує порт: %1 + + + UPnP support [ON] + Підтримка UNnP [Увімкнено] + + + UPnP support [OFF] + Підтримка UPnP [Вимкнено] + + + NAT-PMP support [ON] + Підтримка NAT-PMP [Увімкнено] + + + NAT-PMP support [OFF] + Підтримка NAT-PMP [Вимкнено] + + + DHT support [ON], port: UDP/%1 + Підтримка DHT [Увімкнено], порт: UDP/%1 + + + DHT support [OFF] + Підтримка DHT [Вимкнено] + + + PeX support [ON] + Підтримка PeX [Увімкнено] + + + Local Peer Discovery [ON] + Пошук Локальних Пірів [Увімкнено] + + + Local Peer Discovery support [OFF] + Пошук Локальних Пірів [Вимкнено] + + + Encryption support [ON] + Підтримка шифрування [Увімкнено] + + + Encryption support [FORCED] + Підтримка шифрування [Примусова] + + + Encryption support [OFF] + Підтримка шифрування [Вимкнено] + + + Web User Interface Error - Unable to bind Web UI to port %1 + Помилка Веб-інтерфейсу - Не можу приєднати Веб-інтерфейс до порту %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' було видалено із списку завантажень і жорсткого диску. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' було видалено із списку завантажень. + + + '%1' is not a valid magnet URI. + '%1' не є правильним магнітним посиланням. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' вже є у списку завантажень. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' відновлено. (швидке відновлення) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' додано до списку завантажень. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Не вдалося розкодувати торрент-файл: '%1' + + + This file is either corrupted or this isn't a torrent. + Цей файл або пошкоджений, або не є торрент-файлом. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>було заблоковано згідно з вашим IP-фільтром</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>було заблоковано через пошкоджені частини</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Рекурсивне завантаження файлу %1 в торренті %2 + + + Unable to decode %1 torrent file. + Не можу розкодувати %1 торрент-файл. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Не можу приєднати порт, повідомлення: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Успішне приєднання порта, повідомлення: %1 + + + Fast resume data was rejected for torrent %1, checking again... + Було відмовлено у швидкому відновленні данних для torrent'у %1, перевіряю знову... + + + Url seed lookup failed for url: %1, message: %2 + Пошук url роздачі невдалий для url: %1, повідомлення: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Завантажую '%1', зачекайте... + + + Using a disk cache size of %1 MiB + Використовую дисковий кеш розміром %1 MiB + + + PeX support [OFF] + Підтримка PeX [Вимкнено] + + + Restart is required to toggle PeX support + Щоб перемкнути підтримку PeX, потрібно перезавантажити програму + + + The Web UI is listening on port %1 + Веб-інтерфейс приєднано до порту %1 + + + HTTP user agent is %1 + Браузер користувача: %1 + + + Reason: %1 + Причина: %1 + + + Note: new trackers were added to the existing torrent. + Нові трекери було додано до існуючого торрента. + + + Note: new URL seeds were added to the existing torrent. + Нові URL-сіди було додано до існуючого торрента. + + + An I/O error occured, '%1' paused. + Сталася помилка вводу/виводу, '%1' зупинено. + + + Removing torrent %1... + Видаляю торрент %1... + + + Pausing torrent %1... + Зупиняю торрент %1... + + + Error: The torrent %1 does not contain any file. + Помилка: Торрент %1 не містить жодного файла. + + + File sizes mismatch for torrent %1, pausing it. + Розміри файлів не збігаються для торрента %1, зупиняю його. + + + Torrent name: %1 + Назва торрента: %1 + + + Torrent size: %1 + Розмір торрента: %1 + + + Save path: %1 + Шлях збереження: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Торрент було завантажено за %1. + + + Thank you for using qBittorrent. + Дякуємо, що ви користуєтесь qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] Завантаження "%1" завершено + + + + ConsoleDlg + + General + Загальні + + + Blocked IPs + Заблоковані IP + + + qBittorrent log viewer + Журнал подій qBittorrent + + + + CookiesDlg + + Cookies management + Керування Cookies + + + Key + As in Key/Value pair + Ключ + + + Value + As in Key/Value pair + Значення + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Звичайні ключі для cookies: '%1', '%2'. +Цю інформацію можна отримати з налаштувань веб-браузера. + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + + + + Dynamic DNS error: hostname supplied does not exist under specified account. + + + + Dynamic DNS error: Invalid username/password. + + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + + + + Dynamic DNS error: Your username was blocked due to abuse. + + + + Dynamic DNS error: supplied domain name is invalid. + + + + Dynamic DNS error: supplied username is too short. + + + + Dynamic DNS error: supplied password is too short. + + + + + DownloadThread + + I/O Error + Помилка вводу/виводу + + + The remote host name was not found (invalid hostname) + Віддалений сервер не знайдено (неправильна адреса) + + + The operation was canceled + Операцію скасовано + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Віддалений сервер закрив з'єднання зарано, перед тим, як було отримано і оброблено відповідь + + + The connection to the remote server timed out + Вичерпано час на з'єднання з віддаленим сервером + + + SSL/TLS handshake failed + Помилка SSL/TLS + + + The remote server refused the connection + Віддалений сервер відмовив у з'єднанні + + + The connection to the proxy server was refused + Відмовлено у з'єднанні з проксі-сервером + + + The proxy server closed the connection prematurely + Проксі-сервер закрив з'єднання + + + The proxy host name was not found + Не знайдено проксі-сервер + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Вичерпано час на з'єднання з проксі + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Проксі потребує автентифікації, але не прийняв автентифікаційних даних + + + The access to the remote content was denied (401) + Відмовлено у доступі до віддалених даних (401) + + + The operation requested on the remote content is not permitted + Операція щодо віддаленого контенту не дозволена + + + The remote content was not found at the server (404) + Віддалені дані не знайдено на сервері (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Віддалений сервер потребує автентифікації, але не прийняв автентифікаційних даних + + + The Network Access API cannot honor the request because the protocol is not known + Невідомий протокол + + + The requested operation is invalid for this protocol + Операція неправильна для цього протоколу + + + An unknown network-related error was detected + Невідома помилка, пов'язана з мережею + + + An unknown proxy-related error was detected + Невідома помилка, пов'язана з проксі + + + An unknown error related to the remote content was detected + Невідома помилка, пов'язана з віддаленим контентом + + + A breakdown in protocol was detected + Поломка в протоколі + + + Unknown error + Невідома помилка + + + + EventManager + + %1/s + e.g. 120 KiB/s + %1/с + + + Working + Працюю + + + Updating... + Оновлюю... + + + Not working + Не працюю + + + Not contacted yet + Ще не було зв'язку з трекером + + + this session + Поточна сесія + + + /s + /second (i.e. per second) + + + + Seeded for %1 + e.g. Seeded for 3m10s + Роздавав %1 + + + %1 max + e.g. 10 max + максимально %1 + + + + ExecutionLog + + Form + Форма + + + General + Загальні + + + Blocked IPs + Заблоковані IP + + + + FeedDownloader + + RSS Feed downloader + Завантажувач подач RSS + + + RSS feed: + RSS-подача: + + + Feed name + Назва подачі + + + Automatically download torrents from this feed + Автоматично завантажувати торренти з цієї подачі + + + Download filters + Фільтри завантажень + + + Filters: + Фільтри: + + + Filter settings + Налаштування фільтрів + + + Matches: + Результати: + + + Does not match: + Не підходить: + + + Destination folder: + Папка призначення: + + + ... + ... + + + Filter testing + Тестування фільтру + + + Torrent title: + Заголовок торренту: + + + Result: + Результат: + + + Test + Тест + + + Import... + Імпорт... + + + Export... + Експорт... + + + Rename filter + Перейменувати фільтр + + + Remove filter + Видалити фільтр + + + Add filter + Додати фільтр + + + + FeedDownloaderDlg + + New filter + Новий фільтр + + + Please choose a name for this filter + Будь ласка, виберіть назву для цього фільтру + + + Filter name: + Назва фільтру: + + + Invalid filter name + Неправильна назва фільтру + + + The filter name cannot be left empty. + Назва фільтру не може бути порожньою. + + + This filter name is already in use. + Ця назва вже використана. + + + Filter testing error + Помилка тестування фільтру + + + Please specify a test torrent name. + Будь ласка, вкажіть ім'я торренту. + + + matches + результати + + + does not match + не підходить + + + Select file to import + Виберіть файл для імпорту + + + Filters Files + Файли фільтрів + + + Import successful + Успішно імпортовано + + + Filters import was successful. + Імпорт фільтрів успішний. + + + Import failure + Невдалий імпорт + + + Filters could not be imported due to an I/O error. + Фільтри не були імпортовані через помилку вводу/виводу. + + + Select destination file + Виберіть цільовий файл + + + Export successful + Успішно експортовано + + + Filters export was successful. + Експорт фільтрів успішний. + + + Export failure + Невдалий експорт + + + Filters could not be exported due to an I/O error. + Фільтри не були експортовані через помилку вводу/виводу. + + + Choose save path + Виберіть шлях збереження + + + + FeedList + + Unread + Непрочитані + + + + FeedListWidget + + RSS feeds + RSS-подачі + + + Unread + Непрочитані + + + + GUI + + Open Torrent Files + Відкрити Torrent-файли + + + Torrent Files + Torrent-файли + + + qBittorrent + qBittorrent + + + Transfers + Завантаження + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Швидкість прийому: %1 КіБ/с + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Швидкість віддачі: %1 КіБ/с + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Завантаження '%1' закінчилось. + + + I/O Error + i.e: Input/Output Error + Помилка вводу/виводу + + + Search + Пошук + + + RSS + RSS + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Сталася помилка вводу/виводу для торрента %1. Причина: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + Помилка завантаження url + + + Couldn't download file at url: %1, reason: %2. + Не вдалося завантажити файл з URL: %1, причина: %2. + + + Options were saved successfully. + Налаштування були успішно збережені. + + + Download completion + Завантажено + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Не всі завантаження завершені. Ви впевнені, що хочете вийти? + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + Глобальний ліміт вивантаження + + + Global Download Speed Limit + Глобальний ліміт завантаження + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Зав.: %2/с, Вив.: %3/с) + + + Recursive download confirmation + Підтвердження рекурсивного завантаження + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Торрент %1 містить інші торренти. Завантажувати і їх? + + + Torrent file association + Відкривання torrent-файлів + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent не є програмою за замовчуванням для відкривання торрентів та Магнітних посилань. +Встановити qBittorrent як програму для відкривання torrent-файлів та Магнітних посилань? + + + Transfers (%1) + Завантаження (%1) + + + Yes + Так + + + No + Ні + + + Never + Ніколи + + + Always + Завжди + + + Exiting qBittorrent + Вихід із qBittorrent + + + Set the password... + Встановити пароль... + + + Password update + Оновити пароль + + + The UI lock password has been successfully updated + Пароль блокування інтерфейсу був успішно оновлений + + + UI lock password + + + + + Please type the UI lock password: + Будь ласка, введіть пароль блокування інтерфейсу: + + + Invalid password + Неправильний пароль + + + The password is invalid + Пароль неправильний + + + A newer version is available + Доступна новіше версія + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Нова версія qBittorrent доступна на SourceForge. +Чи хочете ви оновити qBittorrent до версії %1? + + + Impossible to update qBittorrent + Неможливо оновити qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent не вдалося оновити. Причина: %1 + + + + GeoIP + + Australia + Австралія + + + Argentina + Аргентина + + + Austria + Австрія + + + United Arab Emirates + Об'єднані Арабські Емірати + + + Brazil + Бразилія + + + Bulgaria + Болгарія + + + Belarus + Білорусь + + + Belgium + Бельгія + + + Bosnia + Боснія + + + Canada + Канада + + + Czech Republic + Чехія + + + China + Китай + + + Costa Rica + Коста Ріка + + + Switzerland + Швейцарія + + + Germany + Німеччина + + + Denmark + Данія + + + Algeria + Алжир + + + Spain + Іспанія + + + Egypt + Єгипет + + + Finland + Фінляндія + + + France + Франція + + + Greece + Греція + + + Georgia + Грузія + + + Hungary + Угорщина + + + Croatia + Хорватія + + + Italy + Італія + + + India + Індія + + + Israel + Ізраїль + + + Ireland + Ірландія + + + Iceland + Ісландія + + + Indonesia + Індонезія + + + Japan + Японія + + + South Korea + Південна Корея + + + Luxembourg + Люксембург + + + Malaysia + Малайзія + + + Mexico + Мексика + + + Serbia + Сербія + + + Morocco + Марокко + + + Netherlands + Нідерланди + + + Norway + Норвегія + + + New Zealand + Нова Зеландія + + + Portugal + Португалія + + + Poland + Польща + + + Pakistan + Пакистан + + + Philippines + Філіппіни + + + Russia + Росія + + + Romania + Румунія + + + France (Reunion Island) + Франція (острів Реюньйон) + + + Sweden + Швеція + + + Slovakia + Словаччина + + + Singapore + Сінгапур + + + Slovenia + Словенія + + + Taiwan + Тайвань + + + Turkey + Туреччина + + + Thailand + Таїланд + + + USA + США + + + Ukraine + Україна + + + South Africa + Південна Африка + + + Saudi Arabia + Саудівська Аравія + + + + HeadlessLoader + + Information + Інформація + + + To control qBittorrent, access the Web UI at http://localhost:%1 + Щоб керувати qBittorrent'ом, перейдіть за адресою http://localhost:%1 + + + The Web UI administrator user name is: %1 + Ім'я користувача-адміністратора в Веб-інтерфейсі: %1 + + + The Web UI administrator password is still the default one: %1 + Пароль адміністратора в Веб-інтерфейсі все ще стандартний: %1 + + + This is a security risk, please consider changing your password from program preferences. + Це ризик безпеки, будь ласка, встановіть пароль в налаштуваннях програми. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + Вашу IP-адресу було заблоковано, через те, що було здійснено забагато спроб автентифікації. + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Зав.: %1/с (%2) + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Вив.: %1/с (%2) + + + + HttpServer + + File + Файл + + + Edit + Редагувати + + + Help + Допомога + + + Delete from HD + Видалити з жорсткого диска + + + Download Torrents from their URL or Magnet link + Завантажити торренти з іх URL або Магнітного посилання + + + Only one link per line + Одне посилання на рядок + + + Download + Завантажити + + + Download local torrent + Завантажити локальний торрент + + + Torrent files were correctly added to download list. + Торрент-файли були успішно додані до списку завантажень. + + + Point to torrent file + Вказати торрент-файл + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + Ви впевнені, що хочете видалити вибрані торренти зі списку завантажень і жорсткого диска? + + + Download rate limit must be greater than 0 or disabled. + Ліміт швидкості завантаження повинен бути більшим від 0 або відсутнім. + + + Upload rate limit must be greater than 0 or disabled. + Ліміт швидкості вивантаження повинен бути більшим від 0 або відсутнім. + + + Maximum number of connections limit must be greater than 0 or disabled. + Максимальна кількість з'єднань повинна бути більша за 0 або відсутня. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + Максимальна кількість з'єднань на торрент повинна бути більша за 0 або відсутня. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + Максимальна кількість з'єднань для вивантаження на торрент повинна бути більша за 0 або відсутня. + + + Unable to save program preferences, qBittorrent is probably unreachable. + Не вдалося зберегти налаштування програми. + + + Language + Мова + + + The port used for incoming connections must be greater than 1024 and less than 65535. + Порт, який використовується для вхідних підключень, повинен бути між 1024 і 65535. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Порт, який використовується для Веб-інтерфейсу повинен бути між 1024 і 65535. + + + The Web UI username must be at least 3 characters long. + Ім'я користувача Веб-інтерфейсу повинне містити хоча б 3 символи. + + + The Web UI password must be at least 3 characters long. + Пароль від Веб-інтерфейсу повинен містити хоча б 3 символи. + + + Downloaded + Is the file downloaded or not? + Завантажено + + + Save + Зберегти + + + qBittorrent client is not reachable + Клієнт qBittorrent недосяжний + + + HTTP Server + HTTP сервер + + + Torrent path + + + + Torrent name + + + + The following parameters are supported: + + + + + LegalNotice + + Legal Notice + Примітка + + + Legal notice + Примітка + + + Cancel + Скасувати + + + I Agree + Я погоджуюсь + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent - це програма для роздачі файлів. Коли ви запускаєте торрент, його дані будуть доступні іншим через вивантаження. Всі дані, які ви роздаєте, на вашій відповідальності + +Ця замітка більше не з'являтиметься. + + + Press %1 key to accept and continue... + Натисніть %1, щоб погодитись і продовжити... + + + + LineEdit + + Clear the text + Очистити текст + + + + MainWindow + + &Edit + &Редагувати + + + &File + &Файл + + + &Help + &Допомога + + + Preview file + Файл перегляду + + + Clear log + Очистити лог + + + Decrease priority + Зменшити приорітет + + + Increase priority + Збільшити приорітет + + + &Tools + &Інструменти + + + &View + &Показати + + + &Add File... + &Додати файл... + + + E&xit + Ви&хід + + + &Options... + &Налаштування... + + + Add &URL... + Д&одати URL... + + + Torrent &creator + Створювач &торрентів + + + Set upload limit... + Встановити ліміт вивантаження... + + + Set download limit... + Встановити ліміт завантаження... + + + Set global download limit... + Встановити глобальний ліміт завантаження... + + + Set global upload limit... + Встановити глобальний ліміт вивантаження... + + + &Log viewer... + Показати &журнал подій... + + + Top &tool bar + &Верхня панель + + + Display top tool bar + Показувати верхню панель + + + &Speed in title bar + &Швидкість у заголовку + + + Show transfer speed in title bar + Показувати швидкість завантаження і вивантаження у заголовку + + + Alternative speed limits + Альтернативні обмеження швидкості + + + &About + &Про програму + + + &Pause + При&зупинити + + + &Delete + &Видалити + + + P&ause All + З&упинити всі + + + Visit &Website + Відвідати веб&сайт + + + Report a &bug + Повідомити про &помилку + + + &Documentation + &Документація + + + &RSS reader + &Читач RSS + + + Search &engine + По&шуковик + + + Log viewer + Журнал подій + + + Lock qBittorrent + Заблокувати qBittorrent + + + Ctrl+L + Ctrl+L + + + Shutdown computer when downloads complete + Вимкнути комп'ютер, коли завершаться завантаження + + + &Resume + &Продовжити + + + R&esume All + П&родовжити всі + + + Shutdown qBittorrent when downloads complete + Вимкнути qBittorrent після завершення завантажень + + + Exit + Вийти + + + Import torrent... + Імпортувати торрент... + + + Donate money + Пожертвувати гроші + + + If you like qBittorrent, please donate! + Якщо вам подобається qBittorrent, будь ласка, пожертвуйте кошти! + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + Встановити пароль... + + + Transfers + Завантаження + + + Torrent file association + Асоціації torrent-файлів + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent не є програмою за замовчуванням для відкривання торрентів. +Встановити qBittorrent як програму для відкривання torrent-файлів та Магнітних посилань? + + + UI lock password + Пароль блокування інтерфейсу + + + Please type the UI lock password: + Будь ласка, введіть пароль блокування інтерфейсу: + + + Password update + Оновити пароль + + + The UI lock password has been successfully updated + Пароль блокування інтерфейсу був успішно оновлений + + + RSS + RSS + + + Search + Пошук + + + Transfers (%1) + Завантаження (%1) + + + Download completion + Завантажено + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + Завантаження '%1' закінчилось. + + + I/O Error + i.e: Input/Output Error + Помилка вводу/виводу + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Сталася помилка вводу/виводу для торрента %1. +Причина: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + Підтвердження рекурсивного завантаження + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Торрент %1 містить інші торренти. Завантажувати і їх? + + + Yes + Так + + + No + Ні + + + Never + Ніколи + + + Url download error + Помилка завантаження URL + + + Couldn't download file at url: %1, reason: %2. + Не вдалося завантажити файл з URL: %1, причина: %2. + + + Global Upload Speed Limit + Глобальний ліміт вивантаження + + + Global Download Speed Limit + Глобальний ліміт завантаження + + + Invalid password + Неправильний пароль + + + The password is invalid + Пароль неправильний + + + Exiting qBittorrent + Вихід із qBittorrent + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + Не всі завантаження завершені. +Ви впевнені, що хочете вийти з програми? + + + Always + Завжди + + + Open Torrent Files + Відкрити torrent-файли + + + Torrent Files + Torrent-файли + + + Options were saved successfully. + Налаштування були успішно збережені. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + Швидкість прийому: %1 КіБ/с + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + Швидкість віддачі: %1 КіБ/с + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (Зав.: %2/с, Вив.: %3/с) + + + A newer version is available + Доступна новіша версія + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Нова версія qBittorrent доступна на SourceForge. +Чи хочете ви оновити qBittorrent до версії %1? + + + Impossible to update qBittorrent + Неможливо оновити qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent не вдалося оновити. Причина: %1 + + + &Add torrent file... + &Додати торрент-файл... + + + Add &link to torrent... + Додати &посилання на торрент... + + + Import existing torrent... + Імпортувати існуючий торрент... + + + Execution &Log + &Журнал виконання + + + Execution Log + Журнал виконання + + + Auto-Shutdown on downloads completion + Автоматичне вимкнення після завершення завантажень + + + Exit qBittorrent + Вийти із qBittorrent + + + Suspend system + Призупинити систему + + + Shutdown system + Вимкнути систему + + + Disabled + Вимкнено + + + The password should contain at least 3 characters + Пароль повинен містити щонайменше 3 символи + + + + PeerAdditionDlg + + Invalid IP + Неправильна IP + + + The IP you provided is invalid. + Вказана IP-адреса неправильна. + + + + PeerListDelegate + + /s + /second (i.e. per second) + + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + Клієнт + + + Progress + i.e: % downloaded + Прогрес + + + Down Speed + i.e: Download speed + Шв. завант. + + + Up Speed + i.e: Upload speed + Шв. вивант. + + + Downloaded + i.e: total data downloaded + Завантажено + + + Uploaded + i.e: total data uploaded + Вивантажено + + + Ban peer permanently + Заблокувати піра + + + Peer addition + Додавання піра + + + The peer was added to this torrent. + Піра додано до цього торрента. + + + The peer could not be added to this torrent. + Не вдалося додати піра до цього торрента. + + + Are you sure? -- qBittorrent + Ви впевнені? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + Ви впевнені, що хочете назовсім заблокувати вибраних пірів? + + + &Yes + &Так + + + &No + &Ні + + + Manually banning peer %1... + Заблоковано піра %1... + + + Upload rate limiting + Обмеження швидкості вивантаження + + + Download rate limiting + Обмеження швидкості завантаження + + + Add a new peer... + Додати нового піра... + + + Limit download rate... + Обмежити швидкість завантаження... + + + Limit upload rate... + Обмежити швидкість вивантаження... + + + Copy IP + Копіювати IP-адресу + + + Connection + З'єднання + + + + Preferences + + UI + User Interface + Інтерфейс + + + Downloads + Завантаження + + + Connection + З'єднання + + + Bittorrent + Bittorrent + + + Proxy + Проксі + + + Web UI + Веб-інтерфейс + + + Language: + Мова: + + + (Requires restart) + (Потребує перезавантаження програми) + + + Visual style: + Візуальний стиль: + + + Transfer list + Список завантажень + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + Кожен другий рядок виділений кольором + + + File system + Файлова система + + + Torrent queueing + Черга торрентів + + + Maximum active downloads: + Макс. активних завантажень: + + + Maximum active uploads: + Макс. активних вивантажень: + + + Maximum active torrents: + Макс. активних торрентів: + + + When adding a torrent + При додаванні торрента + + + Display torrent content and some options + Відображати вміст торрента і деякі налаштування + + + Listening port + Порт + + + Port used for incoming connections: + Порт для вхідних з'єднань: + + + Random + Випадковий + + + Enable UPnP port mapping + Увімкнути UPnP + + + Enable NAT-PMP port mapping + Увімкнути NAT-PMP + + + Connections limit + Ліміт з'єднань + + + Global maximum number of connections: + Максимальна кількість з'єднань: + + + Maximum number of connections per torrent: + Максимальна кількість з'єднань на торрент: + + + Maximum number of upload slots per torrent: + Макс. з'єднань для вивантаження на торрент: + + + Upload: + Вивантаження: + + + Download: + Завантаження: + + + KiB/s + КіБ/с + + + Bittorrent features + Можливості Bittorrent + + + Enable DHT network (decentralized) + Увімкнути мережу DHT (децентралізована) + + + Use a different port for DHT and Bittorrent + Використовувати різні порти для DHT та Bittorrent + + + DHT port: + Порт DHT: + + + Enable Peer Exchange / PeX (requires restart) + Увімкнути обмін пірами/PeX (потребує перезавантаження) + + + Enable Local Peer Discovery + Увімкнути локальний пошук пірів + + + Enabled + Увімкнено + + + Forced + Примусове + + + Disabled + Вимкнено + + + Type: + Тип: + + + (None) + (Немає) + + + HTTP + HTTP + + + Port: + Порт: + + + Authentication + Автентифікація + + + Username: + Ім'я користувача: + + + Password: + Пароль: + + + SOCKS5 + SOCKS5 + + + HTTP Server + HTTP сервер + + + Filter path (.dat, .p2p, .p2b): + Шлях до фільтра (.dat, .p2p, .p2b): + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP-спілкування (трекери, веб-сіди, пошуковики) + + + Host: + Сервер: + + + Peer Communications + Спілкування пірів + + + SOCKS4 + SOCKS4 + + + Speed + Швидкість + + + Advanced + Додатково + + + Copy .torrent files to: + Копіювати torrent-файли до: + + + Global speed limits + Глобальні обмеження швидкості + + + Alternative global speed limits + Альтернативні глобальні обмеження швидкості + + + to + time1 to time2 + - + + + Every day + Щодня + + + Week days + Дні тижня + + + Week ends + Вихідні + + + Remove folder + Вилучити папку + + + No action + Без дії + + + Options + Налаштування + + + Visual Appearance + Вигляд + + + Action on double-click + Дія при подвійному клацанні + + + Downloading torrents: + Завантажую торренти: + + + Start / Stop + Почати / Зупинити + + + Open destination folder + Відкрити папку призначення + + + Completed torrents: + Завершені торренти: + + + Desktop + Робочий стіл + + + Show splash screen on start up + Показувати логотип при завантаженні програми + + + Start qBittorrent minimized + Запускати qBittorrent згорнутим + + + Show qBittorrent icon in notification area + Показувати qBittorrent у зоні сповіщень + + + Minimize qBittorrent to notification area + Згортати qBittorrent у зону сповіщень + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + Закривати qBittorrent у зону сповіщень + + + Do not start the download automatically + The torrent will be added to download list in pause state + Не починати заантаження автоматично + + + Save files to location: + Зберігати файли до: + + + Append the label of the torrent to the save path + Додавати мітку торрента до шляху збереження + + + Pre-allocate disk space for all files + Попередньо виділяти місце для всіх файлів + + + Keep incomplete torrents in: + Тримати незавершені торренти у: + + + Append .!qB extension to incomplete files' names + Додавати розширення .!qB до незавершених файлів + + + Automatically add torrents from: + Автоматично додавати торренти із: + + + Add folder... + Додати папку... + + + IP Filtering + IP-фільтр + + + Schedule the use of alternative speed limits + Розклад використання альтернативних обмежень швидкості + + + from + from (time1 to time2) + з + + + When: + Коли: + + + Look for peers on your local network + Шукати пірів у локальній мережі + + + Protocol encryption: + Шифрування протоколу: + + + Enable Web User Interface (Remote control) + Увімкнути Веб-інтерфейс (дистанційне керування) + + + Share ratio limiting + Обмеження коефіцієнта роздачі + + + Seed torrents until their ratio reaches + Сідувати торренти, доки їх коефіцієнт не досягне + + + then + тоді + + + Pause them + Призупинити їх + + + Remove them + Видалити їх + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + Обмін пірами із сумісними Bittorrent-клієнтами (µTorrent, Vuze, ...) + + + Email notification upon download completion + Сповіщення через e-mail при завершенні завантажень + + + Destination email: + E-mail призначення: + + + SMTP server: + SMTP сервер: + + + Run an external program on torrent completion + Запустити зовнішню програму при завершенні торрента + + + Use %f to pass the torrent path in parameters + Використовуйте %f, щоб передати шлях торрента як параметр + + + Proxy server + Проксі сервер + + + BitTorrent + BitTorrent + + + Start / Stop Torrent + Почати / зупинити торрент + + + Use UPnP / NAT-PMP port forwarding from my router + Використовувати UPnP / NAT-PMP з мого роутера + + + Privacy + Конфіденційність + + + Enable DHT (decentralized network) to find more peers + Увімкнути DHT (децентралізовану мережу, щоб знаходити більше пірів + + + Use a different port for DHT and BitTorrent + Використовувати різні порти для DHT та BitTorrent + + + Enable Peer Exchange (PeX) to find more peers + Увімкнути обмін пірами (PeX), щоб знаходити більше пірів + + + Enable Local Peer Discovery to find more peers + Увімкнути локальний пошук пірів, щоб знаходити більше пірів + + + Encryption mode: + Режим шифрування: + + + Prefer encryption + Надавати перевагу шифруванню + + + Require encryption + Вимагати шифрування + + + Disable encryption + Вимкнути шифрування + + + User Interface + Інтерфейс користувача + + + Reload the filter + Перезавантажити фільтр + + + Behavior + Поведінка + + + Language + Мова + + + Power Management + Керування енергоспоживанням + + + Inhibit system sleep when torrents are active + Не дозволяти призупинення системи, коли є активні торренти + + + Bypass authentication for localhost + Обходити автентифікацію для localhost + + + Ask for program exit confirmation + Вимагати підверрдження виходу з програми + + + Use monochrome system tray icon (requires restart) + Використовувати монохромний логотип системного лотка (вимагає перезапуску) + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + + + + Tray icon style: + + + + Normal + Нормальний + + + Monochrome (Dark theme) + + + + Monochrome (Light theme) + + + + This server requires a secure connection (SSL) + + + + User Interface Language: + + + + Transfer List + + + + Show qBittorrent in notification area + + + + Hard Disk + + + + Listening Port + + + + Connections Limits + + + + Proxy Server + + + + Torrent Queueing + + + + Share Ratio Limiting + + + + Use UPnP / NAT-PMP to forward the port from my router + + + + Update my dynamic domain name + + + + Service: + + + + Register + + + + Domain name: + + + + Global Rate Limits + + + + Apply rate limit to uTP connections + + + + Apply rate limit to transport overhead + + + + Alternative Global Rate Limits + + + + Schedule the use of alternative rate limits + + + + Enable bandwidth management (uTP) + + + + Otherwise, the proxy server is only used for tracker connections + + + + Use proxy for peer connections + + + + Append .!qB extension to incomplete files + + + + Use HTTPS instead of HTTP + + + + Import SSL Certificate + + + + Import SSL Key + + + + Certificate: + + + + Key: + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + + PreviewSelect + + Name + Назва + + + Size + Розмір + + + Progress + Прогрес + + + Preview impossible + Перегляд неможливий + + + Sorry, we can't preview this file + Пробачте, неможливо переглянути цей файл + + + + ProgramUpdater + + Could not create the file %1 + Не вдалося створити файл %1 + + + Failed to download the update at %1 + %1 is an URL + Не вдалося завантажити оновлення із %1 + + + + PropListDelegate + + Normal + Normal (priority) + Нормальний + + + High + High (priority) + Високий + + + Maximum + Maximum (priority) + Максимальний + + + Not downloaded + Не завантажується + + + Mixed + Mixed (priorities + Змішані + + + + PropTabBar + + General + Загальні + + + Trackers + Трекери + + + Peers + Піри + + + URL Seeds + URL-сіди + + + Files + Файли + + + HTTP Sources + Джерела HTTP + + + Content + Вміст + + + + PropertiesWidget + + Save path: + Шлях збереження: + + + Torrent hash: + Хеш: + + + Comment: + Коментар: + + + Share ratio: + Коефіцієнт роздачі: + + + General + Загальні + + + Trackers + Трекери + + + URL seeds + URL-сіди + + + Files + Файли + + + Priority + Пріоритет + + + New url seed + New HTTP source + Нова URL-роздача + + + New url seed: + Нова URL-роздача: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + Ця URL-роздача вже є в списку. + + + Choose save path + Виберіть шлях збереження + + + Save path creation error + Помилка при створенні шляху збереження + + + Could not create the save path + Не вдалося створити шлях збереження + + + Downloaded: + Завантажено: + + + Transfer + Передача + + + Uploaded: + Вивантажено: + + + Wasted: + Змарновано: + + + UP limit: + Ліміт вив.: + + + DL limit: + Ліміт зав.: + + + Time elapsed: + Минуло часу: + + + Connections: + З'єднання: + + + Information + Інформація + + + Created on: + Створено: + + + Peers + Піри + + + Maximum + Максимальний + + + High + Високий + + + this session + цієї сесії + + + %1 max + e.g. 10 max + макс. %1 + + + Availability: + Доступно: + + + /s + /second (i.e. per second) + + + + Seeded for %1 + e.g. Seeded for 3m10s + Роздавав %1 + + + Rename... + Перейменувати... + + + New name: + Нова назва: + + + The file could not be renamed + Файл не вдалося перейменувати + + + This name is already in use in this folder. Please use a different name. + Це ім'я вже використовується в цій папці. Будь ласка, виберіть інше ім'я. + + + The folder could not be renamed + Не вдалося перейменувати цю папку + + + Rename the file + Перейменувати файл + + + This file name contains forbidden characters, please choose a different one. + Це ім'я файла містить заборонені символи. Будь ласка, виберіть інше. + + + I/O Error + Помилка вводу/виводу + + + This file does not exist yet. + Цей файл ще не існує. + + + This folder does not exist yet. + Ця папка ще не існує. + + + Normal + Нормальний + + + Reannounce in: + Переанонсувати в: + + + Select All + Вибрати все + + + Select None + Зняти виділення + + + Do not download + Не завантажувати + + + Pieces size: + Розмір частин: + + + Time active: + Time (duration) the torrent is active (not paused) + Активний протягом: + + + Torrent content: + Вміст торренту: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1 досяг максимального коефіцієнта, налаштованого вами. + + + Removing torrent %1... + Видаляю торрент %1... + + + Pausing torrent %1... + Зупиняю торрент %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent використовує порт: %1 + + + UPnP support [ON] + Підтримка UNnP [Увімкнено] + + + UPnP support [OFF] + Підтримка UPnP [Вимкнено] + + + NAT-PMP support [ON] + Підтримка NAT-PMP [Увімкнено] + + + NAT-PMP support [OFF] + Підтримка NAT-PMP [Вимкнено] + + + HTTP user agent is %1 + Браузер користувача: %1 + + + Using a disk cache size of %1 MiB + Використовую дисковий кеш розміром %1 MiB + + + DHT support [ON], port: UDP/%1 + Підтримка DHT [Увімкнено], порт: UDP/%1 + + + DHT support [OFF] + Підтримка DHT [Вимкнено] + + + PeX support [ON] + Підтримка PeX [Увімкнено] + + + PeX support [OFF] + Підтримка PeX [Вимкнено] + + + Restart is required to toggle PeX support + Щоб перемкнути підтримку PeX, потрібно перезавантажити програму + + + Local Peer Discovery [ON] + Пошук Локальних Пірів [Увімкнено] + + + Local Peer Discovery support [OFF] + Пошук Локальних Пірів [Вимкнено] + + + Encryption support [ON] + Підтримка шифрування [Увімкнено] + + + Encryption support [FORCED] + Підтримка шифрування [Примусова] + + + Encryption support [OFF] + Підтримка шифрування [Вимкнено] + + + Embedded Tracker [ON] + Вбудований трекер [увімкнено] + + + Failed to start the embedded tracker! + Не вдалося запустити вбудований трекер! + + + Embedded Tracker [OFF] + Вбудований трекер [вимкнено] + + + The Web UI is listening on port %1 + Веб-інтерфейс приєднано до порту %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Помилка Веб-інтерфейсу - Не можу приєднати Веб-інтерфейс до порту %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' було видалено із списку завантажень і жорсткого диску. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' було видалено із списку завантажень. + + + '%1' is not a valid magnet URI. + '%1' не є правильним магнітним посиланням. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' вже є у списку завантажень. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' продовжено. (швидке відновлення) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' додано до списку завантажень. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + Не вдалося розкодувати торрент-файл: '%1' + + + This file is either corrupted or this isn't a torrent. + Цей файл або пошкоджений, або не є торрент-файлом. + + + Error: The torrent %1 does not contain any file. + Помилка: Торрент %1 не містить жодного файла. + + + Note: new trackers were added to the existing torrent. + Нові трекери було додано до існуючого торрента. + + + Note: new URL seeds were added to the existing torrent. + Нові URL-сіди було додано до існуючого торрента. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>було заблоковано згідно з вашим IP-фільтром</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>було заблоковано через пошкоджені частини</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + Рекурсивне завантаження файлу %1 в торренті %2 + + + Unable to decode %1 torrent file. + Не можу розкодувати %1 торрент-файл. + + + Torrent name: %1 + Назва торрента: %1 + + + Torrent size: %1 + Розмір торрента: %1 + + + Save path: %1 + Шлях збереження: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Торрент було завантажено за %1. + + + Thank you for using qBittorrent. + Дякуємо, що ви користуєтесь qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] Завантаження "%1" завершено + + + An I/O error occured, '%1' paused. + Сталася помилка вводу/виводу, '%1' зупинено. + + + Reason: %1 + Причина: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: Не можу приєднати порт, повідомлення: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: Успішне приєднання порта, повідомлення: %1 + + + File sizes mismatch for torrent %1, pausing it. + Розміри файлів не збігаються для торрента %1, зупиняю його. + + + Fast resume data was rejected for torrent %1, checking again... + Було відмовлено у швидкому відновленні данних для torrent'у %1, перевіряю знову... + + + Url seed lookup failed for url: %1, message: %2 + Пошук url роздачі невдалий для url: %1, повідомлення: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + Завантажую '%1', зачекайте... + + + The network interface defined is invalid: %1 + Зазначений мережевий інтерфейс неправильний: %1 + + + Trying any other network interface available instead. + Пробую на інших доступних мережевих інтерфейсах. + + + Listening on IP address %1 on network interface %2... + Чекаю підключень на IP %1 та мережевому інтерфейсі %2... + + + Failed to listen on network interface %1 + Не вдалося запуститись не мережевому інтерфейсі %1 + + + UPnP / NAT-PMP support [ON] + Підтримка UPnP / NAT-PMP [Увімкнено] + + + UPnP / NAT-PMP support [OFF] + Підтримка UPnP / NAT-PMP [Вимкнено] + + + Local Peer Discovery support [ON] + Підтримка локального пошуку пірів [Увімкнено] + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Успішно розібрано даний фільтр IP: було застосовано %1 правил. + + + Error: Failed to parse the provided IP filter. + Помилка: Не вдалося розібрати даний фільтр IP. + + + Reporting IP address %1 to trackers... + Повідомляю IP адресу %1 трекерам... + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + Зараз комп'ютер перемкнеться в режим сну, якщо ви не відміните це протягом наступних 15 секунд... + + + The computer will now be switched off unless you cancel within the next 15 seconds... + Зараз комп'ютер вимкнеться, якщо ви не відміните це протягом наступних 15 секунд... + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + Програма qBittorrent зараз закриється, якщо ви не відміните це протягом наступних 15 секунд... + + + + RSS + + Search + Пошук + + + Delete + Видалити + + + Rename + Перейменувати + + + Refresh RSS streams + Обновити потоки RSS + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Торренти:</span> <span style=" font-style:italic;">(двічі клацніть, щоб завантажити)</span></p></body></html> + + + Download torrent + Завантажити торрент + + + Open news URL + Відкрити URL новини + + + Copy feed URL + Копіювати URL подачі + + + New subscription + Нова підписка + + + Mark items read + Позначити як прочитане + + + Update all + Оновити всі + + + Update all feeds + Оновити всі подачі + + + RSS feeds + RSS-подачі + + + Update + Оновити + + + Feed URL + URL подачі + + + Article title + Заголовок + + + Rename... + Перейменувати... + + + New subscription... + Нова підписка... + + + RSS feed downloader... + Завантажувач RSS-подач... + + + New folder... + Нова папка... + + + Manage cookies... + Керування Cookies... + + + Settings... + Налаштування... + + + RSS Downloader... + Завантажувач RSS... + + + + RSSImp + + Please type a rss stream url + Будь-ласка, введіть url потоку rss + + + Stream URL: + URL потоку: + + + Are you sure? -- qBittorrent + Ви впевнені? -- qBittorrent + + + &Yes + &Так + + + &No + &Ні + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + Цей rss-стрічка вже є в списку. + + + Date: + Дата: + + + Author: + Автор: + + + Please choose a folder name + Будь ласка, виберіть назву папки + + + Folder name: + Назва папки: + + + New folder + Нова папка + + + Are you sure you want to delete these elements from the list? + Ви впевнені, що хочете видалити ці елементи зі списку? + + + Are you sure you want to delete this element from the list? + Ви впевнені, що хочете видалити цей елемент зі списку? + + + Please choose a new name for this RSS feed + Будь ласка, виберіть нове ім'я для цієї RSS-подачі + + + New feed name: + Нове ім'я подачі: + + + Name already in use + Ім'я вже використовується + + + This name is already used by another item, please choose another one. + Це ім'я вже використовується. Будь ласка, виберіть інше ім'я. + + + Overwrite attempt + Спроба перезапису + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + Ви не можете замінити "%1". + + + Unread + Непрочитані + + + + RssArticle + + No description available + Опис відсутній + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + Автоматично завантажую торрент %1 з RSS-подачі %2... + + + + RssItem + + No description available + Опис відсутній + + + + RssSettings + + RSS Reader Settings + Налаштування Читача RSS + + + RSS feeds refresh interval: + Інтервал оновлення RSS-подач: + + + minutes + хвилин + + + Maximum number of articles per feed: + Максимальна кількість новин в подачі: + + + + RssSettingsDlg + + RSS Reader Settings + Налаштування Читача RSS + + + RSS feeds refresh interval: + Інтервал оновлення RSS-подач: + + + minutes + хвилин + + + Maximum number of articles per feed: + Максимальна кількість новин в подачі: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + Автоматично завантажую торрент %1 з RSS-подачі %2... + + + + ScanFoldersModel + + Watched Folder + Папка спостерігання + + + Download here + Завантажувати сюди + + + + SearchCategories + + All categories + Всі категорії + + + Movies + Фільми + + + TV shows + Телешоу + + + Music + Музика + + + Games + Ігри + + + Anime + Аніме + + + Software + Програми + + + Pictures + Зображення + + + Books + Книги + + + + SearchEngine + + Empty search pattern + Пустий шаблон пошуку + + + Please type a search pattern first + Будь ласка, спочатку введіть шаблон пошуку + + + Results + Результати + + + Searching... + Шукаю... + + + Cut + Вирізати + + + Copy + Копіювати + + + Paste + Вставити + + + Clear field + Очистити поле + + + Clear completion history + Очистити історію автозавершення + + + Search Engine + Пошуковик + + + Search has finished + Пошук закінчено + + + An error occured during search... + Під час пошуку сталася помилка... + + + Search aborted + Пошук скасовано + + + Search returned no results + Пошук не дав результів + + + Results + i.e: Search results + Результати + + + Unknown + Невідомо + + + Search + Пошук + + + Download error + Помилка завантаження + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Не вдалося завантажити програму інсталяції Python. Причина: %1. +Будь ласка, встановіть Python самостійно. + + + Missing Python Interpreter + Не вистачає інтерпретатора Python + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + Для використання Пошуковика потрібен Python 2.x, але, здається, він не встановлений. +Встановити його зараз? + + + Confirmation + Підтвердження + + + Are you sure you want to clear the history? + Ви впевнені, що хочете очистити історію? + + + + SearchTab + + Name + i.e: file name + Ім'я + + + Size + i.e: file size + Розмір + + + Seeders + i.e: Number of full sources + Сідери + + + Leechers + i.e: Number of partial sources + Лічери + + + Search engine + Пошуковик + + + + ShutdownConfirmDlg + + Shutdown confirmation + Підтвердження вимкнення + + + + SpeedLimitDialog + + KiB/s + КіБ/с + + + + StatusBar + + Connection status: + Статус з'єднання: + + + No direct connections. This may indicate network configuration problems. + Немає прямих з'єднань. Це може означати, що є проблеми з мережею. + + + DHT: %1 nodes + DHT: %1 + + + Connection Status: + Статус з'єднання: + + + Online + В мережі + + + Global Download Speed Limit + Глобальний ліміт завантаження + + + Global Upload Speed Limit + Глобальний ліміт вивантаження + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + Зав.: %1/с (%2) + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + Вив.: %1/с (%2) + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + Зав.: %1 Б/с (%2) + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + Вив.: %1 Б/с (%2) + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + Не в мережі. Зазвичай це означає, що qBittorrent не зміг приєднатись до вибраного порту і очікувати вхідні з'єднання. + + + Click to disable alternative speed limits + Клацніть, щоб вимкнути альтернативні обмеження швидкості + + + Click to enable alternative speed limits + Клацніть, щоб увімкнути альтернативні обмеження швидкості + + + qBittorrent needs to be restarted + Потрібно перезапустити qBittorrent + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent було щойно оновлено, і тепер потрібно його перезапустити, щоб застосувати зміни. + + + Click to switch to alternative speed limits + Клацніть, щоб перемкнутись на альтернативні обмеження швидкості + + + Click to switch to regular speed limits + Клацніть, щоб перемкнутись на звичайні обмеження швидкості + + + %1/s + Per second + %1/с + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + Виберіть папку для додавання в torrent + + + Select a file to add to the torrent + Виберіть файл для додавання в торрент + + + Please type an announce URL + Будь ласка, введіть URL анонсу + + + Announce URL: + Tracker URL + URL анонсу: + + + Please type a web seed url + Будь ласка, введіть URL web-роздачі + + + Web seed URL: + URL web-роздачі: + + + No input path set + Не задано вхідний шлях + + + Please type an input path first + Будь ласка, спочатку введіть вхідний шлях + + + Select destination torrent file + Виберіть цільовий torrent-файл + + + Torrent Files + Торрент-файли + + + Torrent creation + Створення торренту + + + Torrent creation was unsuccessful, reason: %1 + Створення torrent'у було невдалим, причина: %1 + + + Created torrent file is invalid. It won't be added to download list. + Створений торрент-файл неправильний. Його не буде додано до списку завантажень. + + + Torrent was created successfully: + Торрент було успішно створено: + + + + TorrentFilesModel + + Name + Ім'я + + + Size + Розмір + + + Progress + Прогрес + + + Priority + Пріоритет + + + + TorrentImportDlg + + Torrent Import + Імпорт торрента + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + Цей майстер допоможе вам поділитись з qBittorrent торрентом, який ви вже завантажили. + + + Torrent file to import: + Торрент-файл, що імпортується: + + + ... + ... + + + Content location: + Розташування вмісту: + + + Skip the data checking stage and start seeding immediately + Пропустити перевірку даних та почати сідування негайно + + + Import + Імпорт + + + Torrent file to import + Торрент-файл, що імпортується + + + Torrent files (*.torrent) + Torrent-файли (*.torrent) + + + %1 Files + %1 is a file extension (e.g. PDF) + Файли %1 + + + Please provide the location of %1 + %1 is a file name + Будь ласка, вкажіть розташування %1 + + + Please point to the location of the torrent: %1 + Будь ласка, вкажіть на розташування торрента: %1 + + + Invalid torrent file + Неправильний torrent-файл + + + This is not a valid torrent file. + Цей файл не є правильним torrent-файлом. + + + + TorrentModel + + Name + i.e: torrent name + Назва + + + Size + i.e: torrent size + Розмір + + + Done + % Done + Зроблено + + + Status + Torrent status (e.g. downloading, seeding, paused) + Статус + + + Seeds + i.e. full sources (often untranslated) + Сіди + + + Peers + i.e. partial sources (often untranslated) + Піри + + + Down Speed + i.e: Download speed + Шв. завант. + + + Up Speed + i.e: Upload speed + Шв. вивант. + + + Ratio + Share ratio + Коефіцієнт + + + ETA + i.e: Estimated Time of Arrival / Time left + Залишилось + + + Label + Мітка + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Додано + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Завершено + + + Tracker + Трекер + + + Down Limit + i.e: Download limit + Ліміт завант. + + + Up Limit + i.e: Upload limit + Ліміт вивант. + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + Завантажено + + + Amount left + Amount of data left to download (e.g. in MB) + Залишилось + + + Time Active + Time (duration) the torrent is active (not paused) + Активний протягом + + + + TrackerList + + URL + URL + + + Status + Статус + + + Peers + Піри + + + Message + Повідомлення + + + [DHT] + [DHT] + + + Working + Працюю + + + Disabled + Вимкнено + + + This torrent is private + Цей торрент приватний + + + Updating... + Оновлюю... + + + Not working + Не працює + + + Not contacted yet + Ще не зв'язувався + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Add a new tracker... + Додати новий трекер... + + + Remove tracker + Видалити трекер + + + Force reannounce + Примусово переанонсувати + + + + TrackersAdditionDlg + + Trackers addition dialog + Додавання трекеру + + + List of trackers to add (one per line): + Список трекерів, які ви хочете додати (один на рядок): + + + µTorrent compatible list URL: + URL списку, сумісного з µTorrent: + + + I/O Error + Помилка вводу/виводу + + + Error while trying to open the downloaded file. + Не вдалося відкрити завантажений файл. + + + No change + Без змін + + + No additional trackers were found. + Не знайдено додаткових трекерів. + + + Download error + Помилка завантаження + + + The trackers list could not be downloaded, reason: %1 + Не вдалося завантажити список трекерів, причина: %1 + + + + TransferListDelegate + + Downloading + Завантажую + + + Paused + Зупинено + + + Queued + i.e. torrent is queued + В черзі + + + Seeding + Torrent is complete and in upload-only mode + Роздаю + + + Stalled + Torrent is waiting for download to begin + Заглохло + + + Checking + Torrent local data is being checked + Перевіряю + + + /s + /second (.i.e per second) + + + + KiB/s + KiB/second (.i.e per second) + КіБ/с + + + Seeded for %1 + e.g. Seeded for 3m10s + Роздавав %1 + + + + TransferListFiltersWidget + + All + Всі + + + Downloading + Завантажую + + + Completed + Завершені + + + Active + Активні + + + Inactive + Неактивні + + + All labels + Всі мітки + + + Unlabeled + Без мітки + + + Remove label + Видалити мітку + + + New Label + Нова мітка + + + Label: + Мітка: + + + Invalid label name + Неправильна назва мітки + + + Please don't use any special characters in the label name. + Будь ласка, не використовуйте спеціальні символи в назві мітки. + + + Paused + Зупинено + + + Add label... + Додати мітку... + + + Resume torrents + Відновити завантаження + + + Pause torrents + Призупинити завантаження + + + Delete torrents + Видалити торренти + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + Залишилось + + + Column visibility + Видимість колонок + + + Open destination folder + Відкрити папку призначення + + + Force recheck + Примусова перевірка + + + Copy magnet link + Копіювати Магнітне посилання + + + Down Speed + i.e: Download speed + Шв. завантаження + + + Up Speed + i.e: Upload speed + Шв. вивантаження + + + Name + i.e: torrent name + Назва + + + Size + i.e: torrent size + Розмір + + + Done + % Done + Зроблено + + + Status + Torrent status (e.g. downloading, seeding, paused) + Статус + + + Seeds + i.e. full sources (often untranslated) + Сіди + + + Peers + i.e. partial sources (often untranslated) + Піри + + + Ratio + Share ratio + Коефіцієнт + + + Torrent Download Speed Limiting + Обмеження швидкості завантаження торрента + + + Torrent Upload Speed Limiting + Обмеження швидкості вивантаження торрента + + + Super seeding mode + Режим супер-сідування + + + Download in sequential order + Завантажувати послідовно + + + Download first and last piece first + Спочатку завантажувати першу і останню частину + + + Label + Мітка + + + New Label + Нова мітка + + + Label: + Мітка: + + + New... + New label... + Нова... + + + Reset + Reset label + Забрати мітку + + + Rename + Перейменувати + + + New name: + Нове ім'я: + + + Rename... + Перейменувати... + + + Invalid label name + Неправильне ім'я мітки + + + Please don't use any special characters in the label name. + Будь ласка, не використовуйте спеціальних символів в назві мітки. + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + Додано + + + Completed On + Torrent was completed on 01/01/2010 08:00 + Завершено + + + Down Limit + i.e: Download limit + Ліміт завантаження + + + Up Limit + i.e: Upload limit + Ліміт вивантаження + + + Choose save path + Виберіть шлях збереження + + + Save path creation error + Помилка при створенні шляху збереження + + + Could not create the save path + Не вдалося створити шлях збереження + + + Set location... + Встановити місце... + + + Preview file... + Переглянути файл... + + + Limit upload rate... + Обмежити швидкість вивантаження... + + + Limit download rate... + Обмежити швидкість завантаження... + + + Move up + i.e. move up in the queue + Посунути вгору + + + Move down + i.e. Move down in the queue + Посунути вниз + + + Move to top + i.e. Move to top of the queue + Розмістити зверху + + + Move to bottom + i.e. Move to bottom of the queue + Розмістити знизу + + + Priority + Пріоритет + + + Resume + Resume/start the torrent + Продовжити + + + Pause + Pause the torrent + Призупинити + + + Delete + Delete the torrent + Видалити + + + Limit share ratio... + Обмежити коефіцієнт роздачі... + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + Обмеження коефіцієнта "вивантаження/завантаження" торрента + + + Use global ratio limit + Використовувати глобальні обмеження + + + buttonGroup + + + + Set no ratio limit + Не використовувати обмеження коефіцієнта + + + Set ratio limit to + Встановити обмеження коефіцієнта на + + + + UsageDisplay + + Usage: + Використання: + + + displays program version + показує версію програми + + + disable splash screen + вимкнути початкову заставку + + + displays this help message + показує це повідомлення + + + changes the webui port (current: %1) + змінює порт Веб-інтерфейсу (поточний: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [файли або URL'и]: завантажує торренти, вказані користувачем (необов'язково) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + Я хотів би подякувати наступним людям, які переклали qBittorrent на власні мови: + + + Please contact me if you would like to translate qBittorrent into your own language. + Будь-ласка зв'яжітся зі мною, якщо ви бажаєте перекласти qBittorrent на вашу мову. + + + + addPeerDialog + + Peer addition + Додавання піра + + + IP + IP + + + Port + Порт + + + + addTorrentDialog + + Torrent addition dialog + Діалог додавання торренту + + + Save path: + Шлях збереження: + + + ... + ... + + + Torrent content: + Вміст торренту: + + + Add to download list in paused state + Додати до списку завантажень у призупиненому стані + + + Add + Додати + + + Cancel + Відміна + + + Normal + Нормальний + + + High + Високий + + + Maximum + Максимальний + + + Torrent size: + Розмір торрента: + + + Unknown + Невідомо + + + Free disk space: + Вільне місце на диску: + + + Download in sequential order (slower but good for previewing) + Завантажувати по порядку (повільніше, але краще для перегляду) + + + Skip file checking and start seeding immediately + Пропустити перевірку файлів і почати сідування негайно + + + Label: + Мітка: + + + Select All + Вибрати все + + + Select None + Зняти виділення + + + Do not download + Не завантажувати + + + + authentication + + Tracker authentication + Аутентификация на трекере + + + Tracker: + Трекер: + + + Login + Логін + + + Username: + Ім'я користувача: + + + Password: + Пароль: + + + Log in + Увійти + + + Cancel + Відміна + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + Підтвердження видалення - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + Ви впевнені, що хочете видалити вибрані торренти зі списку завантажень? + + + Remember choice + Запам'ятати вибір + + + Also delete the files on the hard disk + Також видалити файли на жорсткому диску + + + + createTorrentDialog + + Cancel + Відміна + + + Torrent Creation Tool + Інструмент для створення Torrent'ів + + + Torrent file creation + Створення torrent-файлу + + + Announce urls (trackers): + urls анонсу (трекери): + + + Comment (optional): + Коментарій (необов'язково): + + + Web seeds urls (optional): + Urls web-роздачі (необов'язково): + + + File or folder to add to the torrent: + Файл або папка для додавання в торрент: + + + Piece size: + Розмір частини: + + + 32 KiB + 32 КіБ + + + 64 KiB + 64 КіБ + + + 128 KiB + 128 КіБ + + + 256 KiB + 256 КіБ + + + 512 KiB + 512 КіБ + + + 1 MiB + 1 МіБ + + + 2 MiB + 2 МіБ + + + 4 MiB + 4 МіБ + + + Private (won't be distributed on DHT network if enabled) + Приватно (не буде передаватись через мережу DHT, якщо увімкнено) + + + Start seeding after creation + Почати роздачу одразу після створення + + + Create and save... + Створити і зберегти... + + + Progress: + Прогрес: + + + Add file + Додати файл + + + Add folder + Додати папку + + + Tracker URLs: + URL трекерів: + + + Web seeds urls: + URL веб-сідів: + + + Comment: + Коментар: + + + Auto + Автоматично + + + + createtorrent + + Select destination torrent file + Виберіть цільовий torrent-файл + + + Torrent Files + Torrent файли + + + No input path set + Не задано вхідний шлях + + + Please type an input path first + Будь ласка, спочатку введіть вхідний шлях + + + Torrent creation + Створення торренту + + + Torrent was created successfully: + Торрент було успішно створено: + + + Select a folder to add to the torrent + Виберіть папку для додавання в torrent + + + Please type an announce URL + Будь ласка, введіть URL анонсу + + + Torrent creation was unsuccessful, reason: %1 + Створення torrent'у було невдалим, причина: %1 + + + Announce URL: + Tracker URL + URL анонсу: + + + Please type a web seed url + Будь ласка, введіть URL web-роздачі + + + Web seed URL: + URL web-роздачі: + + + Select a file to add to the torrent + Виберіть файл для додавання в торрент + + + Created torrent file is invalid. It won't be added to download list. + Створений торрент-файл неправильний. Він не буде доданий до списку завантажень. + + + + downloadFromURL + + Download Torrents from URLs + Завантажити торренти з URL-ів + + + Only one URL per line + Лише один URL на лінію + + + Download + Завантажити + + + Cancel + Відміна + + + Download from urls + Завантажити з URL'ів + + + No URL entered + Не введено URL + + + Please type at least one URL. + Будь ласка, введіть хоча б один URL. + + + Add torrent links + Додати посилання на торрент + + + Both HTTP and Magnet links are supported + І HTTP, і магнітні посилання підтримуються + + + + downloadThread + + I/O Error + Помилка вводу/виводу + + + The remote host name was not found (invalid hostname) + Віддалений сервер не знайдено (неправильна адреса) + + + The operation was canceled + Операцію скасовано + + + The remote server closed the connection prematurely, before the entire reply was received and processed + Віддалений сервер закрив з'єднання зарано, перед тим, як було отримано і оброблено відповідь + + + The connection to the remote server timed out + Вичерпано час на з'єднання з віддаленим сервером + + + SSL/TLS handshake failed + Помилка SSL/TLS + + + The remote server refused the connection + Віддалений сервер відмовив у з'єднанні + + + The connection to the proxy server was refused + Відмовлено у з'єднанні з проксі-сервером + + + The proxy server closed the connection prematurely + Проксі-сервер закрив з'єднання + + + The proxy host name was not found + Не знайдено проксі-сервер + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + Вичерпано час на з'єднання з проксі + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + Проксі потребує автентифікації, але не прийняв автентифікаційних даних + + + The access to the remote content was denied (401) + Відмовлено у доступі до віддалених даних (401) + + + The operation requested on the remote content is not permitted + Операція щодо віддаленого контенту не дозволена + + + The remote content was not found at the server (404) + Віддалені дані не знайдено на сервері (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + Віддалений сервер потребує автентифікації, але не прийняв автентифікаційних даних + + + The Network Access API cannot honor the request because the protocol is not known + Невідомий протокол + + + The requested operation is invalid for this protocol + Операція неправильна для цього протоколу + + + An unknown network-related error was detected + Невідома помилка, пов'язана з мережею + + + An unknown proxy-related error was detected + Невідома помилка, пов'язана з проксі + + + An unknown error related to the remote content was detected + Невідома помилка, пов'язана з віддаленим контентом + + + A breakdown in protocol was detected + Поломка в протоколі + + + Unknown error + Невідома помилка + + + + engineSelect + + Search plugins + Пошукові плагіни + + + Installed search engines: + Встановлені пошуковики: + + + Name + Ім'я + + + Url + Url + + + Enabled + Увімкнено + + + Install a new one + Встановити новий + + + Check for updates + Перевірити оновлення + + + Close + Закрити + + + Enable + Дозволити + + + Disable + Заборонити + + + Uninstall + Видалити + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + Ви можете отримати нові пошукові плагіни тут: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + engineSelectDlg + + Uninstall warning + Попередження про видалення + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + Деякі плагіни не можуть бути видалені, тому що вони є частиною qBittorrent. +Можна видалити лише ті плагіни, які ви встановили власноруч. +Тим не менше, ці плагіни вимкнено. + + + Uninstall success + Видалення успішне + + + Select search plugins + Вибрати пошукові плагіни + + + qBittorrent search plugins + Пошукові плагіни qBittorrent + + + Search plugin install + Встановити пошуковий плагін + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + Новіша версія пошукового плагіну %1 вже є встановлена. + + + Search plugin update + Оновити пошуковий плагін + + + Sorry, update server is temporarily unavailable. + Пробачте, сервер оновлень тимчасово недоступний. + + + All your plugins are already up to date. + Всі ваші плагіни мають останню версію. + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + Пошуковий плагін %1 не вдалося оновити, залишено стару версію. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + Не вдалося встановити пошуковий плагін %1. + + + All selected plugins were uninstalled successfully + Всі вибрані пошукові плагіни було успішно видалено + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + Пошуковий плагін %1 було успішно оновлено. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + Пошуковий плагін %1 було успішно встановлено. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + Вибачте, встановлення пошукового плагіну %1 невдале. + + + New search engine plugin URL + Новий URL пошукового плагіну + + + URL: + URL: + + + Yes + Так + + + No + Ні + + + + misc + + B + bytes + Б + + + KiB + kibibytes (1024 bytes) + КіБ + + + MiB + mebibytes (1024 kibibytes) + МіБ + + + GiB + gibibytes (1024 mibibytes) + ГіБ + + + TiB + tebibytes (1024 gibibytes) + ТіБ + + + Unknown + Невідомо + + + Unknown + Unknown (size) + Невідомо + + + < 1m + < 1 minute + < 1хв + + + %1m + e.g: 10minutes + %1хв + + + %1h %2m + e.g: 3hours 5minutes + %1г %2хв + + + %1d %2h + e.g: 2days 10hours + %1д %2г + + + qBittorrent will shutdown the computer now because all downloads are complete. + Зараз qBittorrent вимкне комп'ютер, бо всі завантаження завершено. + + + + options_imp + + Choose a save directory + Виберіть директорію для збереження + + + Choose an ip filter file + Виберіть файл IP-фільтру + + + Filters + Фільтри + + + Choose export directory + Виберіть папку для експорту + + + Add directory to scan + + + + Folder is already being watched. + За папкою вже ведеться стеження. + + + Folder does not exist. + Папка не існує. + + + Folder is not readable. + Папку неможливо прочитати. + + + Failure + Провал + + + Failed to add Scan Folder '%1': %2 + Не вдалося просканувати папку '%1': %2 + + + Parsing error + Помилка розбору + + + Failed to parse the provided IP filter + Не вдалося розібрати даний фільтр IP + + + Succesfully refreshed + Успішно оновлено + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + Успішно розібрано даний фільтр IP: було застосовано %1 правил. + + + Successfully refreshed + Успішно оновлено + + + Invalid key + + + + This is not a valid SSL key. + + + + Invalid certificate + + + + This is not a valid SSL certificate. + + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + + pluginSourceDlg + + Plugin source + Джерело плагіну + + + Search plugin source: + Джерело пошукового плагіну: + + + Local file + Локальний файл + + + Web link + Веб-посилання + + + + preview + + Preview selection + Вибір перегляду + + + File preview + Перегляд файлу + + + The following files support previewing, <br>please select one of them: + Наступні файли підтримують перегляд, <br>будь-ласка, виберіть один з них: + + + Preview + Перегляд + + + Cancel + Відміна + + + + previewSelect + + Preview impossible + Перегляд неможливий + + + Sorry, we can't preview this file + Пробачте, неможливо переглянути цей файл + + + Name + Ім'я + + + Size + Розмір + + + Progress + Прогрес + + + + search_engine + + Search + Пошук + + + Status: + Статус: + + + Stopped + Зупинено + + + Download + Завантажити + + + Search engines... + Пошуковики... + + + Go to description page + Іти до сторінки опису + + + + torrentAdditionDialog + + Unable to decode torrent file: + Не вдалося розкодувати torrent-файл: + + + Choose save path + Виберіть шлях збереження + + + Empty save path + Пустий шлях збереження + + + Please enter a save path + Будь-ласка, введіть шлях збереження + + + Save path creation error + Помилка при створенні шляху збереження + + + Could not create the save path + Не вдалося створити шлях збереження + + + Invalid file selection + Неправильно вибрано файл + + + You must select at least one file in the torrent + Ви повинні вибрати хоча б один файл в торренті + + + Priority + Пріоритет + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (%1 залишиться після завантаження) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (потрібно ще %1 вільного місця) + + + Seeding mode error + Помилка режиму сідування + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + Ви вирішили пропустити перевірку файлів. Але, здається, локальні файли не існують в заданій папці. Будь ласка, вимкніть цю можливіть або змініть шлях збереження. + + + Rename... + Перейменувати... + + + New name: + Нове ім'я: + + + The file could not be renamed + Файл не вдалося перейменувати + + + This name is already in use in this folder. Please use a different name. + Це ім'я вже використовується в цій папці. Виберіть інше ім'я. + + + The folder could not be renamed + Папку не вдалося перейменувати + + + Rename the file + Перейменувати файл + + + Unable to decode magnet link: + Не вдалося розкодувати магнітне посилання: + + + Magnet Link + Магнітне посилання + + + Invalid label name + Неправильна назва мітки + + + Please don't use any special characters in the label name. + Будь ласка, не використовуйте спеціальних символів в назві мітки. + + + This file name contains forbidden characters, please choose a different one. + Це ім'я файла містить заборонені символи. Будь ласка, виберіть інше. + + + diff --git a/src/lang/qbittorrent_zh.qm b/src/lang/qbittorrent_zh.qm new file mode 100644 index 0000000000000000000000000000000000000000..7fe52aa505bac50a543b11a17982d73203ffa07b GIT binary patch literal 87069 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 + + + + AboutDlg + + About qBittorrent + 关于 qBittorrent + + + About + 关于 + + + Author + 作者 + + + Name: + 姓名: + + + Country: + 国家: + + + E-mail: + 电子邮件: + + + Christophe Dumez + + + + France + 法国 + + + Translation + 翻译 + + + License + 许可证 + + + <h3><b>qBittorrent</b></h3> + + + + chris@qbittorrent.org + + + + Thanks to + 感谢 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">该bittorrent用户用C++语言编写,使用Qt4工具包.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">和libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">主页:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">该高级Bitorrent用户以C++语言编写, 并以Qt4 工具包和libtorrent-rasterbar为基础. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">主页:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">故障跟踪:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + AdvancedSettings + + Property + 属性 + + + Value + + + + Ignore transfer limits on local network + 忽略本地网络的传输限制 + + + Include TCP/IP overhead in transfer limits + 在传输限制中包括TCP/IP总开销 + + + Disk write cache size + 磁盘写入缓存大小 + + + MiB + MiB + + + Outgoing ports (Min) [0: Disabled] + 出端口(最小) [0: 禁用] + + + Outgoing ports (Max) [0: Disabled] + 出端口(最大) [0: 禁用] + + + Recheck torrents on completion + 完成后再次核对torrent + + + Transfer list refresh interval + 传输列表刷新间隔 + + + ms + milliseconds + ms + + + Resolve peer countries (GeoIP) + 显示用户国家(GeoIP) + + + Resolve peer host names + 显示用户主机名 + + + Maximum number of half-open connections [0: Disabled] + 最大半开放连接数 [0: 禁用] + + + Strict super seeding + 严格超级做种 + + + Network Interface (requires restart) + 网络界面(需要重启) + + + Any interface + i.e. Any network interface + 任何界面 + + + Display program notification baloons + 显示程序通知消息 + + + Display program notification balloons + 显示程序通知消息 + + + Enable embedded tracker + 启用嵌入式tracker + + + Embedded tracker port + 嵌入式tracker端口 + + + Check for software updates + 检查软件更新 + + + Use system icon theme + 使用系统图标主题 + + + Confirm torrent deletion + 确认删除torrent + + + IP Address to report to trackers (requires restart) + 向追踪器报告IP地址(需重启) + + + Display program on-screen notifications + 在屏幕上显示程序通知 + + + Setting + 设置 + + + Value + Value set for this setting + + + + Exchange trackers with other peers + + + + + AutomatedRssDownloader + + Automated RSS Downloader + 自动RSS下载器 + + + Enable the automated RSS downloader + 启动自动RSS下载器 + + + Download rules + 下载规则 + + + Rule definition + 规则定义 + + + Must contain: + 必须包含: + + + Must not contain: + 必须不包含: + + + ... + ... + + + Assign label: + 指定标签: + + + Apply rule to feeds: + 对该文件应用规则: + + + Matching RSS articles + 匹配RSS文章 + + + Save to a different directory + 保存到不同的目录 + + + Save to: + 保存到: + + + Import... + 导入... + + + Export... + 导出... + + + New rule name + 新规则名称 + + + Please type the name of the new download rule. + 请命名新的下载规则 + + + Rule name conflict + 规则名称冲突 + + + A rule with this name already exists, please choose another name. + 该名称已被另一规则使用, 请重新命名 + + + Are you sure you want to remove the download rule named %1? + 您确定要移除名为%1的下载规则吗? + + + Are you sure you want to remove the selected download rules? + 您确定要移除选中的规则吗? + + + Rule deletion confirmation + 确认删除规则 + + + Destination directory + 目标目录 + + + Invalid action + 无效行为 + + + The list is empty, there is nothing to export. + 该目录为空, 无项目可导出. + + + Where would you like to save the list? + 您想将该目录保存在? + + + Rules list (*.rssrules) + 规则目录 (*.rssrules) + + + I/O Error + 输入/输出错误 + + + Failed to create the destination file + 创建目标文件失败 + + + Please point to the RSS download rules file + 请指向RSS下载规则文件 + + + Rules list (*.rssrules *.filters) + 规则目录 (*.rssrules *.filters) + + + Import Error + 导入错误 + + + Failed to import the selected rules file + 无法导入选中的规则文件 + + + Add new rule... + 添加新规则... + + + Delete rule + 删除规则 + + + Rename rule... + 重命名规则... + + + Delete selected rules + 删除选中的规则 + + + Rule renaming + 正在重命名规则 + + + Please type the new rule name + 请输入新的规则名称 + + + Use regular expressions + 使用正则表达式 + + + Regex mode: use Perl-like regular expressions + 正则表达式模式: 使用类似Perl的正则表达式 + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + 通配符模式:可使用<ul><li>? 匹配任意单字符</li><li>* 匹配零个或多个任意字符</li><li>空格视为运算符"且"</li></ul> + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + 通配符模式:可使用<ul><li>? 匹配任意单字符</li><li>* 匹配零个或多个任意字符</li><li>| 表示运算符"或"</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + '%1'达到您设置的最大比率. + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent 绑定端口: TCP/%1 + + + UPnP support [ON] + UPnP 支持[开] + + + UPnP support [OFF] + UPnP 支持[关] + + + NAT-PMP support [ON] + NAT-PMP 支持[开] + + + NAT-PMP support [OFF] + NAT-PMP 支持[关] + + + DHT support [ON], port: UDP/%1 + DHT 支持 [开], 端口: UDP/%1 + + + DHT support [OFF] + DHT 支持[关] + + + PeX support [ON] + PeX 支持[ON] + + + Local Peer Discovery [ON] + 本地资源搜索[开] + + + Local Peer Discovery support [OFF] + 本地资源搜索支持[关] + + + Encryption support [ON] + 加密支持[开] + + + Encryption support [FORCED] + 加密支持[强制] + + + Encryption support [OFF] + 加密支持[关] + + + Web User Interface Error - Unable to bind Web UI to port %1 + 网络用户界面错误-无法绑定网络用户界面到端口%1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1'从传输列表及硬盘被移除. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1'从传输列表被移除. + + + '%1' is not a valid magnet URI. + %1不是有效的MAGNET链接. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1'已存在于下载列表中. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1'重新开始. (快速) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1'添加到下载列表. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + 无法解码torrent文件:'%1' + + + This file is either corrupted or this isn't a torrent. + 该文件不是torrent文件或已经损坏. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>被您的IP过滤器阻止</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>因损坏碎片被禁止</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + 循环下载包含在torrent%2中的文件%1 + + + Unable to decode %1 torrent file. + 无法解码%1torrent文件. + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: 端口映射失败, 消息: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: 端口映射成功, 消息: %1 + + + Fast resume data was rejected for torrent %1, checking again... + 快速继续数据torrent %1失败,再次检查... + + + Url seed lookup failed for url: %1, message: %2 + 找不到网址种子:%1, 消息:%2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + '%1'下载中,请等待... + + + Using a disk cache size of %1 MiB + 使用%1:MiB磁盘高速缓存 + + + PeX support [OFF] + PeX 支持[关] + + + Restart is required to toggle PeX support + 更改PeX支持状态需要重启 + + + The Web UI is listening on port %1 + Web用户界面在侦听端口%1 + + + HTTP user agent is %1 + HTTP用户代理是%1 + + + Reason: %1 + 原因: + + + Note: new trackers were added to the existing torrent. + 注意:新跟踪器被添加到现有的torrent. + + + Note: new URL seeds were added to the existing torrent. + 注意:新URL种子被添加到现有的torrent. + + + An I/O error occured, '%1' paused. + 出现输入/输出错误,'%1'暂停. + + + Removing torrent %1... + 正在移除torrent%1... + + + Pausing torrent %1... + 正在暂停torrent%1... + + + Error: The torrent %1 does not contain any file. + 错误:torrent%1不包含任何内容. + + + File sizes mismatch for torrent %1, pausing it. + 文件大小与torrent%1不匹配,暂停中. + + + Torrent name: %1 + Torrent名称:%1 + + + Torrent size: %1 + Torrent大小:%1 + + + Save path: %1 + 保存路径:%1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + 该torrent下载用时为%1. + + + Thank you for using qBittorrent. + 感谢您使用qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1下载完毕. + + + + ConsoleDlg + + General + 普通 + + + Blocked IPs + 被阻止IP + + + qBittorrent log viewer + qBittorrent日志浏览器 + + + + CookiesDlg + + Cookies management + Cookies管理 + + + Key + As in Key/Value pair + 键值 + + + Value + As in Key/Value pair + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + 对cookies的公共键值为:%1,%2. +您可以在您的浏览器首选项里得到相关信息. + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + 您的动态域名系统已更新成功. + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + 动态域名系统错误: 该服务暂时无法使用, 30分钟后将重试. + + + Dynamic DNS error: hostname supplied does not exist under specified account. + 动态域名系统错误: 指定的帐户下不存在提供的主机名. + + + Dynamic DNS error: Invalid username/password. + 动态域名系统错误: 无效用户名/密码. + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + 动态域名系统错误: qBittorrent被该服务列入黑名单, 请报告故障至 http://bugs.qbittorrent.org. + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + 动态域名系统错误: 服务返回%1, 请报告故障至 http://bugs.qbittorrent.org. + + + Dynamic DNS error: Your username was blocked due to abuse. + 动态域名系统错误: 您的用户名由于滥用被阻止. + + + Dynamic DNS error: supplied domain name is invalid. + 动态域名系统错误: 提供的域名无效. + + + Dynamic DNS error: supplied username is too short. + 动态域名系统错误: 提供的用户名过短. + + + Dynamic DNS error: supplied password is too short. + 动态域名系统错误: 提供的密码过短. + + + + DownloadThread + + I/O Error + 输入/输出错误 + + + The remote host name was not found (invalid hostname) + 未找到远端主机名(无效主机名) + + + The operation was canceled + 操作被取消 + + + The remote server closed the connection prematurely, before the entire reply was received and processed + 远端服务器在接到和处理完整回复前过早关闭连接 + + + The connection to the remote server timed out + 连接远端伺服器超时 + + + SSL/TLS handshake failed + SSL/TLS握手失败 + + + The remote server refused the connection + 远端服务器拒绝连接 + + + The connection to the proxy server was refused + 连接到代理服务器被拒绝 + + + The proxy server closed the connection prematurely + 代理服务器过早关闭连接 + + + The proxy host name was not found + 未找到代理主机名 + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + 连接到代理服务器超时或代理服务器未及时回复请求 + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + 为了执行要求,代理服务器需要认证但不接受任何提供的凭证 + + + The access to the remote content was denied (401) + 读取远端内容被拒绝 (401) + + + The operation requested on the remote content is not permitted + 对于远端内容请求的操作未被允许 + + + The remote content was not found at the server (404) + 内容在远端伺服器上未找到(404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + 为了提供内容,远端伺服器需要认证但不接受任何提供的凭证 + + + The Network Access API cannot honor the request because the protocol is not known + 由于协议未知网络访问API不能履行请求 + + + The requested operation is invalid for this protocol + 请求的操作对该协议无效 + + + An unknown network-related error was detected + 检测到未知的关于局域网的错误 + + + An unknown proxy-related error was detected + 检测到未知的关于代理服务器的错误 + + + An unknown error related to the remote content was detected + 检测到未知的关于远端内容的错误 + + + A breakdown in protocol was detected + 检测到协议故障 + + + Unknown error + 未知错误 + + + + EventManager + + %1/s + e.g. 120 KiB/s + %1/s + + + Working + 运行 + + + Updating... + 更新中... + + + Not working + 不可用 + + + Not contacted yet + 未联系 + + + this session + 此次会话 + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + 已做种%1 + + + %1 max + e.g. 10 max + %1最大 + + + + ExecutionLog + + Form + 表格 + + + General + 普通 + + + Blocked IPs + 被阻止IP + + + + FeedDownloader + + RSS Feed downloader + 从RSS文件下载 + + + RSS feed: + RSS文件: + + + Feed name + 文件名 + + + Automatically download torrents from this feed + 自动下载此文件中的torrent + + + Download filters + 下载过滤器 + + + Filters: + 过滤器: + + + Filter settings + 过滤器设置 + + + Matches: + 匹配: + + + Does not match: + 不匹配: + + + Destination folder: + 目标文件夹: + + + ... + ... + + + Filter testing + 过滤器测试 + + + Torrent title: + Torrent标题: + + + Result: + 结果: + + + Test + 测试 + + + Import... + 导入... + + + Export... + 导出... + + + Rename filter + 重命名过滤器 + + + Remove filter + 删除过滤器 + + + Add filter + 添加过滤器 + + + + FeedDownloaderDlg + + New filter + 新过滤器 + + + Please choose a name for this filter + 请选择过滤器名 + + + Filter name: + 过滤器名: + + + Invalid filter name + 无效过滤器名 + + + The filter name cannot be left empty. + 过滤器名不能为空. + + + This filter name is already in use. + 该过滤器名已被使用. + + + Filter testing error + 过滤器测试错误 + + + Please specify a test torrent name. + 请指定测试torrent名称. + + + matches + 匹配 + + + does not match + 不匹配 + + + Select file to import + 选择要导入的文件 + + + Filters Files + 过滤器文件 + + + Import successful + 导入成功 + + + Filters import was successful. + 过滤器导入成功. + + + Import failure + 导入失败 + + + Filters could not be imported due to an I/O error. + 输入/输出错误使过滤器不能被导入. + + + Select destination file + 选择目标文件 + + + Export successful + 导出成功 + + + Filters export was successful. + 过滤器导出成功. + + + Export failure + 导出失败 + + + Filters could not be exported due to an I/O error. + 输入/输出错误使过滤器不能被导出. + + + Choose save path + 选择保存路径 + + + + FeedList + + Unread + 未读 + + + + FeedListWidget + + RSS feeds + RSS文件 + + + Unread + 未读 + + + + GUI + + Open Torrent Files + 打开Torrent文件 + + + Torrent Files + Torrent文件 + + + Transfers + 传输 + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + 下载速度: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + 上传速度: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + '%1'下载完毕. + + + I/O Error + i.e: Input/Output Error + 输入/输出错误 + + + Search + 搜索 + + + RSS + RSS + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + torrent %1 出现输入/输出错误. +原因: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + 网址下载错误 + + + Couldn't download file at url: %1, reason: %2. + 无法在网址:%1下载文件,原因:%2. + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Options were saved successfully. + 选项保存成功. + + + Download completion + 下载完成 + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + 一些文件正在传输中. +您确定要退出qBittorrent吗? + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + 总上传速度限制 + + + Global Download Speed Limit + 总下载速度限制 + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (下载: %2/s, 上传: %3/s) + + + Recursive download confirmation + 循环下载确认 + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent%1包含torrent文件,您想继续下载吗? + + + Torrent file association + 结合torrent文件 + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent不是打开torrent文件或Magnet链接的默认应用程序. +您想用qBittorrent打开torrent文件或Magnet链接吗? + + + Transfers (%1) + 传输(%1) + + + Yes + + + + No + + + + Never + 从不 + + + Always + 一直 + + + Exiting qBittorrent + 正在退出qBittorrent + + + Set the password... + 设置密码... + + + Password update + 更新密码 + + + The UI lock password has been successfully updated + 锁定用户界面的密码已成功更新 + + + UI lock password + 锁定用户界面的密码 + + + Please type the UI lock password: + 请输入用于锁定用户界面的密码 + + + Invalid password + 无效密码 + + + The password is invalid + 该密码无效 + + + A newer version is available + 新版本可用 + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Sourceforge上有更新版本的qBittorrent. +您想将qBittorrent更新到版本%1吗? + + + Impossible to update qBittorrent + 无法更新qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent更新失败, 原因:%1 + + + + GeoIP + + Australia + 澳大利亚 + + + Argentina + 阿根廷 + + + Austria + 奥地利 + + + United Arab Emirates + 阿拉伯联合酋长国 + + + Brazil + 巴西 + + + Bulgaria + 保加利亚 + + + Belarus + 白俄罗斯 + + + Belgium + 比利时 + + + Bosnia + 波斯尼亚 + + + Canada + 加拿大 + + + Czech Republic + 捷克共和国 + + + China + 中国 + + + Costa Rica + 哥斯达黎加 + + + Switzerland + 瑞士 + + + Germany + 德国 + + + Denmark + 丹麦 + + + Algeria + 阿尔及利亚 + + + Spain + 西班牙 + + + Egypt + 埃及 + + + Finland + 芬兰 + + + France + 法国 + + + United Kingdom + 英国 + + + Greece + 希腊 + + + Georgia + 格鲁吉亚 + + + Hungary + 匈牙利 + + + Croatia + 克罗地亚 + + + Italy + 意大利 + + + India + 印度 + + + Israel + 以色列 + + + Ireland + 爱尔兰 + + + Iceland + 冰岛 + + + Indonesia + 印度尼西亚 + + + Japan + 日本 + + + South Korea + 韩国 + + + Luxembourg + 卢森堡 + + + Malaysia + 马来西亚 + + + Mexico + 墨西哥 + + + Serbia + 塞尔维亚 + + + Morocco + 摩洛哥 + + + Netherlands + 荷兰 + + + Norway + 挪威 + + + New Zealand + 新西兰 + + + Portugal + 葡萄牙 + + + Poland + 波兰 + + + Pakistan + 巴基斯坦 + + + Philippines + 菲律宾 + + + Russia + 俄罗斯 + + + Romania + 罗马尼亚 + + + France (Reunion Island) + 法国(留尼旺岛) + + + Sweden + 瑞典 + + + Slovakia + 斯洛伐克 + + + Singapore + 新加坡 + + + Slovenia + 斯洛文尼亚 + + + Taiwan + 台湾 + + + Turkey + 土耳其 + + + Thailand + 泰国 + + + USA + 美国 + + + Ukraine + 乌克兰 + + + South Africa + 南非 + + + Saudi Arabia + 沙特阿拉伯 + + + + HeadlessLoader + + Information + 信息 + + + To control qBittorrent, access the Web UI at http://localhost:%1 + 进入Web用户界面 http://localhost:%1以控制qBittorrent + + + The Web UI administrator user name is: %1 + Web用户界面管理员为%1 + + + The Web UI administrator password is still the default one: %1 + Web用户界面管理员密码仍为默认值:%1 + + + This is a security risk, please consider changing your password from program preferences. + 有安全风险,请考虑在程序首选项更改密码. + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + 由于过多的身份验证失败,您的IP地址被禁止. + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + 下载:%1/s -传输:%2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + 上传:%1/s -传输:%2 + + + + HttpServer + + File + 文件 + + + Edit + 编辑 + + + Help + 帮助 + + + Delete from HD + 从硬盘删除 + + + Download Torrents from their URL or Magnet link + 从URL或MAGNET连接下载Torrents + + + Only one link per line + 每行仅可有一连接 + + + Download + 下载 + + + Download local torrent + 下载本地torrent + + + Torrent files were correctly added to download list. + Torrent文件正确添加到下载列表. + + + Point to torrent file + 指向torrent文件 + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + 您确定要从传输列表和硬盘中删除选中的torrent吗? + + + Download rate limit must be greater than 0 or disabled. + 下载速度限制必须大于0或禁用. + + + Upload rate limit must be greater than 0 or disabled. + 上传速度限制必须大于0或禁用. + + + Maximum number of connections limit must be greater than 0 or disabled. + 最大连接数限制必须大于0或禁用. + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + 每torrent最大连接数限制必须大于0或禁用. + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + 每torrent最大上传通道数限制必须大于0或禁用. + + + Unable to save program preferences, qBittorrent is probably unreachable. + 无法保存程序偏好选项,qBttorrent也许无法达到. + + + Language + 语言 + + + The port used for incoming connections must be greater than 1024 and less than 65535. + 用于对内连接的端口必须大于1024且小于65535. + + + The port used for the Web UI must be greater than 1024 and less than 65535. + 用于Web用户界面的端口必须大于1024且小于65535. + + + The Web UI username must be at least 3 characters long. + Web界面用户名长度最少为3个字符. + + + The Web UI password must be at least 3 characters long. + Web用户界面密码长度最少为3个字符. + + + Downloaded + Is the file downloaded or not? + 已下载 + + + Save + 保存 + + + qBittorrent client is not reachable + 无法访问qBittorrent客户端 + + + HTTP Server + HTTP 服务器 + + + Torrent path + Torrent 路径 + + + Torrent name + Torrent 名称 + + + The following parameters are supported: + 支持以下参数: + + + + LegalNotice + + Legal Notice + 法律声明 + + + Legal notice + 法律声明 + + + Cancel + 取消 + + + I Agree + 同意 + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent是一个分享文件程序.当您运行一个torrent时,其数据可通过上传形式被他人获得.您对您分享的任何内容承担全部责任. + + + Press %1 key to accept and continue... + 按%1键接受并继续... + + + + LineEdit + + Clear the text + 清除文本 + + + + MainWindow + + &Edit + &编辑 + + + &File + &文件 + + + &Help + &帮助 + + + Preview file + 预览文件 + + + Clear log + 清除日志 + + + Decrease priority + 降低优先 + + + Increase priority + 增加优先 + + + &Tools + 工具 + + + &View + 视图 + + + &Add File... + 添加文件... + + + E&xit + 退出 + + + &Options... + 选项... + + + Add &URL... + 添加URL... + + + Torrent &creator + Torrent创建者 + + + Set upload limit... + 设定上传限制... + + + Set download limit... + 设定下载限制... + + + Set global download limit... + 设定总下载限制... + + + Set global upload limit... + 设定总上传限制... + + + &Log viewer... + 日志浏览器... + + + Top &tool bar + 顶部工具栏 + + + Display top tool bar + 显示顶部工具栏 + + + &Speed in title bar + 标题栏中显示速度 + + + Show transfer speed in title bar + 标题栏中显示传输速度 + + + Alternative speed limits + 其他速度限制 + + + &About + 关于 + + + &Pause + 暂停 + + + &Delete + 删除 + + + P&ause All + 暂停所有 + + + Visit &Website + 浏览网站 + + + Report a &bug + 报告错误 + + + &Documentation + 文档资料 + + + &RSS reader + RSS阅读器 + + + Search &engine + 搜索引擎 + + + Log viewer + 日志浏览器 + + + Lock qBittorrent + 锁定qBittorrent + + + Ctrl+L + Ctrl+L + + + Shutdown computer when downloads complete + 下载完毕后关闭电脑 + + + &Resume + 重新开始 + + + R&esume All + 重新开始所有 + + + Shutdown qBittorrent when downloads complete + 更新完毕后关闭qBittorrent + + + Exit + 退出 + + + Import torrent... + 导入torrent... + + + Donate money + 捐赠钱款 + + + If you like qBittorrent, please donate! + 如果您喜欢qBittorrent, 请捐款! + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + 设置密码... + + + Transfers + 传输 + + + Torrent file association + 结合torrent文件 + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent不是打开torrent文件或Magnet链接的默认应用程序. +您想用qBittorrent打开torrent文件或Magnet链接吗? + + + UI lock password + 锁定用户界面的密码 + + + Please type the UI lock password: + 请输入用于锁定用户界面的密码 + + + Password update + 更新密码 + + + The UI lock password has been successfully updated + 锁定用户界面的密码已成功更新 + + + RSS + RSS + + + Search + 搜索 + + + Transfers (%1) + 传输(%1) + + + Download completion + 下载完成 + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + '%1'下载完毕. + + + I/O Error + i.e: Input/Output Error + 输入/输出错误 + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + torrent %1 出现输入/输出错误. +原因: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + 循环下载确认 + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent%1包含torrent文件,您想继续下载吗? + + + Yes + + + + No + + + + Never + 从不 + + + Url download error + 网址下载错误 + + + Couldn't download file at url: %1, reason: %2. + 无法在网址:%1下载文件,原因:%2. + + + Global Upload Speed Limit + 总上传速度限制 + + + Global Download Speed Limit + 总下载速度限制 + + + Invalid password + 无效密码 + + + The password is invalid + 该密码无效 + + + Exiting qBittorrent + 正在退出qBittorrent + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + 一些文件正在传输中. +您确定要退出qBittorrent吗? + + + Always + 一直 + + + Open Torrent Files + 打开Torrent文件 + + + Torrent Files + Torrent文件 + + + Options were saved successfully. + 选项保存成功. + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + 下载速度: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + 上传速度: %1 KiB/s + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (下载: %2/s, 上传: %3/s) + + + A newer version is available + 新版本可用 + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Sourceforge上有较新版本的qBittorrent. +您想将qBittorrent更新到版本%1吗? + + + Impossible to update qBittorrent + 无法更新qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent更新失败, 原因:%1 + + + &Add torrent file... + 添加torrent文件... + + + Add &link to torrent... + 向torrent添加链接... + + + Import existing torrent... + 导出现有的torrent... + + + Execution &Log + 执行日志 + + + Execution Log + 执行日志 + + + Auto-Shutdown on downloads completion + 下载完毕后自动关闭 + + + Exit qBittorrent + 退出qBittorrent + + + Suspend system + 休眠系统 + + + Shutdown system + 关闭系统 + + + Disabled + 禁用 + + + The password should contain at least 3 characters + 密码应包含至少三个字符 + + + + PeerAdditionDlg + + Invalid IP + 无效IP + + + The IP you provided is invalid. + 您提供的IP无效. + + + + PeerListDelegate + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + 用户 + + + Progress + i.e: % downloaded + 进度 + + + Down Speed + i.e: Download speed + 下载速度 + + + Up Speed + i.e: Upload speed + 上传速度 + + + Downloaded + i.e: total data downloaded + 已下载 + + + Uploaded + i.e: total data uploaded + 已上传 + + + Ban peer permanently + 永久禁止用户 + + + Peer addition + 用户添加 + + + The peer was added to this torrent. + 该用户已添加到此torrent. + + + The peer could not be added to this torrent. + 该用户无法添加到此torrent. + + + Are you sure? -- qBittorrent + 确定? -- qBittorrent + + + Are you sure you want to ban permanently the selected peers? + 您确定要永久禁止被选中的用户吗? + + + &Yes + &是 + + + &No + &否 + + + Manually banning peer %1... + 手动禁止用户%1... + + + Upload rate limiting + 上传速度限制 + + + Download rate limiting + 下载速度限制 + + + Add a new peer... + 添加新用户 + + + Limit download rate... + 限制下载速度... + + + Limit upload rate... + 限制上传速度... + + + Copy IP + 复制IP + + + Connection + 连接 + + + + Preferences + + UI + User Interface + 用户界面 + + + Downloads + 下载 + + + Connection + 连接 + + + Bittorrent + Bittorrent + + + Proxy + 代理服务器 + + + Web UI + 网络操作界面 + + + Language: + 语言: + + + (Requires restart) + (需要重启) + + + Visual style: + 视觉外观: + + + Transfer list + 传输列表 + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + 使用交替的行颜色 + + + File system + 文件系统 + + + Torrent queueing + Torrent排队 + + + Maximum active downloads: + 使激活的下载最大化: + + + Maximum active uploads: + 使激活的上传最大化: + + + Maximum active torrents: + 使激活的torrents最大化: + + + When adding a torrent + 添加torrent时 + + + Display torrent content and some options + 显示torrent内容及选项 + + + Listening port + 侦听端口 + + + Port used for incoming connections: + 用于对内连接的端口: + + + Random + 随机 + + + Enable UPnP port mapping + 启用UPnP端口映射 + + + Enable NAT-PMP port mapping + 启用NAT-PMP端口映射 + + + Connections limit + 连接限度 + + + Global maximum number of connections: + 总最大连接数: + + + Maximum number of connections per torrent: + 每torrent最大连接数: + + + Maximum number of upload slots per torrent: + 每torrent上传位置最大值: + + + Upload: + 上传: + + + Download: + 下载: + + + KiB/s + KiB/s + + + Bittorrent features + Bittorrent 功能 + + + Enable DHT network (decentralized) + 启用DHT网络(无服务器) + + + Use a different port for DHT and Bittorrent + DHT和Bittorrent使用不同端口 + + + DHT port: + DHT端口: + + + Enable Peer Exchange / PeX (requires restart) + 启用资源PeX(需要重启) + + + Enable Local Peer Discovery + 启用本地资源搜索 + + + Enabled + 启用 + + + Forced + 强制 + + + Disabled + 禁用 + + + Type: + 类型: + + + (None) + (无) + + + HTTP + HTTP + + + Port: + 端口: + + + Authentication + 验证 + + + Username: + 用户名: + + + Password: + 密码: + + + SOCKS5 + SOCKS5 + + + HTTP Server + HTTP 服务器 + + + Filter path (.dat, .p2p, .p2b): + 过滤器路径(.dat, .p2p, .p2b): + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP通讯(跟踪器,网络种子,搜索引擎) + + + Host: + IP: + + + Peer Communications + 用户通讯 + + + SOCKS4 + SOCKS4 + + + Speed + 速度 + + + Global speed limits + 总速度限制 + + + Alternative global speed limits + 供选择的总速度限制 + + + to + time1 to time2 + + + + Every day + 每天 + + + Week days + 工作日 + + + Week ends + 休息日 + + + Advanced + 高级 + + + Copy .torrent files to: + 复制.torrent文件到: + + + Remove folder + 移除文件夹 + + + No action + 无行动 + + + Options + 选项 + + + Visual Appearance + 视觉外观 + + + Action on double-click + 双击执行活动 + + + Downloading torrents: + 正在下载torrents: + + + Start / Stop + 开始 / 结束 + + + Open destination folder + 打开目标文件夹 + + + Completed torrents: + 完成的torrents: + + + Desktop + 桌面 + + + Show splash screen on start up + 启动时显示程序启动画面 + + + Start qBittorrent minimized + 开始时使qBittorrent最小化 + + + Show qBittorrent icon in notification area + 在通知区域显示qBittorrent图标 + + + Minimize qBittorrent to notification area + 最小化qBittorrent到通知区域 + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + 关闭qBittorrent到通知区域 + + + Do not start the download automatically + The torrent will be added to download list in pause state + 不要自动开始下载 + + + Save files to location: + 保存文件到: + + + Append the label of the torrent to the save path + 在保存路径附加torrent的标签 + + + Pre-allocate disk space for all files + 为所有文件预分配磁盘空间 + + + Keep incomplete torrents in: + 保存未完成的torrents到: + + + Append .!qB extension to incomplete files' names + 给未完成文件附加扩展名.!qB + + + Automatically add torrents from: + 自动从此处添加torrents: + + + Add folder... + 添加文件夹... + + + IP Filtering + IP过滤中 + + + Schedule the use of alternative speed limits + 为替代速度限制的使用安排时间 + + + from + from (time1 to time2) + + + + When: + 时间: + + + Look for peers on your local network + 在本地网络上寻找资源 + + + Protocol encryption: + 加密协定: + + + Enable Web User Interface (Remote control) + 启用网络用户界面(远程控制) + + + Share ratio limiting + 分享率限制中 + + + Seed torrents until their ratio reaches + 分享torrents直至达到比率 + + + then + 然后 + + + Pause them + 暂停它们 + + + Remove them + 移除它们 + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + 与兼容的Bittorrent客户端交换资源(µTorrent, Vuze, ...) + + + Email notification upon download completion + 下载完成时邮件通知 + + + Destination email: + 目标电子邮件: + + + SMTP server: + SMTP服务器: + + + Run an external program on torrent completion + torrent完成时运行外部程序 + + + Use %f to pass the torrent path in parameters + 使用%f在参数中传输torrent路径 + + + Proxy server + 代理服务器 + + + BitTorrent + BitTorrent + + + Start / Stop Torrent + 开始 / 停止Torrent + + + Use UPnP / NAT-PMP port forwarding from my router + 使用UPnP / NAT-PMP端口从路由器转发 + + + Privacy + 隐私 + + + Enable DHT (decentralized network) to find more peers + 启用DHT (无服务器网络) 以获取更多的资源 + + + Use a different port for DHT and BitTorrent + DHT和Bittorrent使用不同端口 + + + Enable Peer Exchange (PeX) to find more peers + 启用同行交换 (PeX) 以获取更多资源 + + + Enable Local Peer Discovery to find more peers + 启用本地资源搜索以获取更多资源 + + + Encryption mode: + 加密模式: + + + Prefer encryption + 偏好加密 + + + Require encryption + 命令加密 + + + Disable encryption + 禁用加密 + + + User Interface + 用户界面 + + + Reload the filter + 重载过滤器 + + + Behavior + 行为 + + + Language + 语言 + + + Power Management + 电源管理 + + + Inhibit system sleep when torrents are active + 当torrent激活时禁止系统休眠 + + + Bypass authentication for localhost + 绕过对本地主机的验证 + + + Ask for program exit confirmation + 请求程序退出确认 + + + Use monochrome system tray icon (requires restart) + 使用单色系统托盘图标(需重启) + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + 支持以下参数: +<ul> +<li>%f: Torrent 路径</li> +<li>%n: Torrent 名称</li> +</ul> + + + Tray icon style: + 托盘图标样式: + + + Normal + 正常 + + + Monochrome (Dark theme) + 单色 (深色主题) + + + Monochrome (Light theme) + 单色 (浅色主题) + + + This server requires a secure connection (SSL) + 该服务器需要安全链接 (SSL) + + + User Interface Language: + 用户界面语言: + + + Transfer List + 传输列表 + + + Show qBittorrent in notification area + 在通知区域显示qBittorrent + + + Hard Disk + 硬盘 + + + Listening Port + 侦听端口 + + + Connections Limits + 连接限度 + + + Proxy Server + 代理服务器 + + + Torrent Queueing + Torrent排队 + + + Share Ratio Limiting + 分享率限制 + + + Use UPnP / NAT-PMP to forward the port from my router + 使用UPnP / NAT-PMP 从路由器转发转发端口 + + + Update my dynamic domain name + 更新我的动态域名 + + + Service: + 服务: + + + Register + 注册 + + + Domain name: + 域名: + + + Global Rate Limits + 总速度限制 + + + Apply rate limit to uTP connections + 应用速度限制于 uTP 连接 + + + Apply rate limit to transport overhead + 应用速度限制于传送总开销 + + + Alternative Global Rate Limits + 可替代的总速度限制 + + + Schedule the use of alternative rate limits + 预定可替代的速度限制的使用时间 + + + Enable bandwidth management (uTP) + 启用宽带管理 (uTP) + + + Otherwise, the proxy server is only used for tracker connections + 否则, 代理服务器将仅用于tracker连接 + + + Use proxy for peer connections + 使用代理服务器进行对等连接 + + + Append .!qB extension to incomplete files + 为不完整的文件添加扩展名 .!qB + + + Use HTTPS instead of HTTP + 用 HTTPS 取代 HTTP + + + Import SSL Certificate + 导入 SSL 证书 + + + Import SSL Key + 导入 SSL 密匙 + + + Certificate: + 证书: + + + Key: + 密匙: + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + + PreviewSelect + + Name + 名称 + + + Size + 大小 + + + Progress + 进度 + + + Preview impossible + 无法预览 + + + Sorry, we can't preview this file + 抱歉, 此文件无法被预览 + + + + ProgramUpdater + + Could not create the file %1 + 无法创建文件%1 + + + Failed to download the update at %1 + %1 is an URL + 在%1下载更新失败 + + + + PropListDelegate + + Normal + Normal (priority) + 正常 + + + High + High (priority) + + + + Maximum + Maximum (priority) + 最大 + + + Not downloaded + 未下载 + + + Mixed + Mixed (priorities + 混合的 + + + + PropTabBar + + General + 普通 + + + Trackers + Trackers + + + Peers + 用户 + + + URL Seeds + 网址种子 + + + Files + 文件 + + + HTTP Sources + HTTP 源 + + + Content + 内容 + + + + PropertiesWidget + + Save path: + 保存路径: + + + Torrent hash: + Torrent哈西值: + + + Comment: + 注释: + + + Share ratio: + 分享率: + + + General + 普通 + + + Trackers + Trackers + + + URL seeds + 网址种子 + + + Files + 文件 + + + Priority + 优先 + + + New url seed + New HTTP source + 新网址种子 + + + New url seed: + 新网址种子: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + 该网址种子已在列表中. + + + Choose save path + 选择保存路径 + + + Save path creation error + 创建保存路径时出现错误 + + + Could not create the save path + 无法创建保存路径 + + + Downloaded: + 已下载: + + + Transfer + 传输 + + + Uploaded: + 已上传: + + + Wasted: + 已丢弃: + + + UP limit: + 上传限制: + + + DL limit: + 下载限制: + + + Time elapsed: + 用时: + + + Connections: + 连接: + + + Information + 信息 + + + Created on: + 创建于: + + + Peers + 用户 + + + Normal + 正常 + + + Maximum + 最大 + + + High + + + + this session + 此次会话 + + + %1 max + e.g. 10 max + %1最大 + + + Availability: + 可用性: + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + 已做种%1 + + + Rename... + 重命名... + + + New name: + 新名: + + + The file could not be renamed + 文件不能被重命名 + + + This name is already in use in this folder. Please use a different name. + 该名称已被使用,请重新命名. + + + The folder could not be renamed + 文件夹不能被重命名 + + + Rename the file + 重命名文件 + + + This file name contains forbidden characters, please choose a different one. + 该文件名包含被禁止符号,请重新命名. + + + I/O Error + 输入/输出错误 + + + This file does not exist yet. + 该文件尚未存在. + + + This folder does not exist yet. + 该文件夹尚未存在. + + + Reannounce in: + 再次连接时间: + + + Select All + 选择所有 + + + Select None + 全不选 + + + Do not download + 不下载 + + + Pieces size: + 文件块大小: + + + Time active: + Time (duration) the torrent is active (not paused) + 有效时间: + + + Torrent content: + Torrent内容: + + + + QBtSession + + %1 reached the maximum ratio you set. + '%1'达到您设置的最大比率. + + + Removing torrent %1... + 正在移除torrent%1... + + + Pausing torrent %1... + 正在暂停torrent%1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent 绑定端口: TCP/%1 + + + UPnP support [ON] + UPnP 支持[开] + + + UPnP support [OFF] + UPnP 支持[关] + + + NAT-PMP support [ON] + NAT-PMP 支持[开] + + + NAT-PMP support [OFF] + NAT-PMP 支持[关] + + + HTTP user agent is %1 + HTTP用户代理是%1 + + + Using a disk cache size of %1 MiB + 使用%1:MiB磁盘高速缓存 + + + DHT support [ON], port: UDP/%1 + DHT 支持 [开], 端口: UDP/%1 + + + DHT support [OFF] + DHT 支持[关] + + + PeX support [ON] + PeX 支持[ON] + + + PeX support [OFF] + PeX 支持[关] + + + Restart is required to toggle PeX support + 更改PeX支持状态需要重启 + + + Local Peer Discovery [ON] + 本地资源搜索[开] + + + Local Peer Discovery support [OFF] + 本地资源搜索支持[关] + + + Encryption support [ON] + 加密支持[开] + + + Encryption support [FORCED] + 加密支持[强制] + + + Encryption support [OFF] + 加密支持[关] + + + Embedded Tracker [ON] + 嵌入式Tracker [开] + + + Failed to start the embedded tracker! + 无法启动嵌入式tracker! + + + Embedded Tracker [OFF] + 嵌入式Tracker [关] + + + The Web UI is listening on port %1 + Web用户界面在侦听端口%1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + 网络用户界面错误-无法绑定网络用户界面到端口%1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1'从传输列表及硬盘被移除. + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1'从传输列表被移除. + + + '%1' is not a valid magnet URI. + %1不是有效的MAGNET链接. + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1'已存在于下载列表中. + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1'重新开始. (快速) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1'已添加到下载列表. + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + 无法解码torrent文件:'%1' + + + This file is either corrupted or this isn't a torrent. + 该文件不是torrent文件或已经损坏. + + + Error: The torrent %1 does not contain any file. + 错误:torrent%1不包含任何内容. + + + Note: new trackers were added to the existing torrent. + 注意:新跟踪器被添加到现有的torrent. + + + Note: new URL seeds were added to the existing torrent. + 注意:新URL种子被添加到现有的torrent. + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>被您的IP过滤器阻止</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>因损坏的碎片被禁止</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + 循环下载包含在torrent%2中的文件%1 + + + Unable to decode %1 torrent file. + 无法解码%1torrent文件. + + + Torrent name: %1 + Torrent名称:%1 + + + Torrent size: %1 + Torrent大小:%1 + + + Save path: %1 + 保存路径:%1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + 该torrent下载用时为%1. + + + Thank you for using qBittorrent. + 感谢您使用qBittorrent. + + + [qBittorrent] %1 has finished downloading + [qBittorrent] %1下载完毕. + + + An I/O error occured, '%1' paused. + 出现输入/输出错误,'%1'暂停. + + + Reason: %1 + 原因: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: 端口映射失败, 消息: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: 端口映射成功, 消息: %1 + + + File sizes mismatch for torrent %1, pausing it. + 文件大小与torrent%1不匹配,暂停中. + + + Fast resume data was rejected for torrent %1, checking again... + 快速继续数据torrent %1失败,再次检查... + + + Url seed lookup failed for url: %1, message: %2 + 找不到网址种子:%1, 消息:%2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + '%1'下载中,请等待... + + + The network interface defined is invalid: %1 + 网络界面定义无效:%1 + + + Trying any other network interface available instead. + 请尝试其他可用的网络界面作替代 + + + Listening on IP address %1 on network interface %2... + 侦听网络界面%2上的IP地址%1... + + + Failed to listen on network interface %1 + 无法侦听网络界面%1 + + + UPnP / NAT-PMP support [ON] + UPnP / NAT-PMP 支持 [开] + + + UPnP / NAT-PMP support [OFF] + UPnP / NAT-PMP 支持 [关] + + + Local Peer Discovery support [ON] + 本地资源搜索支持[开] + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + 解析提供的IP过滤器成功: %1 规则被应用 + + + Error: Failed to parse the provided IP filter. + 错误: 无法解析提供的IP过滤器 + + + Reporting IP address %1 to trackers... + 向追踪器报告IP地址%1... + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + 如果您15秒内不取消电脑将进入休眠模式... + + + The computer will now be switched off unless you cancel within the next 15 seconds... + 如果您15秒内不取消电脑将被关闭... + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + 如果您15秒内不取消qBitorrent将退出... + + + + RSS + + Search + 搜索 + + + Delete + 删除 + + + Rename + 重命名 + + + Refresh RSS streams + 重新载入RSS资源 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrent:</span> <span style=" font-style:italic;">(双击进行下载)</span></p></body></html> + + + Download torrent + 下载torrent + + + Open news URL + 打开新闻URL + + + Copy feed URL + 复制文件URL + + + New subscription + 新RSS文件 + + + Mark items read + 标记项目为已读 + + + Update all + 更新所有 + + + Update all feeds + 更新所有文件 + + + RSS feeds + RSS文件 + + + Update + 更新 + + + Feed URL + 文件URL + + + Article title + 文章标题 + + + Rename... + 重命名... + + + New subscription... + 新RSS文件... + + + RSS feed downloader... + RSS源下载器 + + + New folder... + 新文件夹... + + + Manage cookies... + 管理cookies... + + + Settings... + 设置... + + + RSS Downloader... + RSS下载器... + + + + RSSImp + + Please type a rss stream url + + + + Stream URL: + 网址资源: + + + Are you sure? -- qBittorrent + 确定? -- qBittorrent + + + &Yes + &是 + + + &No + &否 + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + 该RSS消息种子已在列表中. + + + Date: + 日期: + + + Author: + 作者: + + + Please choose a folder name + 请选择文件夹名 + + + Folder name: + 文件夹名: + + + New folder + 新文件夹 + + + Are you sure you want to delete these elements from the list? + 确定要从列表中删除这些项吗? + + + Are you sure you want to delete this element from the list? + 确定要从列表中删除此项吗? + + + Please choose a new name for this RSS feed + 请命名该RSS文件 + + + New feed name: + 新文件名: + + + Name already in use + 名称已被使用 + + + This name is already used by another item, please choose another one. + 该名称已被另一项目使用,请重新选择. + + + Overwrite attempt + 企图覆盖 + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + 您不能覆盖%1项目. + + + Unread + 未读 + + + + RssArticle + + No description available + 无可用描述 + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + 自动下载%2RSS文件中的%1torrent... + + + + RssItem + + No description available + 无可用描述 + + + + RssSettings + + RSS Reader Settings + RSS阅读器设置 + + + RSS feeds refresh interval: + RSS消息源刷新间隔: + + + minutes + 分钟 + + + Maximum number of articles per feed: + 每个订阅源文章数目最大值: + + + + RssSettingsDlg + + RSS Reader Settings + RSS阅读器设置 + + + RSS feeds refresh interval: + RSS消息源刷新间隔: + + + minutes + 分钟 + + + Maximum number of articles per feed: + 每个订阅源文章数目最大值: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + 自动下载%2RSS文件中的%1torrent... + + + + ScanFoldersModel + + Watched Folder + 监控文件夹 + + + Download here + 下载到这里 + + + + SearchCategories + + All categories + 所有类别 + + + Movies + 电影 + + + TV shows + 电视节目 + + + Music + 音乐 + + + Games + 游戏 + + + Anime + 动漫 + + + Software + 软件 + + + Pictures + 图片 + + + Books + 书籍 + + + + SearchEngine + + Empty search pattern + 无搜索关键词 + + + Please type a search pattern first + 请先输入关键词 + + + Results + 结果 + + + Searching... + 搜索中... + + + Cut + 剪切 + + + Copy + 复制 + + + Paste + 粘贴 + + + Clear field + 清除信息 + + + Clear completion history + 清除搜索历史 + + + Search Engine + 搜索引擎 + + + Search has finished + 搜索完毕 + + + An error occured during search... + 搜索中出现错误... + + + Search aborted + 搜索失败 + + + Search returned no results + 搜索无结果 + + + Results + i.e: Search results + 结果 + + + Unknown + 未知 + + + Search + 搜索 + + + Download error + 下载错误 + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + 不能下载Python安装程序,原因:%1. +请手动安装. + + + Missing Python Interpreter + 缺少Python解释器 + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + 需要Python 2.x以使用搜索引擎但未被安装. +您想现在安装吗? + + + Confirmation + 确认 + + + Are you sure you want to clear the history? + 您确定要清楚历史记录吗? + + + + SearchTab + + Name + i.e: file name + 名称 + + + Size + i.e: file size + 大小 + + + Seeders + i.e: Number of full sources + 完整种子 + + + Leechers + i.e: Number of partial sources + 不完整种子 + + + Search engine + 搜索引擎 + + + + ShutdownConfirmDlg + + Shutdown confirmation + 确认关闭 + + + + SpeedLimitDialog + + KiB/s + KiB/s + + + + StatusBar + + Connection status: + 连接状态: + + + No direct connections. This may indicate network configuration problems. + 无直接连接.这也许指示网络设置问题. + + + DHT: %1 nodes + DHT: %1 结点 + + + Connection Status: + 连接状态: + + + Online + 联机 + + + Global Download Speed Limit + 总下载速度限制 + + + Global Upload Speed Limit + 总上传速度限制 + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + 下载:%1/s -传输:%2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + 上传:%1/s -传输:%2 + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + 下载:%1B/s -传输:%2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + 上传:%1B/s -传输:%2 + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + 脱机.通常意味着qBittorrent侦听对内连接的端口失败. + + + Click to disable alternative speed limits + 点击以禁用其他速度限制 + + + Click to enable alternative speed limits + 点击以启用其他速度限制 + + + qBittorrent needs to be restarted + 需要重启qBittorrent + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent刚刚被更新需要重启使改动生效. + + + Click to switch to alternative speed limits + 点击以切换到其他速度限制 + + + Click to switch to regular speed limits + 点击以切换到常规速度限制 + + + %1/s + Per second + %1/s + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + 选择加入torrent的文件夹 + + + Select a file to add to the torrent + 选择加入到torrent的文件 + + + Please type an announce URL + 请输入一个announce网址 + + + Announce URL: + Tracker URL + Announce网址: + + + Please type a web seed url + 请输入一个网络种子网址 + + + Web seed URL: + 网络种子网址: + + + No input path set + 未设置输入路径 + + + Please type an input path first + 请先给出输入路径 + + + Select destination torrent file + 选择目标torrent文件 + + + Torrent Files + Torrent文件 + + + Torrent creation + 创建Torrent + + + Torrent creation was unsuccessful, reason: %1 + 创建Torrent失败,原因:%1 + + + Created torrent file is invalid. It won't be added to download list. + 创建的torrent文件无效.它将不会被添加到下载列表中. + + + Torrent was created successfully: + 成功创建Torrent: + + + + TorrentFilesModel + + Name + 名称 + + + Size + 大小 + + + Progress + 进度 + + + Priority + 优先 + + + + TorrentImportDlg + + Torrent Import + Torrent导入 + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + 该助手将帮助您与qBittorrent分享您已下载的torrent. + + + Torrent file to import: + 要导入的torrent文件: + + + ... + ... + + + Content location: + 内容位置: + + + Skip the data checking stage and start seeding immediately + 跳过数据检查立即开始做种 + + + Import + 导入 + + + Torrent file to import + 要导入的torrent文件 + + + Torrent files (*.torrent) + Torrent文件 (*.torrent) + + + %1 Files + %1 is a file extension (e.g. PDF) + %1文件 + + + Please provide the location of %1 + %1 is a file name + 请提供%1的位置 + + + Please point to the location of the torrent: %1 + 请指向torrent的位置:%1 + + + Invalid torrent file + 无效torrent文件 + + + This is not a valid torrent file. + 这不是有效的torrent文件. + + + + TorrentModel + + Name + i.e: torrent name + 名称 + + + Size + i.e: torrent size + 大小 + + + Done + % Done + 结束 + + + Status + Torrent status (e.g. downloading, seeding, paused) + 状态 + + + Seeds + i.e. full sources (often untranslated) + 完整种子 + + + Peers + i.e. partial sources (often untranslated) + 用户 + + + Down Speed + i.e: Download speed + 下载速度 + + + Up Speed + i.e: Upload speed + 上传速度 + + + Ratio + Share ratio + 比率 + + + ETA + i.e: Estimated Time of Arrival / Time left + 剩余时间 + + + Label + 标签 + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + 添加于 + + + Completed On + Torrent was completed on 01/01/2010 08:00 + 完成于 + + + Tracker + Tracker + + + Down Limit + i.e: Download limit + 下载限制 + + + Up Limit + i.e: Upload limit + 上传限制 + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + 下载总量 + + + Amount left + Amount of data left to download (e.g. in MB) + 剩余总量 + + + Time Active + Time (duration) the torrent is active (not paused) + 有效时间 + + + + TrackerList + + URL + 网址 + + + Status + 状态 + + + Peers + 用户 + + + Message + 消息 + + + [DHT] + [DHT] + + + Working + 工作 + + + Disabled + 禁用 + + + This torrent is private + 此Torrent是非公开的 + + + Updating... + 更新中... + + + Not working + 未工作 + + + Not contacted yet + 未联系 + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Add a new tracker... + 添加新tracker... + + + Remove tracker + 移除tracker + + + Force reannounce + 强制再次连接 + + + + TrackersAdditionDlg + + Trackers addition dialog + 添加trackers对话窗 + + + List of trackers to add (one per line): + 要添加的trackers列表(每行一个): + + + µTorrent compatible list URL: + µTorrent兼容的URL列表: + + + I/O Error + 输入/输出错误 + + + Error while trying to open the downloaded file. + 打开已下载文件时出错. + + + No change + 无变化 + + + No additional trackers were found. + 未找到另外的trackers. + + + Download error + 下载错误 + + + The trackers list could not be downloaded, reason: %1 + 无法下载trackers列表,原因:%1 + + + + TransferListDelegate + + Downloading + 下载中 + + + Paused + 暂停 + + + Queued + i.e. torrent is queued + 列队 + + + Seeding + Torrent is complete and in upload-only mode + 正在做种 + + + Stalled + Torrent is waiting for download to begin + 等待 + + + Checking + Torrent local data is being checked + 检查中 + + + /s + /second (.i.e per second) + /s + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + Seeded for %1 + e.g. Seeded for 3m10s + 已做种%1 + + + + TransferListFiltersWidget + + All + 所有 + + + Downloading + 下载中 + + + Completed + 完成 + + + Active + 启用 + + + Inactive + 未启用 + + + All labels + 所有标签 + + + Unlabeled + 无标签 + + + Remove label + 删除标签 + + + New Label + 新标签 + + + Label: + 标签: + + + Invalid label name + 无效标签名 + + + Please don't use any special characters in the label name. + 请不要在标签名中使用特殊符号. + + + Paused + 暂停 + + + Add label... + 添加标签... + + + Resume torrents + 重新开始torrent + + + Pause torrents + 暂停torrent + + + Delete torrents + 删除torrent + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + 剩余时间 + + + Column visibility + 是否显示列 + + + Open destination folder + 打开目标文件夹 + + + Force recheck + 强制再次核对 + + + Copy magnet link + 复制MAGNET链接 + + + Down Speed + i.e: Download speed + 下载速度 + + + Up Speed + i.e: Upload speed + 上传速度 + + + Name + i.e: torrent name + 名称 + + + Size + i.e: torrent size + 大小 + + + Done + % Done + 结束 + + + Status + Torrent status (e.g. downloading, seeding, paused) + 状态 + + + Seeds + i.e. full sources (often untranslated) + 完整种子 + + + Peers + i.e. partial sources (often untranslated) + 用户 + + + Ratio + Share ratio + 比率 + + + Torrent Download Speed Limiting + Torrent下载速度限制 + + + Torrent Upload Speed Limiting + Torrent上传速度限制 + + + Super seeding mode + 超级做种模式 + + + Download in sequential order + 以连续顺序下载 + + + Download first and last piece first + 先下载首尾段 + + + Label + 标签 + + + New Label + 新标签 + + + Label: + 标签: + + + New... + New label... + 新... + + + Reset + Reset label + 重置 + + + Rename + 重命名 + + + New name: + 新名: + + + Rename... + 重命名... + + + Invalid label name + 无效标签名 + + + Please don't use any special characters in the label name. + 请不要在标签名中使用特殊符号. + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + 添加于 + + + Completed On + Torrent was completed on 01/01/2010 08:00 + 完成于 + + + Down Limit + i.e: Download limit + 下载限制 + + + Up Limit + i.e: Upload limit + 上传限制 + + + Choose save path + 选择保存路径 + + + Save path creation error + 创建保存路径时出现错误 + + + Could not create the save path + 无法创建保存路径 + + + Set location... + 设定地区 + + + Preview file... + 预览文件... + + + Limit upload rate... + 限制上传速度... + + + Limit download rate... + 限制下载速度... + + + Move up + i.e. move up in the queue + 上移 + + + Move down + i.e. Move down in the queue + 下移 + + + Move to top + i.e. Move to top of the queue + 移至顶部 + + + Move to bottom + i.e. Move to bottom of the queue + 移至底部 + + + Priority + 优先 + + + Resume + Resume/start the torrent + 重新开始 + + + Pause + Pause the torrent + 暂停 + + + Delete + Delete the torrent + 删除 + + + Limit share ratio... + 限制分享率... + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + Torrent上传/下载率限制 + + + Use global ratio limit + 使用总比率限制 + + + buttonGroup + 按键组 + + + Set no ratio limit + 不设比率限制 + + + Set ratio limit to + 设比率限制为 + + + + UsageDisplay + + Usage: + 用途: + + + displays program version + 显示程序版本 + + + disable splash screen + 禁用程序启动画面 + + + displays this help message + 显示该帮助消息 + + + changes the webui port (current: %1) + 更改网络用户界面端口(current: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [文件或urls]:下载用户批准的torrents (可选) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + 感谢以下所有qBittorrent的志愿翻译者: + + + Please contact me if you would like to translate qBittorrent into your own language. + 如果你想为qBittorrent提供翻译请与我联系. + + + + addPeerDialog + + Peer addition + 用户添加 + + + IP + IP + + + Port + 端口 + + + + addTorrentDialog + + Torrent addition dialog + 添加Torrent对话窗 + + + Save path: + 保存路径: + + + ... + ... + + + Torrent content: + Torrent内容: + + + Add to download list in paused state + 以暂停状态添加到下载列表中 + + + Add + 添加 + + + Cancel + 取消 + + + Normal + 正常 + + + High + + + + Maximum + 最大 + + + Torrent size: + Torrent大小: + + + Unknown + 未知 + + + Free disk space: + 可用磁盘空间: + + + Download in sequential order (slower but good for previewing) + 按顺序下载(速度有所减慢但利于预览) + + + Skip file checking and start seeding immediately + 跳过文件检查立即开始做种 + + + Label: + 标签: + + + Select All + 选择所有 + + + Select None + 全不选 + + + Do not download + 不下载 + + + + authentication + + Tracker authentication + Tracker验证 + + + Tracker: + Tracker: + + + Login + 登录 + + + Username: + 用户名: + + + Password: + 密码: + + + Log in + 登入 + + + Cancel + 取消 + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + 确认删除-qBttorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + 您确定要从传输列表中删除选中的torrent吗? + + + Remember choice + 记住选择 + + + Also delete the files on the hard disk + 同时从硬盘上删除文件 + + + + createTorrentDialog + + Cancel + 取消 + + + Torrent Creation Tool + Torrent创建工具 + + + Torrent file creation + 创建Torrent文件 + + + Announce urls (trackers): + Announce网址(trackers): + + + Comment (optional): + 注释(可选): + + + Web seeds urls (optional): + 网络种子网址(可选): + + + File or folder to add to the torrent: + 加入torrent的文件或文件夹: + + + Piece size: + 文件块大小: + + + 32 KiB + 32 KiB + + + 64 KiB + 64 KiB + + + 128 KiB + 128 KiB + + + 256 KiB + 256 KiB + + + 512 KiB + 512 KiB + + + 1 MiB + 1 MiB + + + 2 MiB + 2 MiB + + + 4 MiB + 4 MiB + + + Start seeding after creation + 创建后开始做种 + + + Create and save... + 创建并保存... + + + Private (won't be distributed on DHT network if enabled) + 私人(不共享到DHT网络如启用) + + + Progress: + 进度: + + + Add file + 添加文件 + + + Add folder + 添加文件夹 + + + Tracker URLs: + Tracker网址: + + + Web seeds urls: + 网络种子网址: + + + Comment: + 注释: + + + Auto + 自动 + + + + createtorrent + + Select destination torrent file + 选择torrent文件目的地 + + + Torrent Files + Torrent文件 + + + No input path set + 未设置输入路径 + + + Please type an input path first + 请先给出输入路径 + + + Torrent creation + 创建Torrent + + + Torrent was created successfully: + 成功创建Torrent: + + + Select a folder to add to the torrent + 选择加入torrent的文件夹 + + + Please type an announce URL + 请输入一个announce网址 + + + Torrent creation was unsuccessful, reason: %1 + 创建Torrent失败,原因:%1 + + + Announce URL: + Tracker URL + Announce网址: + + + Please type a web seed url + 请输入一个网络种子网址 + + + Web seed URL: + 网络种子网址: + + + Select a file to add to the torrent + 选择加入到torrent的文件 + + + Created torrent file is invalid. It won't be added to download list. + 创建的torrent文件无效.它将不会被添加到下载列表中. + + + + downloadFromURL + + Download Torrents from URLs + 从URL下载Torrents + + + Only one URL per line + 每行仅可有一URL + + + Download + 下载 + + + Cancel + 取消 + + + Download from urls + 从URL下载 + + + No URL entered + 未输入URL + + + Please type at least one URL. + 请至少输入一个URL. + + + Add torrent links + 添加torrent链接 + + + Both HTTP and Magnet links are supported + 支持HTTP和Magnetl链接 + + + + downloadThread + + I/O Error + 输入/输出错误 + + + The remote host name was not found (invalid hostname) + 远端主机名未找到(无效主机名) + + + The operation was canceled + 操作被取消 + + + The remote server closed the connection prematurely, before the entire reply was received and processed + 远端服务器在接到和处理完整回复前过早关闭连接 + + + The connection to the remote server timed out + 连接远端伺服器超时 + + + SSL/TLS handshake failed + SSL/TLS握手失败 + + + The remote server refused the connection + 远端服务器拒绝连接 + + + The connection to the proxy server was refused + 连接到代理服务器被拒绝 + + + The proxy server closed the connection prematurely + 代理服务器过早关闭连接 + + + The proxy host name was not found + 未找到代理主机名 + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + 连接到代理服务器超时或代理服务器未及时回复请求 + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + 为了执行要求,代理服务器需要认证但不接受任何提供的凭证 + + + The access to the remote content was denied (401) + 读取远端内容被拒绝(401) + + + The operation requested on the remote content is not permitted + 对于远端内容请求的操作未被允许 + + + The remote content was not found at the server (404) + 内容在远端伺服器上未找到(404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + 为了提供内容,远端伺服器需要认证但不接受任何提供的凭证 + + + The Network Access API cannot honor the request because the protocol is not known + 未知协议 + + + The requested operation is invalid for this protocol + 请求的操作对该协议无效 + + + An unknown network-related error was detected + 检测到未知的关于局域网的错误 + + + An unknown proxy-related error was detected + 检测到未知的关于代理服务器的错误 + + + An unknown error related to the remote content was detected + 检测到未知的关于远端内容的错误 + + + A breakdown in protocol was detected + 检测到协议故障 + + + Unknown error + 未知错误 + + + + engineSelect + + Search plugins + 搜索插件 + + + Installed search engines: + 搜索引擎已安装: + + + Name + 名称 + + + Url + 网址 + + + Enabled + 启用 + + + Install a new one + 安装新一个 + + + Check for updates + 检查更新 + + + Close + 关闭 + + + Enable + 启用 + + + Disable + 禁用 + + + Uninstall + 卸载 + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + 您可以在这里获得新的搜索引擎:<a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + engineSelectDlg + + Uninstall warning + 卸载警告 + + + Uninstall success + 卸载成功 + + + Select search plugins + 选择搜索插件 + + + qBittorrent search plugins + qBittorrent搜索插件 + + + Search plugin install + 安装搜索插件 + + + qBittorrent + qBittorrent + + + Search plugin update + 更新搜索插件 + + + Sorry, update server is temporarily unavailable. + 对不起, +更新服务器暂时不可用. + + + All your plugins are already up to date. + 所有的插件已是最新的. + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1搜索引擎插件不能被安装. + + + All selected plugins were uninstalled successfully + 所有选中的插件已成功卸载 + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1搜索引擎插件已成功更新. + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1搜索引擎插件已成功安装. + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + 对不起, %1搜索插件安装失败. + + + New search engine plugin URL + 新搜索引擎插件网址 + + + URL: + 网址: + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + 一些插件由于被包括在qBittorrent内不能被卸载. + 只有由您添加的插件可以被卸载然而, 那些插件被禁用. + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + 更新版本的%1搜索引擎插件已安装. + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1搜索引擎插件不能被更新,保留旧版本. + + + Yes + + + + No + + + + + misc + + B + bytes + + + + KiB + kibibytes (1024 bytes) + + + + MiB + mebibytes (1024 kibibytes) + + + + GiB + gibibytes (1024 mibibytes) + + + + TiB + tebibytes (1024 gibibytes) + + + + Unknown + 未知 + + + Unknown + Unknown (size) + 未知 + + + < 1m + < 1 minute + < 1分钟 + + + %1m + e.g: 10minutes + %1分钟 + + + %1h %2m + e.g: 3hours 5minutes + %1小时%2分钟 + + + %1d %2h + e.g: 2days 10hours + %1天%2小时 + + + qBittorrent will shutdown the computer now because all downloads are complete. + 所有下载已完成,qBittorrent即将关闭电脑 + + + + options_imp + + Choose a save directory + 保存到 + + + Choose an ip filter file + 选择ip过滤文件 + + + Filters + 过滤器 + + + Choose export directory + 选择导出目录 + + + Add directory to scan + 添加监视目录 + + + Folder is already being watched. + 文件夹已被监视. + + + Folder does not exist. + 文件夹不存在. + + + Folder is not readable. + 文件夹不可读. + + + Failure + 失败 + + + Failed to add Scan Folder '%1': %2 + 添加监视文件夹 '%1失败:%2 + + + Parsing error + 解析错误 + + + Failed to parse the provided IP filter + 无法解析提供的IP过滤器 + + + Succesfully refreshed + 刷新成功 + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + 解析提供的IP过滤器成功: %1 规则被应用 + + + Successfully refreshed + 刷新成功 + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + Invalid key + + + + This is not a valid SSL key. + + + + Invalid certificate + + + + This is not a valid SSL certificate. + + + + + pluginSourceDlg + + Plugin source + 插件来源 + + + Search plugin source: + 搜索插件来源: + + + Local file + 本地文件 + + + Web link + 网络连接 + + + + preview + + Preview selection + 选择要预览的文件 + + + File preview + 文件预览 + + + Preview + 预览 + + + Cancel + 取消 + + + The following files support previewing, <br>please select one of them: + 下列文件支持预览,<br>请选择其一: + + + + previewSelect + + Preview impossible + 无法预览 + + + Sorry, we can't preview this file + 抱歉, 此文件无法被预览 + + + Name + 名称 + + + Size + 大小 + + + Progress + 进度 + + + + search_engine + + Search + 搜索 + + + Status: + 状态: + + + Stopped + 停止 + + + Download + 下载 + + + Search engines... + 搜索引擎... + + + Go to description page + 跳至描述页 + + + + torrentAdditionDialog + + Unable to decode torrent file: + 无法解码torrent文件: + + + Choose save path + 选择保存路径 + + + Empty save path + 保存路径为空 + + + Please enter a save path + 请输入一个保存路径 + + + Save path creation error + 创建保存路径时出现错误 + + + Could not create the save path + 无法创建保存路径 + + + Invalid file selection + 所选文件无效 + + + You must select at least one file in the torrent + 至少选择一个torrent文件 + + + Priority + 优先 + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (torrent下载后剩余%1) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (另需%1以完成下载) + + + Seeding mode error + 做种模式错误 + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + 您选择跳过检查.但本地文件不在当前目标文件夹.请停用此功能或更新保存路径. + + + Rename... + 重命名... + + + New name: + 新名: + + + The file could not be renamed + 文件不能被重命名 + + + This name is already in use in this folder. Please use a different name. + 该名称已被使用,请重新命名. + + + The folder could not be renamed + 文件夹不能被重命名 + + + Rename the file + 重命名文件 + + + Unable to decode magnet link: + 无法解码magnet链接: + + + Magnet Link + Magnet链接 + + + Invalid label name + 无效标签名 + + + Please don't use any special characters in the label name. + 请不要在标签名中使用特殊符号. + + + This file name contains forbidden characters, please choose a different one. + 该文件名包含被禁止符号,请重新命名. + + + diff --git a/src/lang/qbittorrent_zh_TW.qm b/src/lang/qbittorrent_zh_TW.qm new file mode 100644 index 0000000000000000000000000000000000000000..890843f269a9699c9a7816ea09b238ea6d334806 GIT binary patch literal 89245 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 + + + + AboutDlg + + About qBittorrent + 關於 qBittorrent + + + About + 關於 + + + Author + 作者 + + + Name: + 姓名: + + + Country: + 國籍: + + + E-mail: + E-mail: + + + Christophe Dumez + Christophe Dumez + + + France + 法國 + + + Translation + 翻譯 + + + License + 授權 + + + <h3><b>qBittorrent</b></h3> + <h3><b>qBittorrent</b></h3> + + + chris@qbittorrent.org + chris@qbittorrent.org + + + Thanks to + 感謝 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">A Bittorrent client programmed in C++, based on Qt4 toolkit </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">and libtorrent-rasterbar. <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">一個使用 C++ 編寫, 基於 QT4 的 Bittorrent 客戶端 </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">以及 libtorrent-rasterbar。 <br /><br />Copyright ©2006-2010 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">首頁:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">論壇:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" text-decoration: underline; color:#0000ff;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">An advanced BitTorrent client programmed in C++, based on Qt4 toolkit and libtorrent-rasterbar. <br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Home Page:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Forum:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans';">一個使用 C++ 編寫, 基於 QT4 以及 libtorrent-rasterbar 的 Bittorrent 客戶端。<br /><br />Copyright ©2006-2011 Christophe Dumez<br /><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">首頁:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://www.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://www.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">Bug Tracker:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://bugs.qbittorrent.org"><span style=" text-decoration: underline; color:#0057ae;">http://bugs.qbittorrent.org</span></a><span style=" font-family:'DejaVu Sans';"><br /></span><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">論壇:</span><span style=" font-family:'DejaVu Sans';"> </span><a href="http://forum.qbittorrent.org"><span style=" font-family:'Sans'; text-decoration: underline; color:#0057ae;">http://forum.qbittorrent.org</span></a></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; text-decoration: underline;">IRC:</span><span style=" font-family:'DejaVu Sans';"> #qbittorrent on Freenode</span></p></body></html> + + + + AdvancedSettings + + Property + 屬性 + + + Value + + + + Ignore transfer limits on local network + 忽略本地網路的傳輸限制 + + + Include TCP/IP overhead in transfer limits + 將 TCP/IP 加載包含於傳輸限制中 + + + Disk write cache size + 磁碟寫入快取大小 + + + MiB + MiB + + + Outgoing ports (Min) [0: Disabled] + 連出埠 (最小) [0: 停用] + + + Outgoing ports (Max) [0: Disabled] + 連出埠 (最大) [0: 停用] + + + Recheck torrents on completion + 完成後重新檢查 torrent + + + Transfer list refresh interval + 傳輸清單更新間隔 + + + ms + milliseconds + ms + + + Resolve peer countries (GeoIP) + 解析下載者的國家 (GeoIP) + + + Resolve peer host names + 解析下載者的主機名 + + + Maximum number of half-open connections [0: Disabled] + 最大半開啟連線數 [0: 停用] + + + Strict super seeding + 嚴格超級種子 + + + Network Interface (requires restart) + 網路介面 (需要重新啟動) + + + Any interface + i.e. Any network interface + 任何介面 + + + Display program notification baloons + 顯示程式通知氣球 + + + Display program notification balloons + 顯示程式通知氣球 + + + Enable embedded tracker + 啟用嵌入 tracker + + + Embedded tracker port + 嵌入 tracker 埠 + + + Check for software updates + 檢查軟體更新 + + + Use system icon theme + 使用系統圖示佈景 + + + Confirm torrent deletion + 確認 torrent 刪除 + + + IP Address to report to trackers (requires restart) + 回報至 tracker 的 IP 地址 (需要重新啟動) + + + Display program on-screen notifications + 顯示程式通知 + + + Setting + 設定 + + + Value + Value set for this setting + + + + Exchange trackers with other peers + + + + + AutomatedRssDownloader + + Automated RSS Downloader + 自動 RSS 下載器 + + + Enable the automated RSS downloader + 啟用自動 RSS 下載器 + + + Download rules + 下載規則 + + + Rule definition + 規則定義 + + + Must contain: + 必須包含: + + + Must not contain: + 必須不包含: + + + ... + ... + + + Assign label: + 指定標籤: + + + Apply rule to feeds: + 套用規則到 feed: + + + Matching RSS articles + 配對 RSS 文章 + + + Save to a different directory + 儲存到其他的目錄 + + + Save to: + 儲存至: + + + Import... + 匯入... + + + Export... + 匯出... + + + + New rule name + 新原則名稱 + + + Please type the name of the new download rule. + 請輸入新下載規則的名稱。 + + + Rule name conflict + 原則名稱衝突 + + + A rule with this name already exists, please choose another name. + 此原則名稱已存在, 請選擇另一個名稱。 + + + Are you sure you want to remove the download rule named %1? + 你確定要刪除下載原則 %1 嗎? + + + Are you sure you want to remove the selected download rules? + 你確定要移除所選的下載原則嗎? + + + Rule deletion confirmation + 規則刪除確認 + + + Destination directory + 目的地目錄 + + + Invalid action + 無效的行動 + + + The list is empty, there is nothing to export. + 清單是空白的, 不會匯出任何東西。 + + + Where would you like to save the list? + 你想要將清單儲存到哪裡? + + + Rules list (*.rssrules) + 規則清單 (*.rssrules) + + + I/O Error + I/O 錯誤 + + + Failed to create the destination file + 無法建立目的檔案 + + + Please point to the RSS download rules file + 請指定 RSS 下載規則檔案 + + + Rules list (*.rssrules *.filters) + 規則清單 (*.rssrules, *.filters) + + + Import Error + 匯入錯誤 + + + Failed to import the selected rules file + 匯入選擇的規則檔案失敗 + + + Add new rule... + 增加新規則... + + + Delete rule + 刪除規則 + + + Rename rule... + 重新命名規則... + + + Delete selected rules + 刪除所選的規則 + + + Rule renaming + 重新命名規則 + + + Please type the new rule name + 請輸入新規則檔案的名稱 + + + Use regular expressions + 使用正規表示法 + + + Regex mode: use Perl-like regular expressions + 正規表示法模式: 使用類 Perl 的正規表示法 + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>Whitespaces count as AND operators</li></ul> + 萬用字元模式: 你可以使用<ul><li>? 來配對任何單一字元</li><li>* 來配對零或多個字元</li><li>空白視為 "和" 運算子</li></ul> + + + Wildcard mode: you can use<ul><li>? to match any single character</li><li>* to match zero or more of any characters</li><li>| is used as OR operator</li></ul> + 萬用字元模式: 你可以使用<ul><li>? 來配對任何單一字元</li><li>* 來配對零或多個字元</li><li>| 視為 "或" 運算子</li></ul> + + + + Bittorrent + + %1 reached the maximum ratio you set. + %1 已經到達你設定的最大比率了。 + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent 綁定埠: TCP/%1 + + + UPnP support [ON] + UPnP 支援 [開啟] + + + UPnP support [OFF] + UPnP 支援 [關閉] + + + NAT-PMP support [ON] + NAT-PMP 支援 [開啟] + + + NAT-PMP support [OFF] + NAT-PMP 支援 [關閉] + + + DHT support [ON], port: UDP/%1 + DHT 支援 [開啟], 埠: UDP/%1 + + + DHT support [OFF] + DHT 支援 [關閉] + + + PeX support [ON] + PeX 支援 [開啟] + + + Local Peer Discovery [ON] + 本地下載者搜尋 [開啟] + + + Local Peer Discovery support [OFF] + 本地下載者搜尋支援 [關閉] + + + Encryption support [ON] + 加密支援 [開啟] + + + Encryption support [FORCED] + 加密支援 [強迫] + + + Encryption support [OFF] + 加密支援 [關閉] + + + Web User Interface Error - Unable to bind Web UI to port %1 + Web UI 錯誤 - 無法綁定 Web UI 到埠 %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' 已經從傳輸清單和硬碟中刪除了。 + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' 已經從傳輸清單中刪除了。 + + + '%1' is not a valid magnet URI. + '%1' 不是一個有效的磁性 URI。 + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' 已經在下載清單裡了。 + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' 已恢復下載。(快速恢復) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' 已增加到下載清單。 + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + 無法解碼 torrent 檔案: '%1' + + + This file is either corrupted or this isn't a torrent. + 這個檔案不是損壞就是並非 torrent。 + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>因為你的 IP 過濾器而被封鎖了</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>因為有損壞的分塊而被踢出</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + 遞迴下載在 torrent %2 裡的檔案 %1 + + + Unable to decode %1 torrent file. + 無法解碼 torrent 檔案 %1 。 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: 埠映射失敗, 訊息: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: 埠映射成功, 訊息: %1 + + + Fast resume data was rejected for torrent %1, checking again... + 快速恢復資料被 torrent %1 拒絕, 重新檢查... + + + Url seed lookup failed for url: %1, message: %2 + 找不到 URL: %1 的 URL 種子, 訊息: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + 下載 '%1' 中, 請稍候... + + + Using a disk cache size of %1 MiB + 使用磁碟快取大小為 %1 MiB + + + PeX support [OFF] + PeX 支援 [關閉] + + + Restart is required to toggle PeX support + 切換 PeX 支援需重新啟動 + + + The Web UI is listening on port %1 + Web UI 監聽的埠為: %1 + + + HTTP user agent is %1 + HTTP 使用者代理是: %1 + + + Reason: %1 + 原因: %1 + + + Note: new trackers were added to the existing torrent. + 備註: 新 tracker 已增加到現有的 torrent 中。 + + + Note: new URL seeds were added to the existing torrent. + 備註: URL 種子已增加到現有 torrent 中。 + + + An I/O error occured, '%1' paused. + 發生 I/O 錯誤, '%1' 已暫停。 + + + Removing torrent %1... + 移除 torrent %1... + + + Pausing torrent %1... + 暫停 torrent %1... + + + Error: The torrent %1 does not contain any file. + 錯誤: Torrent %1 沒有包含任何檔案。 + + + File sizes mismatch for torrent %1, pausing it. + 檔案大小和 torrent %1 不合, 暫停。 + + + Torrent name: %1 + Torrent 名稱: %1 + + + Torrent size: %1 + Torrent 大小: %1 + + + Save path: %1 + 儲存路徑: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent 已於 %1 下載完成。 + + + Thank you for using qBittorrent. + 感謝您使用 qBittorrent。 + + + [qBittorrent] %1 has finished downloading + [qBittorrent] 已下載完成 %1 + + + + ConsoleDlg + + General + 一般 + + + Blocked IPs + 被封鎖的 IP + + + qBittorrent log viewer + qBittorrent 紀錄檢視器 + + + + CookiesDlg + + Cookies management + Cookie 管理 + + + Key + As in Key/Value pair + + + + Value + As in Key/Value pair + + + + Common keys for cookies are : '%1', '%2'. +You should get this information from your Web browser preferences. + Cookie 的常見值為: '%1', '%2'。 +你可從網路瀏覽器的偏好設定中取得這些資訊。 + + + + DNSUpdater + + Your dynamic DNS was successfuly updated. + 你的動態 DNS 更新成功。 + + + Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes. + 動態 DNS 錯誤: 服務暫時無法使用, 將在 30 分鐘後重試。 + + + Dynamic DNS error: hostname supplied does not exist under specified account. + 動態 DNS 錯誤: 提供的主機名稱在指定的帳號下不存在。 + + + Dynamic DNS error: Invalid username/password. + 動態 DNS 錯誤: 無效的使用者名稱/密碼。 + + + Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org. + 動態 DNS 錯誤: qBittorrent 被此服務封鎖了, 請回報此問題至 http://bugs.qbittorrent.org。 + + + Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org. + 動態 DNS 錯誤: %1 被此服務退回, 請回報此問題至 http://bugs.qbittorrent.org。 + + + Dynamic DNS error: Your username was blocked due to abuse. + 動態 DNS 錯誤: 你的使用者名稱因濫用而被封鎖。 + + + Dynamic DNS error: supplied domain name is invalid. + 動態 DNS 錯誤: 提供的領域名稱是無效的。 + + + Dynamic DNS error: supplied username is too short. + 動態 DNS 錯誤: 提供的使用者名稱太短。 + + + Dynamic DNS error: supplied password is too short. + 動態 DNS 錯誤: 提供的密碼太短。 + + + + DownloadThread + + I/O Error + I/O 錯誤 + + + The remote host name was not found (invalid hostname) + 找不到遠端主機的名稱 (無效的主機名) + + + The operation was canceled + 操作已取消 + + + The remote server closed the connection prematurely, before the entire reply was received and processed + 在回應被接收及處理之前遠端伺服器已永遠關閉連線 + + + The connection to the remote server timed out + 連線到遠端伺服器逾時 + + + SSL/TLS handshake failed + SSL/TLS 握手失敗 + + + The remote server refused the connection + 遠端伺服器拒絕連線 + + + The connection to the proxy server was refused + 連線到代理伺服器被拒絕 + + + The proxy server closed the connection prematurely + 代理伺服器永遠關閉連線 + + + The proxy host name was not found + 找不到代理伺服器主機名 + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + 連線到代理伺服器逾時或是在要求的時間中沒有回應 + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + 為了執行要求, 代理伺服器需要認證但是不接受任何提供的憑證 + + + The access to the remote content was denied (401) + 存取遠端內容被拒絕 (401) + + + The operation requested on the remote content is not permitted + 對遠端內容要求的操作不被允許 + + + The remote content was not found at the server (404) + 遠端內容在伺服器上找不到 (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + 為了提供內容, 遠端代理伺服器需要認證, 但是不接受所提供的憑證 + + + The Network Access API cannot honor the request because the protocol is not known + 因為未知的協定, 網路存取 API 無法執行要求 + + + The requested operation is invalid for this protocol + 要求的操作對於此協定是無效的 + + + An unknown network-related error was detected + 偵測到一個未知的網路相關錯誤 + + + An unknown proxy-related error was detected + 偵測到一個未知的代理伺服器相關錯誤 + + + An unknown error related to the remote content was detected + 偵測到一個未知的遠端內容相關錯誤 + + + A breakdown in protocol was detected + 偵測到一個協定錯誤 + + + Unknown error + 未知的錯誤 + + + + EventManager + + %1/s + e.g. 120 KiB/s + %1/s + + + Working + 有效 + + + Updating... + 更新中... + + + Not working + 無效 + + + Not contacted yet + 尚未連接 + + + this session + 此作業階段 + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + 已做種 %1 + + + %1 max + e.g. 10 max + 最大 %1 + + + + ExecutionLog + + Form + 形式 + + + General + 一般 + + + Blocked IPs + 被封鎖的 IP + + + + FeedDownloader + + RSS Feed downloader + RSS feed 下載器 + + + RSS feed: + RSS feed: + + + Feed name + feed 名稱 + + + Automatically download torrents from this feed + 自動從這個feed 下載 torrent + + + Download filters + 下載過濾器 + + + Filters: + 過濾器: + + + Filter settings + 過濾器設定 + + + Matches: + 符合: + + + Does not match: + 不符合: + + + Destination folder: + 目的地資料夾: + + + ... + ... + + + Filter testing + 過濾器測試 + + + Torrent title: + torrent 標題: + + + Result: + 結果: + + + Test + 測試 + + + Import... + 匯入... + + + Export... + 匯出... + + + + Rename filter + 重新命名過濾器 + + + Remove filter + 移除過濾器 + + + Add filter + 增加過濾器 + + + + FeedDownloaderDlg + + New filter + 新過濾器 + + + Please choose a name for this filter + 請為此過濾器取一個名稱 + + + Filter name: + 過濾器名稱: + + + Invalid filter name + 無效的過濾器名稱 + + + The filter name cannot be left empty. + 過濾器名稱不可以空白。 + + + This filter name is already in use. + 此過濾器名稱已使用。 + + + Filter testing error + 過濾器測試錯誤 + + + Please specify a test torrent name. + 請指定一個測試的 torrent 名稱。 + + + matches + 符合 + + + does not match + 不符合 + + + Select file to import + 選擇匯入的檔案 + + + Filters Files + 過濾器檔案 + + + Import successful + 匯入成功 + + + Filters import was successful. + 匯入過濾器成功。 + + + Import failure + 匯入失敗 + + + Filters could not be imported due to an I/O error. + 因 I/O 錯誤導致過濾器不能匯入。 + + + Select destination file + 選擇目的地檔案 + + + Export successful + 匯出成功 + + + Filters export was successful. + 過濾器匯出成功。 + + + Export failure + 匯出失敗 + + + Filters could not be exported due to an I/O error. + 因 I/O 錯誤導致過濾器不能匯出。 + + + Choose save path + 選擇儲存路徑 + + + + FeedList + + Unread + 未讀 + + + + FeedListWidget + + RSS feeds + RSS feeds + + + Unread + 未讀 + + + + GUI + + Open Torrent Files + 開啟 torrent 檔案 + + + Torrent Files + torrent 檔案 + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + 下載速度: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + 上傳速度: %1 KiB/s + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 已經下載完成。 + + + I/O Error + i.e: Input/Output Error + I/O 錯誤 + + + Search + 搜尋 + + + RSS + RSS + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Torrent %1 發生了 I/O 錯誤。 +原因: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Url download error + URL 下載錯誤 + + + Couldn't download file at url: %1, reason: %2. + 無法從 URL: %1 下載檔案, 原因: %2。 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Options were saved successfully. + 選項儲存成功。 + + + Transfers + 傳輸 + + + Download completion + 下載完成 + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + 有些檔案還在傳輸中。 +你確定要退出 qBittorrent 嗎? + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Global Upload Speed Limit + 全域上傳速度限制 + + + Global Download Speed Limit + 全域下載速度限制 + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (下載速度: %2/s, 上傳速度: %3/s) + + + Recursive download confirmation + 遞迴下載確認 + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent %1 包含 torrent 檔案, 你想要執行下載作業嗎? + + + Torrent file association + Torrent 檔案關聯 + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent 不是你開啟 torrent 檔案或磁性連結的預設程式。 +你想要以 qBittorrent 開啟 torrent 檔案和磁性連結嗎? + + + Transfers (%1) + 傳輸 (%1) + + + Yes + + + + No + + + + Never + 從不 + + + Always + 總是 + + + Exiting qBittorrent + 退出 qBittorrent + + + Set the password... + 設定密碼... + + + Password update + 更新密碼 + + + The UI lock password has been successfully updated + UI 鎖定密碼已經更新了 + + + UI lock password + UI 鎖定密碼 + + + Please type the UI lock password: + 請輸入 UI 鎖定密碼: + + + Invalid password + 無效的密碼 + + + The password is invalid + 密碼是無效的 + + + A newer version is available + 有新版本可以取得 + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Sourceforge 上有 qBittorrent 的新版本。 +你想要更新 qBittorrent 的版本到 %1 嗎? + + + Impossible to update qBittorrent + 不可能更新 qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent 更新失敗, 原因: %1 + + + + GeoIP + + Australia + 澳洲 + + + Argentina + 阿根廷 + + + Austria + 奧地利 + + + United Arab Emirates + 阿拉伯聯合大公國 + + + Brazil + 巴西 + + + Bulgaria + 保加利亞 + + + Belarus + 白俄羅斯 + + + Belgium + 比利時 + + + Bosnia + 波士尼亞 + + + Canada + 加拿大 + + + Czech Republic + 捷克 + + + China + 中國 + + + Costa Rica + 哥斯大黎加 + + + Switzerland + 瑞士 + + + Germany + 德國 + + + Denmark + 丹麥 + + + Algeria + 阿爾及利亞 + + + Spain + 西班牙 + + + Egypt + 埃及 + + + Finland + 芬蘭 + + + France + 法國 + + + United Kingdom + 英國 + + + Greece + 希臘 + + + Georgia + 喬治亞 + + + Hungary + 匈牙利 + + + Croatia + 克羅埃西亞 + + + Italy + 義大利 + + + India + 印度 + + + Israel + 以色列 + + + Ireland + 愛爾蘭 + + + Iceland + 冰島 + + + Indonesia + 印尼 + + + Japan + 日本 + + + South Korea + 南韓 + + + Luxembourg + 盧森堡 + + + Malaysia + 馬來西亞 + + + Mexico + 墨西哥 + + + Serbia + 塞爾維亞 + + + Morocco + 摩洛哥 + + + Netherlands + 荷蘭 + + + Norway + 挪威 + + + New Zealand + 紐西蘭 + + + Portugal + 葡萄牙 + + + Poland + 波蘭 + + + Pakistan + 巴基斯坦 + + + Philippines + 菲律賓 + + + Russia + 俄國 + + + Romania + 羅馬尼亞 + + + France (Reunion Island) + 法國 (留尼旺島) + + + Sweden + 瑞典 + + + Slovakia + 斯洛伐克 + + + Singapore + 新加坡 + + + Slovenia + 斯洛維尼亞 + + + Taiwan + 臺灣 + + + Turkey + 土耳其 + + + Thailand + 泰國 + + + USA + 美國 + + + Ukraine + 烏克蘭 + + + South Africa + 南非 + + + Saudi Arabia + 沙烏地阿拉伯 + + + + HeadlessLoader + + Information + 資訊 + + + To control qBittorrent, access the Web UI at http://localhost:%1 + 要控制 qBittorrent, 從 http://localhost:%1 存取 Web UI + + + The Web UI administrator user name is: %1 + Web UI 管理者名稱是: %1 + + + The Web UI administrator password is still the default one: %1 + Web UI 管理者密碼仍是預設的: %1 + + + This is a security risk, please consider changing your password from program preferences. + 這有安全性風險, 請考慮從程式偏好設定更改你的密碼。 + + + + HttpConnection + + Your IP address has been banned after too many failed authentication attempts. + 經過多次授權要求失敗之後, 你的 IP 已經被封鎖了。 + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + 下載速度: %1/s - 已傳輸: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + 上傳速度: %1/s - 已傳輸: %2 + + + + HttpServer + + File + 檔案 + + + Edit + 編輯 + + + Help + 幫助 + + + Delete from HD + 從硬碟刪除 + + + Download Torrents from their URL or Magnet link + 從他們的 URL 或磁性連結下載 torrent + + + Only one link per line + 一線僅一連結 + + + Download + 下載 + + + Download local torrent + 下載本地 torrent + + + Torrent files were correctly added to download list. + Torrent 檔案已正確地加到下載清單中。 + + + Point to torrent file + 指向 torrent 檔案 + + + Are you sure you want to delete the selected torrents from the transfer list and hard disk? + 你確定要從傳輸清單及硬碟裡刪除所選擇的 torrent 嗎? + + + Download rate limit must be greater than 0 or disabled. + 下載速度限制必須大於 0 或停用。 + + + Upload rate limit must be greater than 0 or disabled. + 上傳速度限制必須大於 0 或停用。 + + + Maximum number of connections limit must be greater than 0 or disabled. + 最大連線數限制必須大於 0 或停用。 + + + Maximum number of connections per torrent limit must be greater than 0 or disabled. + 每個 torrent 的最大下載者連線數限制必須大於 0 或停用。 + + + Maximum number of upload slots per torrent limit must be greater than 0 or disabled. + 每個 torrent 上傳位置的最大數限制必須大於 0 或停用。 + + + Unable to save program preferences, qBittorrent is probably unreachable. + 無法儲存程式偏好設定, qBittorrent 可能無法連線。 + + + Language + 語言 + + + The port used for incoming connections must be greater than 1024 and less than 65535. + 進來連線的埠號必須大於 1024 且小於 65535。 + + + The port used for the Web UI must be greater than 1024 and less than 65535. + Web UI 使用的負號必須大於 1024 且小於 65535。 + + + The Web UI username must be at least 3 characters long. + Web UI 使用者名稱必須至少 3 字元長。 + + + The Web UI password must be at least 3 characters long. + Web UI 密碼必須至少 3 字元長。 + + + Downloaded + Is the file downloaded or not? + 已下載 + + + Save + 儲存 + + + qBittorrent client is not reachable + 連接不到 qBittorrent 客戶端 + + + HTTP Server + HTTP 伺服器 + + + Torrent path + torrent 路徑 + + + Torrent name + torrent 名稱 + + + The following parameters are supported: + 支援以下的參數: + + + + LegalNotice + + Legal Notice + 法律聲明 + + + Legal notice + 法律聲明 + + + Cancel + 取消 + + + I Agree + 我同意 + + + qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility. + +No further notices will be issued. + qBittorrent 是一個檔案分享程式。當你執行一個 torrent 時, 它的資料會上傳給其他人。所以, 你分享的任何內容, 你都負有完全的責任。 + +之後不會再有其他提醒。 + + + Press %1 key to accept and continue... + 請按 %1 來接受並繼續... + + + + LineEdit + + Clear the text + 清除文字 + + + + MainWindow + + &Edit + 編輯(&E) + + + &File + 檔案(&F) + + + &Help + 幫助(&H) + + + Preview file + 預覽檔案 + + + Clear log + 清除紀錄 + + + Decrease priority + 降低優先度 + + + Increase priority + 增加優先度 + + + &Tools + 工具 (&T) + + + &View + 檢視 (&V) + + + &Add File... + 增加檔案 (&A)... + + + E&xit + 離開 (&X) + + + &Options... + 選項 (&O)... + + + Add &URL... + 增加 &URL... + + + Torrent &creator + Torrent 建立器 (&C) + + + Set upload limit... + 設定上傳限制... + + + Set download limit... + 設定下載限制... + + + Set global download limit... + 設定全域下載限制... + + + Set global upload limit... + 設定全域上傳限制... + + + &Log viewer... + 紀錄檢視器 (&L)... + + + Top &tool bar + 最上方的工具列 (&T) + + + Display top tool bar + 顯示最上方的工具列 + + + &Speed in title bar + 在標題列顯示速度 (&S) + + + Show transfer speed in title bar + 在標題列顯示傳輸速度 + + + Alternative speed limits + 額外的速度限制 + + + &About + 關於 (&A) + + + &Pause + 暫停 (&P) + + + &Delete + (&D)刪除 + + + P&ause All + 全部暫停 (&A) + + + Visit &Website + 瀏覽網站 (&W) + + + Report a &bug + 回報錯誤 (&B) + + + &Documentation + 文件 (&D) + + + &RSS reader + &RSS 閱讀器 + + + Search &engine + 搜尋引擎 (&E) + + + Log viewer + 紀錄檢視器 + + + Lock qBittorrent + 鎖定 qBittorrent + + + Ctrl+L + Ctrl+L + + + Shutdown computer when downloads complete + 當下載結束後將電腦關機 + + + &Resume + 繼續 (&R) + + + R&esume All + 全部繼續 (&E) + + + Shutdown qBittorrent when downloads complete + 當下載完成後關閉 qBittorrent + + + Exit + 離開 + + + Import torrent... + 匯入 torrent... + + + Donate money + 捐獻金錢 + + + If you like qBittorrent, please donate! + 如果你喜歡 qBittorrent, 請捐款! + + + qBittorrent %1 + e.g: qBittorrent v0.x + qBittorrent %1 + + + Set the password... + 設定密碼... + + + Transfers + 傳輸 + + + Torrent file association + Torrent 檔案關聯 + + + qBittorrent is not the default application to open torrent files or Magnet links. +Do you want to associate qBittorrent to torrent files and Magnet links? + qBittorrent 不是你開啟 torrent 檔案或磁性連結的預設程式。 +你想要以 qBittorrent 開啟 torrent 檔案和磁性連結嗎? + + + UI lock password + UI 鎖定密碼 + + + Please type the UI lock password: + 請輸入 UI 鎖定密碼: + + + Password update + 更新密碼 + + + The UI lock password has been successfully updated + UI 鎖定密碼已經更新了 + + + RSS + RSS + + + Search + 搜尋 + + + Transfers (%1) + 傳輸 (%1) + + + Download completion + 下載完成 + + + %1 has finished downloading. + e.g: xxx.avi has finished downloading. + %1 已經下載完成。 + + + I/O Error + i.e: Input/Output Error + I/O 錯誤 + + + An I/O error occured for torrent %1. + Reason: %2 + e.g: An error occured for torrent xxx.avi. + Reason: disk is full. + Torrent %1 發生了 I/O 錯誤。 +原因: %2 + + + Alt+1 + shortcut to switch to first tab + Alt+1 + + + Alt+2 + shortcut to switch to third tab + Alt+2 + + + Ctrl+F + shortcut to switch to search tab + Ctrl+F + + + Alt+3 + shortcut to switch to fourth tab + Alt+3 + + + Recursive download confirmation + 遞迴下載確認 + + + The torrent %1 contains torrent files, do you want to proceed with their download? + Torrent %1 包含 torrent 檔案, 你想要執行下載作業嗎? + + + Yes + + + + No + + + + Never + 從不 + + + Url download error + URL 下載錯誤 + + + Couldn't download file at url: %1, reason: %2. + 無法從 URL: %1 下載檔案, 原因: %2。 + + + Global Upload Speed Limit + 全域上傳速度限制 + + + Global Download Speed Limit + 全域下載速度限制 + + + Invalid password + 無效的密碼 + + + The password is invalid + 密碼是無效的 + + + Exiting qBittorrent + 退出 qBittorrent + + + Some files are currently transferring. +Are you sure you want to quit qBittorrent? + 有些檔案還在傳輸中。 +你確定要退出 qBittorrent 嗎? + + + Always + 總是 + + + Open Torrent Files + 開啟 torrent 檔案 + + + Torrent Files + torrent 檔案 + + + Options were saved successfully. + 選項儲存成功。 + + + qBittorrent + qBittorrent + + + DL speed: %1 KiB/s + e.g: Download speed: 10 KiB/s + 下載速度: %1 KiB/s + + + UP speed: %1 KiB/s + e.g: Upload speed: 10 KiB/s + 上傳速度: %1 KiB/s + + + qBittorrent %1 (Down: %2/s, Up: %3/s) + %1 is qBittorrent version + qBittorrent %1 (下載速度: %2/s, 上傳速度: %3/s) + + + A newer version is available + 有新版本可以取得 + + + A newer version of qBittorrent is available on Sourceforge. +Would you like to update qBittorrent to version %1? + Sourceforge 上有 qBittorrent 的新版本。 +你想要更新 qBittorrent 的版本到 %1 嗎? + + + Impossible to update qBittorrent + 不可更新 qBittorrent + + + qBittorrent failed to update, reason: %1 + qBittorrent 更新失敗, 原因: %1 + + + &Add torrent file... + 增加 torrent 檔案 (&A)... + + + Add &link to torrent... + 增加連結到 torrent (&L)... + + + Import existing torrent... + 匯入已存在的 torrent... + + + Execution &Log + 執行紀錄 (&L) + + + Execution Log + 執行紀錄 + + + Auto-Shutdown on downloads completion + 當下載結束後將電腦關機 + + + Exit qBittorrent + 退出 qBittorrent + + + Suspend system + 暫停系統 + + + Shutdown system + 關機 + + + Disabled + 已停用 + + + The password should contain at least 3 characters + 密碼應該至少包含 3 個字元 + + + + PeerAdditionDlg + + Invalid IP + 無效的 IP + + + The IP you provided is invalid. + 你提供的 IP 是無效的。 + + + + PeerListDelegate + + /s + /second (i.e. per second) + /s + + + + PeerListWidget + + IP + IP + + + Client + i.e.: Client application + 客戶端 + + + Progress + i.e: % downloaded + 進度 + + + Down Speed + i.e: Download speed + 下載速度 + + + Up Speed + i.e: Upload speed + 上傳速度 + + + Downloaded + i.e: total data downloaded + 已下載 + + + Uploaded + i.e: total data uploaded + 已上傳 + + + Ban peer permanently + 永遠封鎖下載者 + + + Peer addition + 增加下載者 + + + The peer was added to this torrent. + 下載者已增加到此 torrent 中。 + + + The peer could not be added to this torrent. + 下載者無法增加到此 torrent 中。 + + + Are you sure? -- qBittorrent + 你確定? --qBittorrent + + + Are you sure you want to ban permanently the selected peers? + 你確定要永遠封鎖所選擇的下載者嗎? + + + &Yes + 是(&Y) + + + &No + 否(&N) + + + Manually banning peer %1... + 手動封鎖下載者 %1... + + + Upload rate limiting + 上傳速度限制 + + + Download rate limiting + 下載速度限制 + + + Add a new peer... + 增加新下載者... + + + Limit download rate... + 限制下載速度... + + + Limit upload rate... + 限制上傳速度... + + + Copy IP + 複製 IP + + + Connection + 連線 + + + + Preferences + + UI + User Interface + 使用者介面 + + + Downloads + 下載 + + + Connection + 連線 + + + Bittorrent + Bittorrent + + + Proxy + 代理伺服器 + + + Web UI + Web UI + + + Language: + 語言: + + + (Requires restart) + (需要重新啟動) + + + Visual style: + 視覺樣式: + + + Transfer list + 傳輸清單 + + + Use alternating row colors + In transfer list, one every two rows will have grey background. + 列使用不同的顏色 + + + File system + 檔案系統 + + + Torrent queueing + torrent 排程 + + + Maximum active downloads: + 最大活躍的下載數: + + + Maximum active uploads: + 最大活躍的上傳數: + + + Maximum active torrents: + 最大活躍的 torrent: + + + When adding a torrent + 當增加 torrent 時 + + + Display torrent content and some options + 顯示 torrent 內容及其他選項 + + + Listening port + 監聽埠 + + + Port used for incoming connections: + 連入連線時使用的埠: + + + Random + 隨機 + + + Enable UPnP port mapping + 啟用 UPnP 埠映射 + + + Enable NAT-PMP port mapping + 啟用 NAT-PMP 埠映射 + + + Connections limit + 連線限制 + + + Global maximum number of connections: + 全域最大連線數: + + + Maximum number of connections per torrent: + 每個 torrent 的最大連線數: + + + Maximum number of upload slots per torrent: + 每個 torrent 上傳位置的最大數: + + + Upload: + 上傳: + + + Download: + 下載: + + + KiB/s + KiB/s + + + Bittorrent features + Bittorrent 特性 + + + Enable DHT network (decentralized) + 啟用 DHT 網路 (分散式) + + + Use a different port for DHT and Bittorrent + DHT 和 Bittorrent 使用不同的埠 + + + DHT port: + DHT 埠: + + + Enable Peer Exchange / PeX (requires restart) + 啟用 PeX (需要重新啟動) + + + Enable Local Peer Discovery + 啟用本地下載者搜尋 + + + Enabled + 啟用 + + + Forced + 強迫 + + + Disabled + 停用 + + + Type: + 類型: + + + (None) + (無) + + + HTTP + HTTP + + + Port: + 埠: + + + Authentication + 驗證 + + + Username: + 使用者名稱: + + + Password: + 密碼: + + + SOCKS5 + SOCKS5 + + + HTTP Server + HTTP 伺服器 + + + Filter path (.dat, .p2p, .p2b): + 過濾路徑 (.dat, .p2p, .p2b): + + + HTTP Communications (trackers, Web seeds, search engine) + HTTP 連線 (trackers, 網頁種子, 搜尋引擎) + + + Host: + 主機: + + + Peer Communications + 下載者連接 + + + SOCKS4 + SOCKS4 + + + Speed + 速度 + + + Global speed limits + 全域速度限制 + + + Alternative global speed limits + 額外的全域速度限制 + + + to + time1 to time2 + + + + Every day + 每天 + + + Week days + 工作天 + + + Week ends + 假日 + + + Advanced + 進階 + + + Copy .torrent files to: + 複製 torrent 檔案到: + + + Remove folder + 移除資料夾 + + + No action + 無行動 + + + Options + 選項 + + + Visual Appearance + 視覺外觀 + + + Action on double-click + 雙擊時的行動 + + + Downloading torrents: + 下載中的 torrent: + + + Start / Stop + 開始 / 停止 + + + Open destination folder + 開啟目的地資料夾 + + + Completed torrents: + 已完成的 torrent: + + + Desktop + 桌面 + + + Show splash screen on start up + 啟動時顯示啟始畫面 + + + Start qBittorrent minimized + 啟動時最小化 qBittorrent + + + Show qBittorrent icon in notification area + 在通知區域顯示 qBittorrent 圖示 + + + Minimize qBittorrent to notification area + 最小化 qBittorrent 到通知區域 + + + Close qBittorrent to notification area + i.e: The systray tray icon will still be visible when closing the main window. + 關閉 qBittorrent 到通知區域 + + + Do not start the download automatically + The torrent will be added to download list in pause state + 不要自動開始下載 + + + Save files to location: + 儲存檔案到: + + + Append the label of the torrent to the save path + 附加 torrent 的標籤到儲存路徑 + + + Pre-allocate disk space for all files + 為所有檔案事先分配磁碟空間 + + + Keep incomplete torrents in: + 保留未完成的 torrent 於: + + + Append .!qB extension to incomplete files' names + 在未完成檔案加上 .!qB 副檔名 + + + Automatically add torrents from: + 自動載入 torrent 檔案: + + + Add folder... + 增加資料夾... + + + IP Filtering + IP 過濾 + + + Schedule the use of alternative speed limits + 排程使用額外的速度限制 + + + from + from (time1 to time2) + + + + When: + 何時: + + + Look for peers on your local network + 在本地網路找尋下載者 + + + Protocol encryption: + 協定加密: + + + Enable Web User Interface (Remote control) + 啟用 Web UI (遠端控制) + + + Share ratio limiting + 分享率限制 + + + Seed torrents until their ratio reaches + 對 torrent 做種直到達到分享率 + + + then + 然後 + + + Pause them + 暫停它們 + + + Remove them + 移除它們 + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + 與相容的 Bittorrent 客戶端 (µTorrent, Vuze, ...) 交換下載者資訊 + + + Email notification upon download completion + 下載完成時使用 Email 通知 + + + Destination email: + 目的地 email: + + + SMTP server: + SMTP 伺服器: + + + Run an external program on torrent completion + 當 torrent 下載完成時執行外部程式 + + + Use %f to pass the torrent path in parameters + 使用 %f 在參數中傳遞 torrent 路徑 + + + Proxy server + 代理伺服器 + + + BitTorrent + BitTorrent + + + Start / Stop Torrent + 開始 / 停止 torrent + + + Use UPnP / NAT-PMP port forwarding from my router + 從我的路由器使用 UPnP/NAT-PMP: 埠映射 + + + Privacy + 隱私 + + + Enable DHT (decentralized network) to find more peers + 啟用 DHT (分散式網路) 來尋找更多下載者 + + + Use a different port for DHT and BitTorrent + DHT 和 BitTorrent 使用不同的埠 + + + Enable Peer Exchange (PeX) to find more peers + 啟用下載者交換 (PeX) 來尋找更多下載者 + + + Enable Local Peer Discovery to find more peers + 啟用本地下載者搜尋來尋找更多下載者 + + + Encryption mode: + 加密模式: + + + Prefer encryption + 偏好加密 + + + Require encryption + 要求加密 + + + Disable encryption + 停用加密 + + + User Interface + 使用者介面 + + + Reload the filter + 重讀過濾器 + + + Behavior + 行為 + + + Language + 語言 + + + Power Management + 電源管理 + + + Inhibit system sleep when torrents are active + 當 torrent 是活躍時, 防止系統進入睡眠 + + + Bypass authentication for localhost + 略過本機的驗證 + + + Ask for program exit confirmation + 程式離開時需要確認 + + + Use monochrome system tray icon (requires restart) + 使用單色的系統通知區域圖示 (需要重新啟動) + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + 支援以下參數: +<ul> +<li>%f: torrent 路徑</li> +<li>%n: torrent 名稱</li> +</ul> + + + Tray icon style: + 系統匣圖示樣式: + + + Normal + 一般 + + + Monochrome (Dark theme) + 單色 (暗主題) + + + Monochrome (Light theme) + 單色 (亮主題) + + + This server requires a secure connection (SSL) + 這個伺服器需要加密連線 (SSL) + + + User Interface Language: + 使用者介面語言: + + + Transfer List + 傳輸清單 + + + Show qBittorrent in notification area + 在通知區域顯示 qBittorrent + + + Hard Disk + 硬碟 + + + Listening Port + 監聽埠 + + + Connections Limits + 連線限制 + + + Proxy Server + 代理伺服器 + + + Torrent Queueing + torrent 排程 + + + Share Ratio Limiting + 分享率限制 + + + Use UPnP / NAT-PMP to forward the port from my router + 從我的路由器使用 UPnP/NAT-PMP: 埠映射 + + + Update my dynamic domain name + 更新我的動態領域名稱 + + + Service: + 服務: + + + Register + 註冊 + + + Domain name: + 領域名稱: + + + Global Rate Limits + 全域分享率限制 + + + Apply rate limit to uTP connections + 套用速度限制至 uTP 連線 + + + Apply rate limit to transport overhead + 套用速度限制至傳輸負載 + + + Alternative Global Rate Limits + 額外的全域分享率限制 + + + Schedule the use of alternative rate limits + 排程使用額外的速度限制 + + + Enable bandwidth management (uTP) + 啟用頻寬管理 (uTP) + + + Otherwise, the proxy server is only used for tracker connections + 除此之外, 代理伺服器僅用於 tracker 連線 + + + Use proxy for peer connections + 使用代理伺服器來連線下載者 + + + Append .!qB extension to incomplete files + 在未完成檔案加上 .!qB 副檔名 + + + Use HTTPS instead of HTTP + 使用 HTTPS 而不是 HTTP + + + Import SSL Certificate + 匯入 SSL 憑證 + + + Import SSL Key + 匯入 SSL 鑰匙 + + + Certificate: + 憑證: + + + Key: + 鑰匙: + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>關於憑證的資訊</a> + + + + PreviewSelect + + Name + 名稱 + + + Size + 大小 + + + Progress + 進度 + + + Preview impossible + 不可預覽 + + + Sorry, we can't preview this file + 抱歉, 我們無法預覽這個檔案 + + + + ProgramUpdater + + Could not create the file %1 + 無法建立檔案 %1 + + + Failed to download the update at %1 + %1 is an URL + 無法從 %1 下載更新擋 + + + + PropListDelegate + + Normal + Normal (priority) + 一般 + + + High + High (priority) + + + + Maximum + Maximum (priority) + 最高 + + + Not downloaded + 沒有下載 + + + Mixed + Mixed (priorities + 混和 + + + + PropTabBar + + General + 一般 + + + Trackers + Trackers + + + Peers + 下載者 + + + URL Seeds + URL 種子 + + + Files + 檔案 + + + HTTP Sources + HTTP 來源 + + + Content + 內容 + + + + PropertiesWidget + + Save path: + 儲存路徑: + + + Torrent hash: + torrent 雜湊: + + + Comment: + 註解: + + + Share ratio: + 分享率: + + + General + 一般 + + + Trackers + Trackers + + + URL seeds + URL 種子 + + + Files + 檔案 + + + Priority + 優先度 + + + New url seed + New HTTP source + 新 URL 種子 + + + New url seed: + 新 URL 種子: + + + qBittorrent + qBittorrent + + + This url seed is already in the list. + 這個 URL 種子已經在清單裡了。 + + + Choose save path + 選擇儲存路徑 + + + Save path creation error + 建立儲存路徑錯誤 + + + Could not create the save path + 無法建立儲存路徑 + + + Downloaded: + 已下載: + + + Transfer + 傳輸 + + + Uploaded: + 已上傳: + + + Wasted: + 已丟棄: + + + UP limit: + 上傳限制: + + + DL limit: + 下載限制: + + + Time elapsed: + 經過時間: + + + Connections: + 連線: + + + Information + 資訊 + + + Created on: + 建立於: + + + Peers + 下載者 + + + Normal + 一般 + + + Maximum + 最高 + + + High + + + + this session + 此作業階段 + + + %1 max + e.g. 10 max + 最大 %1 + + + Availability: + 可得性: + + + /s + /second (i.e. per second) + /s + + + Seeded for %1 + e.g. Seeded for 3m10s + 已做種 %1 + + + Rename... + 重新命名... + + + New name: + 新名稱: + + + The file could not be renamed + 檔案無法重命名 + + + This name is already in use in this folder. Please use a different name. + 此名稱已在此資料夾中使用。請選擇另一個名稱。 + + + The folder could not be renamed + 此資料夾無法被重新命名 + + + Rename the file + 重新命名檔案 + + + This file name contains forbidden characters, please choose a different one. + 檔案名稱包含禁止使用之字元, 請選擇其他名稱。 + + + I/O Error + I/O 錯誤 + + + This file does not exist yet. + 檔案不存在。 + + + This folder does not exist yet. + 資料夾不存在。 + + + Reannounce in: + 重新公告於: + + + Select All + 全部選擇 + + + Select None + 全部不選 + + + Do not download + 不要下載 + + + Pieces size: + 分塊大小: + + + Time active: + Time (duration) the torrent is active (not paused) + 經過時間: + + + Torrent content: + torrent 內容: + + + + QBtSession + + %1 reached the maximum ratio you set. + %1 已經到達你設定的最大比率了。 + + + Removing torrent %1... + 移除 torrent %1... + + + Pausing torrent %1... + 暫停 torrent %1... + + + qBittorrent is bound to port: TCP/%1 + e.g: qBittorrent is bound to port: 6881 + qBittorrent 綁定埠: TCP/%1 + + + UPnP support [ON] + UPnP 支援 [開啟] + + + UPnP support [OFF] + UPnP 支援 [關閉] + + + NAT-PMP support [ON] + NAT-PMP 支援 [開啟] + + + NAT-PMP support [OFF] + NAT-PMP 支援 [關閉] + + + HTTP user agent is %1 + HTTP 使用者代理是: %1 + + + Using a disk cache size of %1 MiB + 使用磁碟快取大小為 %1 MiB + + + DHT support [ON], port: UDP/%1 + DHT 支援 [開啟], 埠: UDP/%1 + + + DHT support [OFF] + DHT 支援 [關閉] + + + PeX support [ON] + PeX 支援 [開啟] + + + PeX support [OFF] + PeX 支援 [關閉] + + + Restart is required to toggle PeX support + 切換 PeX 支援需重新啟動 + + + Local Peer Discovery [ON] + 本地下載者搜尋 [開啟] + + + Local Peer Discovery support [OFF] + 本地下載者搜尋支援 [關閉] + + + Encryption support [ON] + 加密支援 [開啟] + + + Encryption support [FORCED] + 加密支援 [強迫] + + + Encryption support [OFF] + 加密支援 [關閉] + + + Embedded Tracker [ON] + 嵌入 tracker [開啟] + + + Failed to start the embedded tracker! + 無法開始嵌入 tracker! + + + Embedded Tracker [OFF] + 嵌入 tracker [關閉] + + + The Web UI is listening on port %1 + Web UI 監聽的埠為: %1 + + + Web User Interface Error - Unable to bind Web UI to port %1 + Web UI 錯誤 - 無法綁定 Web UI 到埠 %1 + + + '%1' was removed from transfer list and hard disk. + 'xxx.avi' was removed... + '%1' 已經從傳輸清單和硬碟中刪除了。 + + + '%1' was removed from transfer list. + 'xxx.avi' was removed... + '%1' 已經從傳輸清單中刪除了。 + + + '%1' is not a valid magnet URI. + '%1' 不是一個有效的磁性 URI。 + + + '%1' is already in download list. + e.g: 'xxx.avi' is already in download list. + '%1' 已經在下載清單裡了。 + + + '%1' resumed. (fast resume) + '/home/y/xxx.torrent' was resumed. (fast resume) + '%1' 已恢復下載。(快速恢復) + + + '%1' added to download list. + '/home/y/xxx.torrent' was added to download list. + '%1' 已增加到下載清單。 + + + Unable to decode torrent file: '%1' + e.g: Unable to decode torrent file: '/home/y/xxx.torrent' + 無法解碼 torrent 檔案: '%1' + + + This file is either corrupted or this isn't a torrent. + 這個檔案不是損壞就是並非 torrent。 + + + Error: The torrent %1 does not contain any file. + 錯誤: Torrent %1 沒有包含任何檔案。 + + + Note: new trackers were added to the existing torrent. + 備註: 新 tracker 已增加到現有的 torrent 中。 + + + Note: new URL seeds were added to the existing torrent. + 備註: URL 種子已增加到現有 torrent 中。 + + + <font color='red'>%1</font> <i>was blocked due to your IP filter</i> + x.y.z.w was blocked + <font color='red'>%1</font> <i>因為你的 IP 過濾器而被封鎖了</i> + + + <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> + x.y.z.w was banned + <font color='red'>%1</font> <i>因為有損壞的分塊而被踢出</i> + + + Recursive download of file %1 embedded in torrent %2 + Recursive download of test.torrent embedded in torrent test2 + 遞迴下載在 torrent %2 裡的檔案 %1 + + + Unable to decode %1 torrent file. + 無法解碼 torrent 檔案 %1 。 + + + Torrent name: %1 + Torrent 名稱: %1 + + + Torrent size: %1 + Torrent 大小: %1 + + + Save path: %1 + 儲存路徑: %1 + + + The torrent was downloaded in %1. + The torrent was downloaded in 1 hour and 20 seconds + Torrent 已於 %1 下載完成。 + + + Thank you for using qBittorrent. + 感謝您使用 qBittorrent。 + + + [qBittorrent] %1 has finished downloading + [qBittorrent] 已下載完成 %1 + + + An I/O error occured, '%1' paused. + 發生 I/O 錯誤, '%1' 已暫停。 + + + Reason: %1 + 原因: %1 + + + UPnP/NAT-PMP: Port mapping failure, message: %1 + UPnP/NAT-PMP: 埠映射失敗, 訊息: %1 + + + UPnP/NAT-PMP: Port mapping successful, message: %1 + UPnP/NAT-PMP: 埠映射成功, 訊息: %1 + + + File sizes mismatch for torrent %1, pausing it. + 檔案大小和 torrent %1 不合, 暫停。 + + + Fast resume data was rejected for torrent %1, checking again... + 快速恢復資料被 torrent %1 拒絕, 重新檢查... + + + Url seed lookup failed for url: %1, message: %2 + 找不到 URL: %1 的 URL 種子, 訊息: %2 + + + Downloading '%1', please wait... + e.g: Downloading 'xxx.torrent', please wait... + 下載 '%1' 中, 請稍候... + + + The network interface defined is invalid: %1 + 定義的網路介面是無效的: %1 + + + Trying any other network interface available instead. + 嘗試其他可得的網路介面。 + + + Listening on IP address %1 on network interface %2... + 監聽網路介面 %2 的 IP 位置 %1... + + + Failed to listen on network interface %1 + 監聽網路介面 %1 失敗 + + + UPnP / NAT-PMP support [ON] + NAT-PMP 支援 [開啟] + + + UPnP / NAT-PMP support [OFF] + NAT-PMP 支援 [關閉] + + + Local Peer Discovery support [ON] + 本地下載者搜尋支援 [開啟] + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + 分析 IP 過濾檔案成功: 已套用 %1 個規則。 + + + Error: Failed to parse the provided IP filter. + 錯誤: IP 過濾檔案分析失敗。 + + + Reporting IP address %1 to trackers... + 回報 IP 地址 %1 至 tracker... + + + The computer will now go to sleep mode unless you cancel within the next 15 seconds... + 在 15 秒內你沒有取消的話, 電腦會進入睡眠模式... + + + The computer will now be switched off unless you cancel within the next 15 seconds... + 在 15 秒內你沒有取消的話, 電腦會關機... + + + qBittorrent will now exit unless you cancel within the next 15 seconds... + 在 15 秒內你沒有取消的話, qBittorrent 會離開程式... + + + + RSS + + Search + 搜尋 + + + Delete + 刪除 + + + Rename + 重新命名 + + + Refresh RSS streams + 更新 RSS 資源 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + + + Download torrent + 下載 torrent + + + Open news URL + 開啟消息 URL + + + Copy feed URL + 複製 feed URL + + + New subscription + 新訂閱 + + + Mark items read + 標記項目為已讀 + + + Update all + 全部更新 + + + Update all feeds + 更新全部 feed + + + RSS feeds + RSS feeds + + + Update + 更新 + + + Feed URL + Feed URL + + + Article title + 文章標題 + + + Rename... + 重新命名... + + + New subscription... + 新訂閱... + + + RSS feed downloader... + RSS feed 下載器... + + + New folder... + 新資料夾... + + + Manage cookies... + 管理 cookie... + + + Settings... + 設定... + + + RSS Downloader... + RSS 下載器... + + + + RSSImp + + Please type a rss stream url + 請輸入一個 RSS 資源的 URL + + + Stream URL: + 資源 URL: + + + Are you sure? -- qBittorrent + 你確定? --qBittorrent + + + &Yes + 是(&Y) + + + &No + 否(&N) + + + qBittorrent + qBittorrent + + + This rss feed is already in the list. + 這個 RSS feed 已經在清單裡了。 + + + Date: + 日期: + + + Author: + 作者: + + + Please choose a folder name + 請選擇資料夾名稱 + + + Folder name: + 資料夾名稱: + + + New folder + 新資料夾 + + + Are you sure you want to delete these elements from the list? + 你確定要從清單裡刪除這些項目嗎? + + + Are you sure you want to delete this element from the list? + 你確定要從清單裡刪除這個項目嗎? + + + Please choose a new name for this RSS feed + 請為這個 RSS feed 選擇新名稱 + + + New feed name: + 新 feed 名稱: + + + Name already in use + 此名稱已使用 + + + This name is already used by another item, please choose another one. + 此名稱已被另一個項目使用, 請選擇一個新的名稱。 + + + Overwrite attempt + 嘗試複寫 + + + You cannot overwrite %1 item. + You cannot overwrite myFolder item. + 你不能複寫 %1 項目。 + + + Unread + 未讀 + + + + RssArticle + + No description available + 沒有可得的描述 + + + + RssFeed + + Automatically downloading %1 torrent from %2 RSS feed... + 自動從 %2 RSS feed 下載 %1 torrent... + + + + RssItem + + No description available + 沒有可得的描述 + + + + RssSettings + + RSS Reader Settings + RSS 閱讀器設定 + + + RSS feeds refresh interval: + RSS feed 更新間隔: + + + minutes + 分鐘 + + + Maximum number of articles per feed: + 每個 feed 的最大文章數: + + + + RssSettingsDlg + + RSS Reader Settings + RSS 閱讀器設定 + + + RSS feeds refresh interval: + RSS feed 更新間隔: + + + minutes + 分鐘 + + + Maximum number of articles per feed: + 每個 feed 的最大文章數: + + + + RssStream + + Automatically downloading %1 torrent from %2 RSS feed... + 自動從 %2 RSS feed 下載 %1 torrent... + + + + ScanFoldersModel + + Watched Folder + 監視資料夾 + + + Download here + 下載到此 + + + + SearchCategories + + All categories + 所有類別 + + + Movies + 電影 + + + TV shows + 電視劇 + + + Music + 音樂 + + + Games + 遊戲 + + + Anime + 動畫 + + + Software + 軟體 + + + Pictures + 圖片 + + + Books + + + + + SearchEngine + + Cut + 剪下 + + + Copy + 複製 + + + Paste + 貼上 + + + Clear field + 清除欄位 + + + Clear completion history + 清除已完成的紀錄 + + + Empty search pattern + 沒有搜尋模式 + + + Please type a search pattern first + 請先輸入一個搜尋模式 + + + Results + 結果 + + + Searching... + 搜尋中... + + + Search Engine + 搜尋引擎 + + + Search has finished + 搜尋完成 + + + An error occured during search... + 搜尋時發生錯誤... + + + Search aborted + 搜尋中止 + + + Search returned no results + 沒有搜尋結果 + + + Results + i.e: Search results + 結果 + + + Unknown + 未知 + + + Search + 搜尋 + + + Download error + 下載錯誤 + + + Python setup could not be downloaded, reason: %1. +Please install it manually. + Python 安裝程式無法下載。原因: %1。 +請手動安裝。 + + + Missing Python Interpreter + 遺失 Python 解釋器 + + + Python 2.x is required to use the search engine but it does not seem to be installed. +Do you want to install it now? + 使用搜尋引擎需要 Python 2.x, 但是它沒有安裝。 +你想要現在安裝嗎? + + + Confirmation + 確認 + + + Are you sure you want to clear the history? + 你確定要刪除紀錄嗎? + + + + SearchTab + + Name + i.e: file name + 名稱 + + + Size + i.e: file size + 大小 + + + Seeders + i.e: Number of full sources + 種子 + + + Leechers + i.e: Number of partial sources + 不完整種子 + + + Search engine + 搜尋引擎 + + + + ShutdownConfirmDlg + + Shutdown confirmation + 關機設置 + + + + SpeedLimitDialog + + KiB/s + KiB/s + + + + StatusBar + + Connection status: + 連線狀態: + + + No direct connections. This may indicate network configuration problems. + 沒有直接的連線。這表示你的網路設置可能有問題。 + + + DHT: %1 nodes + DHT: %1 個節點 + + + Connection Status: + 連線狀態: + + + Online + 線上 + + + Global Download Speed Limit + 全域下載速度限制 + + + Global Upload Speed Limit + 全域上傳速度限制 + + + D: %1/s - T: %2 + Download speed: x KiB/s - Transferred: x MiB + 下載速度: %1/s - 已傳輸: %2 + + + U: %1/s - T: %2 + Upload speed: x KiB/s - Transferred: x MiB + 上傳速度: %1/s - 已傳輸: %2 + + + D: %1 B/s - T: %2 + Download speed: x B/s - Transferred: x MiB + 下載速度: %1 B/s - 已傳輸: %2 + + + U: %1 B/s - T: %2 + Upload speed: x B/s - Transferred: x MiB + 上傳速度: %1 B/s - 已傳輸: %2 + + + Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections. + 離線。這通常表示 qBittorrent 監聽進來連線的埠失敗。 + + + Click to disable alternative speed limits + 點選來停用額外的速度限制 + + + Click to enable alternative speed limits + 點選來啟用額外的速度限制 + + + qBittorrent needs to be restarted + qBittorrent 需要重新啟動 + + + qBittorrent was just updated and needs to be restarted for the changes to be effective. + qBittorrent 已經更新了並且需要重新啟動。 + + + Click to switch to alternative speed limits + 點選來切換至額外的速度限制 + + + Click to switch to regular speed limits + 點選來切換至一般的速度限制 + + + %1/s + Per second + %1/秒 + + + + TorrentCreatorDlg + + Select a folder to add to the torrent + 選擇要增加到 torrent 的資料夾 + + + Select a file to add to the torrent + 選擇要增加到 torrent 的檔案 + + + Please type an announce URL + 請先輸入發佈的 URL + + + Announce URL: + Tracker URL + 發佈的 URL: + + + Please type a web seed url + 請先輸入網頁種子 URL + + + Web seed URL: + 網頁種子 URL: + + + No input path set + 沒有設定輸入路徑 + + + Please type an input path first + 請先輸入輸入的路徑 + + + Select destination torrent file + 選擇 torrent 檔案目的地 + + + Torrent Files + torrent 檔案 + + + Torrent creation + 產生 torrent + + + Torrent creation was unsuccessful, reason: %1 + 建立 torrent 不成功, 原因: %1 + + + Created torrent file is invalid. It won't be added to download list. + 建立的 torrent 檔案是無效的。它不會被加入到下載清單。 + + + Torrent was created successfully: + 已經成功建立 torrent: + + + + TorrentFilesModel + + Name + 名稱 + + + Size + 大小 + + + Progress + 進度 + + + Priority + 優先度 + + + + TorrentImportDlg + + Torrent Import + 匯入 torrent + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + 這個助手會協助你將你已經下載完成的檔案使用 qBittorrent 來分享。 + + + Torrent file to import: + 要匯入的 torrent 檔案: + + + ... + ... + + + Content location: + 內容位置: + + + Skip the data checking stage and start seeding immediately + 略過資料檢查並立即開始做種 + + + Import + 匯入 + + + Torrent file to import + 匯入 torrent 檔案 + + + Torrent files (*.torrent) + Torrent 檔案 (*.torrent) + + + %1 Files + %1 is a file extension (e.g. PDF) + %1 檔案 + + + Please provide the location of %1 + %1 is a file name + 請提供 %1 的位置 + + + Please point to the location of the torrent: %1 + 請指定 torren %1 的位置 + + + Invalid torrent file + 無效的 torrent 檔案 + + + This is not a valid torrent file. + 這是一個無效的 torrent 檔案。 + + + + TorrentModel + + Name + i.e: torrent name + 名稱 + + + Size + i.e: torrent size + 大小 + + + Done + % Done + 完成 + + + Status + Torrent status (e.g. downloading, seeding, paused) + 狀態 + + + Seeds + i.e. full sources (often untranslated) + 種子 + + + Peers + i.e. partial sources (often untranslated) + 下載者 + + + Down Speed + i.e: Download speed + 下載速度 + + + Up Speed + i.e: Upload speed + 上傳速度 + + + Ratio + Share ratio + 分享率 + + + ETA + i.e: Estimated Time of Arrival / Time left + 預估剩餘時間 + + + Label + 標籤 + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + 增加於 + + + Completed On + Torrent was completed on 01/01/2010 08:00 + 完成於 + + + Tracker + Tracker + + + Down Limit + i.e: Download limit + 下載限制 + + + Up Limit + i.e: Upload limit + 上傳限制 + + + Amount downloaded + Amount of data downloaded (e.g. in MB) + 已下載量 + + + Amount left + Amount of data left to download (e.g. in MB) + 剩餘量 + + + Time Active + Time (duration) the torrent is active (not paused) + 經過時間 + + + + TrackerList + + URL + URL + + + Status + 狀態 + + + Peers + 下載者 + + + Message + 訊息 + + + [DHT] + [DHT] + + + Working + 有效 + + + Disabled + 已停用 + + + This torrent is private + 這是私有 torrent + + + Updating... + 更新中... + + + Not working + 無效 + + + Not contacted yet + 尚未連接 + + + [PeX] + [PeX] + + + [LSD] + [LSD] + + + Add a new tracker... + 增加新 tracker... + + + Remove tracker + 移除 tracker + + + Force reannounce + 強迫重新公告 + + + + TrackersAdditionDlg + + Trackers addition dialog + 增加 tracker 對話框 + + + List of trackers to add (one per line): + 要增加的 tracker 清單 (一行一個): + + + µTorrent compatible list URL: + µTorrent 相容清單 URL: + + + I/O Error + I/O 錯誤 + + + Error while trying to open the downloaded file. + 嘗試開啟已下載的檔案時發生錯誤。 + + + No change + 沒有改變 + + + No additional trackers were found. + 沒有找到額外的 tracker。 + + + Download error + 下載錯誤 + + + The trackers list could not be downloaded, reason: %1 + 無法下載 tracker 清單, 原因: %1 + + + + TransferListDelegate + + Downloading + 下載中 + + + Paused + 暫停 + + + Queued + i.e. torrent is queued + 佇列 + + + Seeding + Torrent is complete and in upload-only mode + 做種中 + + + Stalled + Torrent is waiting for download to begin + 等待開始 + + + Checking + Torrent local data is being checked + 檢查中 + + + /s + /second (.i.e per second) + /s + + + KiB/s + KiB/second (.i.e per second) + KiB/s + + + Seeded for %1 + e.g. Seeded for 3m10s + 已做種 %1 + + + + TransferListFiltersWidget + + All + 全部 + + + Downloading + 下載中 + + + Completed + 已完成 + + + Active + 活躍的 + + + Inactive + 不活躍的 + + + All labels + 所有標籤 + + + Unlabeled + 取消標籤 + + + Remove label + 移除標籤 + + + New Label + 新標籤 + + + Label: + 標籤: + + + Invalid label name + 無效的標籤名稱 + + + Please don't use any special characters in the label name. + 標籤名稱請不要使用任何特殊字元。 + + + Paused + 暫停 + + + Add label... + 增加標籤... + + + Resume torrents + 繼續 torrent + + + Pause torrents + 暫停 torrent + + + Delete torrents + 刪除 torrent + + + + TransferListWidget + + ETA + i.e: Estimated Time of Arrival / Time left + 預估剩餘時間 + + + Column visibility + 欄可見度 + + + Open destination folder + 開啟目的地資料夾 + + + Force recheck + 強迫重新檢查 + + + Copy magnet link + 複製磁性連結 + + + Down Speed + i.e: Download speed + 下載速度 + + + Up Speed + i.e: Upload speed + 上傳速度 + + + Name + i.e: torrent name + 名稱 + + + Size + i.e: torrent size + 大小 + + + Done + % Done + 完成 + + + Status + Torrent status (e.g. downloading, seeding, paused) + 狀態 + + + Seeds + i.e. full sources (often untranslated) + 種子 + + + Peers + i.e. partial sources (often untranslated) + 下載者 + + + Ratio + Share ratio + 分享率 + + + Torrent Download Speed Limiting + torrent 下載速度限制 + + + Torrent Upload Speed Limiting + torrent 上傳速度限制 + + + Super seeding mode + 超級種子模式 + + + Download in sequential order + 依順序下載 + + + Download first and last piece first + 先下載第一和最後一塊 + + + Label + 標籤 + + + New Label + 新標籤 + + + Label: + 標籤: + + + New... + New label... + 新... + + + Reset + Reset label + 重設 + + + Rename + 重新命名 + + + New name: + 新名稱: + + + Rename... + 重新命名... + + + Invalid label name + 無效的標籤名稱 + + + Please don't use any special characters in the label name. + 標籤名稱請不要使用任何特殊字元。 + + + Added On + Torrent was added to transfer list on 01/01/2010 08:00 + 增加於 + + + Completed On + Torrent was completed on 01/01/2010 08:00 + 完成於 + + + Down Limit + i.e: Download limit + 下載限制 + + + Up Limit + i.e: Upload limit + 上傳限制 + + + Choose save path + 選擇儲存路徑 + + + Save path creation error + 儲存路徑建立錯誤 + + + Could not create the save path + 無法建立儲存路徑 + + + Set location... + 設定位置... + + + Preview file... + 預覽檔案... + + + Limit upload rate... + 限制上傳速度... + + + Limit download rate... + 限制下載速度... + + + Move up + i.e. move up in the queue + 向上移 + + + Move down + i.e. Move down in the queue + 向下移 + + + Move to top + i.e. Move to top of the queue + 移到最上面 + + + Move to bottom + i.e. Move to bottom of the queue + 移到最下面 + + + Priority + 優先度 + + + Resume + Resume/start the torrent + 繼續 + + + Pause + Pause the torrent + 暫停 + + + Delete + Delete the torrent + 刪除 + + + Limit share ratio... + 限制分享率... + + + + UpDownRatioDlg + + Torrent Upload/Download Ratio Limiting + torrent 上傳/下載比率限制 + + + Use global ratio limit + 使用全域比率限制 + + + buttonGroup + 按鈕群組 + + + Set no ratio limit + 設定無比率限制 + + + Set ratio limit to + 設定限制比率至 + + + + UsageDisplay + + Usage: + 使用: + + + displays program version + 顯示程式版本 + + + disable splash screen + 停用啟始畫面 + + + displays this help message + 顯示幫助訊息 + + + changes the webui port (current: %1) + 更改 webui 埠 (目前是: %1) + + + [files or urls]: downloads the torrents passed by the user (optional) + [檔案或 URLs]: 不經由使用者下載 torrent (選擇性) + + + + about + + qBittorrent + qBittorrent + + + I would like to thank the following people who volunteered to translate qBittorrent: + 我想要感謝以下自願翻譯 qBittorrent 的人士: + + + Please contact me if you would like to translate qBittorrent into your own language. + 如果你想將 qBittorrent 翻譯到你的語言, 請與我聯絡。 + + + + addPeerDialog + + Peer addition + 增加下載者 + + + IP + IP + + + Port + + + + + addTorrentDialog + + Torrent addition dialog + 增加 torrent 對話框 + + + Save path: + 儲存路徑: + + + ... + ... + + + Torrent content: + torrent 內容: + + + Add to download list in paused state + 以暫停狀態增加到下載清單 + + + Add + 增加 + + + Cancel + 取消 + + + Normal + 一般 + + + High + + + + Maximum + 最高 + + + Torrent size: + torrent 大小: + + + Unknown + 未知 + + + Free disk space: + 剩餘磁碟空間: + + + Download in sequential order (slower but good for previewing) + 按照順序下載 (較慢但較好預覽) + + + Skip file checking and start seeding immediately + 停止檔案檢查並立刻開始做種 + + + Label: + 標籤: + + + Select All + 全部選擇 + + + Select None + 全部不選 + + + Do not download + 不要下載 + + + + authentication + + Tracker authentication + tracker 驗證 + + + Tracker: + Tracker: + + + Login + 登入 + + + Username: + 使用者名稱: + + + Password: + 密碼: + + + Log in + 登入 + + + Cancel + 取消 + + + + confirmDeletionDlg + + Deletion confirmation - qBittorrent + 刪除確認 - qBittorrent + + + Are you sure you want to delete the selected torrents from the transfer list? + 你確定要刪除在傳輸清單中所選擇的 torrent 嗎? + + + Remember choice + 記住選擇 + + + Also delete the files on the hard disk + 也把硬碟裡的檔案刪除 + + + + createTorrentDialog + + Cancel + 取消 + + + Torrent Creation Tool + torrent 建立工具 + + + Torrent file creation + 建立 torrent 檔案 + + + Announce urls (trackers): + 發佈 URL (tracker): + + + Comment (optional): + 註解 (選擇性): + + + Web seeds urls (optional): + 網頁種子 URL (選擇性): + + + File or folder to add to the torrent: + 要增加到 torrent 裡的檔案或資料夾: + + + Piece size: + 分塊大小: + + + 32 KiB + 32 KiB + + + 64 KiB + 64 KiB + + + 128 KiB + 128 KiB + + + 256 KiB + 256 KiB + + + 512 KiB + 512 KiB + + + 1 MiB + 1 MiB + + + 2 MiB + 2 MiB + + + 4 MiB + 4 MiB + + + Private (won't be distributed on DHT network if enabled) + 私人的 (如果啟用, 不會分佈到 DHT 網路) + + + Start seeding after creation + 建立後開始做種 + + + Create and save... + 建立且儲存... + + + Progress: + 進度: + + + Add file + 增加檔案 + + + Add folder + 增加資料夾 + + + Tracker URLs: + Tracker URL: + + + Web seeds urls: + 網頁種子 URL: + + + Comment: + 註解: + + + Auto + 自動 + + + + createtorrent + + Select destination torrent file + 選擇 torrent 檔案目的地 + + + Torrent Files + torrent 檔案 + + + No input path set + 沒有設定輸入路徑 + + + Please type an input path first + 請先輸入輸入的路徑 + + + Torrent creation + 產生 torrent + + + Torrent was created successfully: + 已經成功建立 torrent: + + + Select a folder to add to the torrent + 選擇要增加到 torrent 的資料夾 + + + Please type an announce URL + 請先輸入發佈的 URL + + + Torrent creation was unsuccessful, reason: %1 + 建立 torrent 不成功, 原因: %1 + + + Announce URL: + Tracker URL + 發佈的 URL: + + + Please type a web seed url + 請先輸入網頁種子 URL + + + Web seed URL: + 網頁種子 URL: + + + Select a file to add to the torrent + 選擇要增加到 torrent 的檔案 + + + Created torrent file is invalid. It won't be added to download list. + 建立的 torrent 檔案是無效的。它不會被加入到下載清單。 + + + + downloadFromURL + + Download Torrents from URLs + 從 URL 下載 torrent + + + Only one URL per line + 每條線僅一個 URL + + + Download + 下載 + + + Cancel + 取消 + + + Download from urls + 從 URL 下載 + + + No URL entered + 沒有輸入 URL + + + Please type at least one URL. + 請輸入至少一個 URL。 + + + Add torrent links + 增加 torrent 連結 + + + Both HTTP and Magnet links are supported + HTTP 和磁性連結皆支援 + + + + downloadThread + + I/O Error + I/O 錯誤 + + + The remote host name was not found (invalid hostname) + 找不到遠端主機的名稱 (無效的主機名) + + + The operation was canceled + 操作已取消 + + + The remote server closed the connection prematurely, before the entire reply was received and processed + 在回應被接收及處理之前遠端伺服器已永遠關閉連線 + + + The connection to the remote server timed out + 連線到遠端伺服器逾時 + + + SSL/TLS handshake failed + SSL/TLS 握手失敗 + + + The remote server refused the connection + 遠端伺服器拒絕連線 + + + The connection to the proxy server was refused + 連線到代理伺服器被拒絕 + + + The proxy server closed the connection prematurely + 代理伺服器永遠關閉連線 + + + The proxy host name was not found + 找不到代理伺服器主機名 + + + The connection to the proxy timed out or the proxy did not reply in time to the request sent + 連線到代理伺服器逾時或是在要求的時間中沒有回應 + + + The proxy requires authentication in order to honour the request but did not accept any credentials offered + 為了執行要求, 代理伺服器需要認證但是不接受任何提供的憑證 + + + The access to the remote content was denied (401) + 存取遠端內容被拒絕 (401) + + + The operation requested on the remote content is not permitted + 對遠端內容要求的操作不被允許 + + + The remote content was not found at the server (404) + 遠端內容在伺服器上找不到 (404) + + + The remote server requires authentication to serve the content but the credentials provided were not accepted + 為了提供內容, 遠端代理伺服器需要認證, 但是不接受所提供的憑證 + + + The Network Access API cannot honor the request because the protocol is not known + 因為未知的協定, 網路存取 API 無法執行要求 + + + The requested operation is invalid for this protocol + 要求的操作對於此協定是無效的 + + + An unknown network-related error was detected + 偵測到一個未知的網路相關錯誤 + + + An unknown proxy-related error was detected + 偵測到一個未知的代理伺服器相關錯誤 + + + An unknown error related to the remote content was detected + 偵測到一個未知的遠端內容相關錯誤 + + + A breakdown in protocol was detected + 偵測到一個協定錯誤 + + + Unknown error + 未知的錯誤 + + + + engineSelect + + Search plugins + 搜尋外掛 + + + Installed search engines: + 已安裝的搜尋引擎: + + + Name + 名稱 + + + Url + Url + + + Enabled + 已啟用 + + + Install a new one + 安裝新的 + + + Check for updates + 檢查更新 + + + Close + 關閉 + + + Enable + 啟用 + + + Disable + 停用 + + + Uninstall + 反安裝 + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + 你可以在這裡取得新的搜尋引擎外掛: <a href="http:plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + + engineSelectDlg + + Uninstall warning + 反安裝警告 + + + Some plugins could not be uninstalled because they are included in qBittorrent. + Only the ones you added yourself can be uninstalled. +However, those plugins were disabled. + 有些外掛不能反安裝, 因為他們包含在 qBittorrent 裡面。 +只有你自己安裝的可以反安裝。 +然而, 這些外掛已經停用。 + + + Uninstall success + 反安裝成功 + + + Select search plugins + 選擇搜尋外掛 + + + qBittorrent search plugins + qBittorrent 搜尋外掛 + + + Search plugin install + 安裝搜尋外掛 + + + qBittorrent + qBittorrent + + + A more recent version of %1 search engine plugin is already installed. + %1 is the name of the search engine + 已安裝一個更新版本的 %1 搜尋引擎外掛。 + + + Search plugin update + 更新搜尋外掛 + + + Sorry, update server is temporarily unavailable. + 抱歉, 更新伺服器暫時不可用。 + + + All your plugins are already up to date. + 你所有的外掛都已經是最新版本。 + + + %1 search engine plugin could not be updated, keeping old version. + %1 is the name of the search engine + %1 搜尋引擎外掛不能升級, 將保持舊版本。 + + + %1 search engine plugin could not be installed. + %1 is the name of the search engine + %1 搜尋引擎外掛不能安裝。 + + + All selected plugins were uninstalled successfully + 所有選擇的外掛都已經成功反安裝了 + + + %1 search engine plugin was successfully updated. + %1 is the name of the search engine + %1 搜尋引擎外掛已經成功更新。 + + + %1 search engine plugin was successfully installed. + %1 is the name of the search engine + %1搜尋引擎外掛已經成功安裝。 + + + Sorry, %1 search plugin install failed. + %1 is the name of the search engine + 抱歉, 安裝搜尋外掛 %1 失敗。 + + + New search engine plugin URL + 新搜尋引擎外掛 URL + + + URL: + URL: + + + Yes + + + + No + + + + + misc + + B + bytes + B + + + KiB + kibibytes (1024 bytes) + KiB + + + MiB + mebibytes (1024 kibibytes) + MiB + + + GiB + gibibytes (1024 mibibytes) + GiB + + + TiB + tebibytes (1024 gibibytes) + TiB + + + Unknown + Unknown (size) + 未知 + + + < 1m + < 1 minute + < 1 分鐘 + + + %1m + e.g: 10minutes + %1 分鐘 + + + Unknown + 未知 + + + %1h %2m + e.g: 3hours 5minutes + %1 小時 %2 分鐘 + + + %1d %2h + e.g: 2days 10hours + %1 天 %2 小時 + + + qBittorrent will shutdown the computer now because all downloads are complete. + 因為所有下載已經完成, qBittorrent 現在會將電腦關機。 + + + + options_imp + + Choose a save directory + 選擇儲存的目錄 + + + Choose an ip filter file + 選擇一個 IP 過濾檔案 + + + Filters + 過濾器 + + + Choose export directory + 選擇輸出目錄 + + + Add directory to scan + 增加要掃描的目錄 + + + Folder is already being watched. + 資料夾已在監視中。 + + + Folder does not exist. + 資料夾不存在。 + + + Folder is not readable. + 資料夾不可讀取。 + + + Failure + 失敗 + + + Failed to add Scan Folder '%1': %2 + 增加掃描資料夾: '%1': %2 失敗 + + + Parsing error + 分析錯誤 + + + Failed to parse the provided IP filter + IP 過濾檔案分析失敗 + + + Succesfully refreshed + 重新更新成功 + + + Successfuly parsed the provided IP filter: %1 rules were applied. + %1 is a number + 分析 IP 過濾檔案成功: 已套用 %1 個規則。 + + + Successfully refreshed + 重新更新成功 + + + Invalid key + + + + This is not a valid SSL key. + + + + Invalid certificate + + + + This is not a valid SSL certificate. + + + + SSL Certificate (*.crt *.pem) + + + + SSL Key (*.key *.pem) + + + + + pluginSourceDlg + + Plugin source + 外掛來源 + + + Search plugin source: + 搜尋外掛來源: + + + Local file + 本地檔案 + + + Web link + 網頁連結 + + + + preview + + Preview selection + 選擇預覽 + + + File preview + 預覽檔案 + + + The following files support previewing, <br>please select one of them: + 下列檔案支援預覽, <br>請選擇其中一個: + + + Preview + 預覽 + + + Cancel + 取消 + + + + previewSelect + + Preview impossible + 不可預覽 + + + Sorry, we can't preview this file + 抱歉, 我們無法預覽這個檔案 + + + Name + 名稱 + + + Size + 大小 + + + Progress + 進度 + + + + search_engine + + Search + 搜尋 + + + Status: + 狀態: + + + Stopped + 已停止 + + + Download + 下載 + + + Search engines... + 搜尋引擎... + + + Go to description page + 到描述頁 + + + + torrentAdditionDialog + + Unable to decode torrent file: + 無法解碼 torrent 檔案: + + + Choose save path + 選擇儲存路徑 + + + Empty save path + 輸入儲存路徑 + + + Please enter a save path + 請輸入儲存路徑 + + + Save path creation error + 建立儲存路徑錯誤 + + + Could not create the save path + 無法建立儲存路徑 + + + Invalid file selection + 無效的選擇檔案 + + + You must select at least one file in the torrent + 你必須至少選擇 torrent 裡的一個檔案 + + + Priority + 優先度 + + + (%1 left after torrent download) + e.g. (100MiB left after torrent download) + (在 torrent 下載後還剩下 %1) + + + (%1 more are required to download) + e.g. (100MiB more are required to download) + (還有 %1 需要下載) + + + Seeding mode error + 做種模式錯誤 + + + You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. + 你選擇跳過檔案檢查。然而, 本地檔案似乎不在目的地資料夾中。請停用此功能或更新儲存路徑。 + + + Rename... + 重新命名... + + + New name: + 新名稱: + + + The file could not be renamed + 檔案無法重新命名 + + + This name is already in use in this folder. Please use a different name. + 此名稱已在此資料夾中使用。請選擇另一個名稱。 + + + The folder could not be renamed + 此資料夾無法被重新命名 + + + Rename the file + 重新命名檔案 + + + Unable to decode magnet link: + 無法解碼磁性連結: + + + Magnet Link + 磁性連結 + + + Invalid label name + 無效的標籤名稱 + + + Please don't use any special characters in the label name. + 標籤名稱請不要使用任何特殊字元。 + + + This file name contains forbidden characters, please choose a different one. + 檔案名稱包含禁止使用之字元, 請選擇其他名稱。 + + + diff --git a/src/lineedit/lineedit.pri b/src/lineedit/lineedit.pri new file mode 100644 index 000000000..d302c94ec --- /dev/null +++ b/src/lineedit/lineedit.pri @@ -0,0 +1,4 @@ +INCLUDEPATH += $$PWD/src +HEADERS += $$PWD/src/lineedit.h +SOURCES += $$PWD/src/lineedit.cpp +RESOURCES += $$PWD/resources/lineeditimages.qrc diff --git a/src/lineedit/resources/lineeditimages.qrc b/src/lineedit/resources/lineeditimages.qrc new file mode 100644 index 000000000..122e8cbd6 --- /dev/null +++ b/src/lineedit/resources/lineeditimages.qrc @@ -0,0 +1,6 @@ + + + lineeditimages/clear_left.png + lineeditimages/search.png + + diff --git a/src/lineedit/resources/lineeditimages/clear_left.png b/src/lineedit/resources/lineeditimages/clear_left.png new file mode 100644 index 0000000000000000000000000000000000000000..00f9d2d9479b4e635ee3fdedff261dfb53f5e4e0 GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCij$^WEHv zfiws(G8{H+?*}qC3p^r$g4}{2%vhfiKM^R%UgGKN%6^HFQ9zeB#Q6?L6H}76y9>kr z_Wm>bfxJ>r7srr_TT3VG7Hm)uaM5(`R#?cS)V+b(T5-FCa`uKLk0boW*oBVQ8rS5- zGrjXZ)X@6%O^QRtt63bEfR83b=?NsLo%Ri;XQO>bq@x#`SLcSAL9*pdLsXK)` x@duaIR;N`Ct&gWWENy3+8n?ixqwdiAl->t70$y)frv!8WgQu&X%Q~loCIEW+RX+d# literal 0 HcmV?d00001 diff --git a/src/lineedit/resources/lineeditimages/search.png b/src/lineedit/resources/lineeditimages/search.png new file mode 100644 index 0000000000000000000000000000000000000000..19f19d6325c6f32e3441130af62070c259e538cc GIT binary patch literal 528 zcmV+r0`L8aP)v5?U~ZSt%ZV^#7N|2=xvebvm|Fa_x|qp zJLlXJ@qHfv5qS=50WSdyI0N=ob&nYl@qHf=c>{a^=0n~b0zUzjxDI><-c40@UH2pKDwoT3%jNQ?NwL{%KCDzKYrqhApsLrC zdeqEFsZ{cU&W_{!N+y%PfdwEF)T2NOAeBm8h0Kd(S(he#90q>_Xt&#TP#llPkzTK7 znd6r*_z0j@tE~(MgV>~4tya_het!}84s?TX#C6>`@D+GsS=L21oBfeUBu1T1C+T_K zvU#_os&A)Yv*%~PKJX%-kAOLoZ>s9{6bv9DF`&So-?xDlZ~`0vt6>KJ;8`IeOTa1c zG-we0FA1pXPaqHU%+-4l*|<~Xi4M}HgTE`?xHD`FvcNGA2U_=njX@sR1q!!%d5l); ST&oWN0000 +** +** Use, modification and distribution is allowed without limitation, +** warranty, liability or support of any kind. +** +****************************************************************************/ + +#include "lineedit.h" +#include +#include +#include + +LineEdit::LineEdit(QWidget *parent) + : QLineEdit(parent) +{ + searchButton = new QToolButton(this); + QPixmap pixmap1(":/lineeditimages/search.png"); + searchButton->setIcon(QIcon(pixmap1)); + searchButton->setIconSize(pixmap1.size()); + searchButton->setCursor(Qt::ArrowCursor); + searchButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); + clearButton = new QToolButton(this); + QPixmap pixmap2(":/lineeditimages/clear_left.png"); + clearButton->setIcon(QIcon(pixmap2)); + clearButton->setIconSize(pixmap2.size()); + clearButton->setCursor(Qt::ArrowCursor); + clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); + clearButton->setToolTip(tr("Clear the text")); + clearButton->hide(); + connect(clearButton, SIGNAL(clicked()), this, SLOT(clear())); + connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&))); + int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + setStyleSheet(QString("QLineEdit { padding-right: %1px; padding-left: %2px; } ").arg(clearButton->sizeHint().width() + frameWidth + 1).arg(clearButton->sizeHint().width() + frameWidth + 1)); + QSize msz = minimumSizeHint(); + setMinimumSize(qMax(msz.width(), clearButton->sizeHint().width() + searchButton->sizeHint().width() + frameWidth * 2 + 2), + qMax(msz.height(), clearButton->sizeHint().height() + frameWidth * 2 + 2)); +} + +void LineEdit::resizeEvent(QResizeEvent *) +{ + QSize sz = searchButton->sizeHint(); + int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + searchButton->move(rect().left() + frameWidth, (rect().bottom() + 2 - sz.height())/2); + sz = clearButton->sizeHint(); + clearButton->move(rect().right() - frameWidth - sz.width(), + (rect().bottom() + 2 - sz.height())/2); +} + +void LineEdit::updateCloseButton(const QString& text) +{ + clearButton->setVisible(!text.isEmpty()); +} + diff --git a/src/lineedit/src/lineedit.h b/src/lineedit/src/lineedit.h new file mode 100644 index 000000000..a0b51959d --- /dev/null +++ b/src/lineedit/src/lineedit.h @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (c) 2007 Trolltech ASA +** +** Use, modification and distribution is allowed without limitation, +** warranty, liability or support of any kind. +** +****************************************************************************/ + +#ifndef LINEEDIT_H +#define LINEEDIT_H + +#include + +QT_BEGIN_NAMESPACE +class QToolButton; +QT_END_NAMESPACE + +class LineEdit : public QLineEdit +{ + Q_OBJECT + +public: + LineEdit(QWidget *parent = 0); + +protected: + void resizeEvent(QResizeEvent *); + +private slots: + void updateCloseButton(const QString &text); + +private: + QToolButton *clearButton; + QToolButton *searchButton; +}; + +#endif // LIENEDIT_H diff --git a/src/login.ui b/src/login.ui new file mode 100644 index 000000000..21387387f --- /dev/null +++ b/src/login.ui @@ -0,0 +1,299 @@ + + + + + authentication + + + + 0 + 0 + 311 + 231 + + + + Tracker authentication + + + + 9 + + + 6 + + + + + 0 + + + 6 + + + + + + 39 + 39 + + + + + + + + + + + + 16777215 + 39 + + + + + Sans Serif + 13 + 75 + false + true + false + false + + + + Tracker authentication + + + + + + + + + 0 + + + 6 + + + + + + Sans Serif + 9 + 75 + false + true + false + false + + + + Tracker: + + + + + + + + 220 + 0 + + + + + Sans Serif + 9 + 75 + false + true + false + false + + + + + + + + + + + + + Login + + + + 9 + + + 6 + + + + + 0 + + + 6 + + + + + Username: + + + lineUsername + + + + + + + + + + + + 0 + + + 6 + + + + + + 68 + 0 + + + + Password: + + + linePasswd + + + + + + + QLineEdit::Password + + + + + + + + + + + + 0 + + + 6 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Log in + + + + + + + Cancel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + cancelButton + clicked() + authentication + reject() + + + 245 + 195 + + + 179 + 230 + + + + + linePasswd + returnPressed() + loginButton + click() + + + 139 + 158 + + + 122 + 199 + + + + + lineUsername + returnPressed() + linePasswd + setFocus() + + + 199 + 130 + + + 198 + 157 + + + + + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 000000000..269ca02dc --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,322 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include + +#ifndef DISABLE_GUI +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sessionapplication.h" +#include "mainwindow.h" +#include "ico.h" +#else +#include "qtsinglecoreapplication.h" +#include +#include +#include "headlessloader.h" +#endif + +#include "preferences.h" +#include "qinisettings.h" +#if defined(Q_WS_X11) || defined(Q_WS_MAC) +#include +#include +#include "stacktrace.h" +#endif + +#include +#include "misc.h" +#include "preferences.h" + +class UsageDisplay: public QObject { + Q_OBJECT + +public: + static void displayUsage(char* prg_name) { + std::cout << qPrintable(tr("Usage:")) << std::endl; + std::cout << '\t' << prg_name << " --version: " << qPrintable(tr("displays program version")) << std::endl; +#ifndef DISABLE_GUI + std::cout << '\t' << prg_name << " --no-splash: " << qPrintable(tr("disable splash screen")) << std::endl; +#endif + std::cout << '\t' << prg_name << " --help: " << qPrintable(tr("displays this help message")) << std::endl; + std::cout << '\t' << prg_name << " --webui-port=x: " << qPrintable(tr("changes the webui port (current: %1)").arg(QString::number(Preferences().getWebUiPort()))) << std::endl; + std::cout << '\t' << prg_name << " " << qPrintable(tr("[files or urls]: downloads the torrents passed by the user (optional)")) << std::endl; + } +}; + +class LegalNotice: public QObject { + Q_OBJECT + +public: + static bool userAgreesWithNotice() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + if(settings.value(QString::fromUtf8("LegalNotice/Accepted"), false).toBool()) // Already accepted once + return true; +#ifdef DISABLE_GUI + std::cout << std::endl << "*** " << qPrintable(tr("Legal Notice")) << " ***" << std::endl; + std::cout << qPrintable(tr("qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility.\n\nNo further notices will be issued.")) << std::endl << std::endl; + std::cout << qPrintable(tr("Press %1 key to accept and continue...").arg("'y'")) << std::endl; + char ret = getchar(); // Read pressed key + if(ret == 'y' || ret == 'Y') { + // Save the answer + settings.setValue(QString::fromUtf8("LegalNotice/Accepted"), true); + return true; + } + return false; +#else + QMessageBox msgBox; + msgBox.setText(tr("qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility.\n\nNo further notices will be issued.")); + msgBox.setWindowTitle(tr("Legal notice")); + msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole); + QAbstractButton *agree_button = msgBox.addButton(tr("I Agree"), QMessageBox::AcceptRole); + msgBox.show(); // Need to be shown or to moveToCenter does not work + msgBox.move(misc::screenCenter(&msgBox)); + msgBox.exec(); + if(msgBox.clickedButton() == agree_button) { + // Save the answer + settings.setValue(QString::fromUtf8("LegalNotice/Accepted"), true); + return true; + } + return false; +#endif + } +}; + +#include "main.moc" + +#if defined(Q_WS_X11) || defined(Q_WS_MAC) +void sigintHandler(int) { + signal(SIGINT, 0); + qDebug("Catching SIGINT, exiting cleanly"); + qApp->exit(); +} + +void sigtermHandler(int) { + signal(SIGTERM, 0); + qDebug("Catching SIGTERM, exiting cleanly"); + qApp->exit(); +} +void sigsegvHandler(int) { + signal(SIGABRT, 0); + signal(SIGSEGV, 0); + std::cerr << "\n\n*************************************************************\n"; + std::cerr << "Catching SIGSEGV, please report a bug at http://bug.qbittorrent.org\nand provide the following backtrace:\n"; + std::cerr << "qBittorrent version: " << VERSION << std::endl; + print_stacktrace(); + raise(SIGSEGV); +} +void sigabrtHandler(int) { + signal(SIGABRT, 0); + signal(SIGSEGV, 0); + std::cerr << "\n\n*************************************************************\n"; + std::cerr << "Catching SIGABRT, please report a bug at http://bug.qbittorrent.org\nand provide the following backtrace:\n"; + std::cerr << "qBittorrent version: " << VERSION << std::endl; + print_stacktrace(); + raise(SIGABRT); +} +#endif + +// Main +int main(int argc, char *argv[]){ + // Create Application + QString uid = misc::getUserIDString(); +#ifdef DISABLE_GUI + QtSingleCoreApplication app("qBittorrent-"+uid, argc, argv); +#else + SessionApplication app("qBittorrent-"+uid, argc, argv); +#endif + + // Check if qBittorrent is already running for this user + if(app.isRunning()) { + qDebug("qBittorrent is already running for this user."); + //Pass program parameters if any + QString message; + for (int a = 1; a < argc; ++a) { + QString p = QString::fromLocal8Bit(argv[a]); + if(p.startsWith("--")) continue; + message += p; + if (a < argc-1) + message += "|"; + } + if(!message.isEmpty()) { + qDebug("Passing program parameters to running instance..."); + qDebug("Message: %s", qPrintable(message)); + app.sendMessage(message); + } + return 0; + } + + Preferences pref; +#ifndef DISABLE_GUI + bool no_splash = false; +#endif + + // Load translation + QString locale = pref.getLocale(); + QTranslator qtTranslator; + QTranslator translator; + if(locale.isEmpty()){ + locale = QLocale::system().name(); + pref.setLocale(locale); + } + if(qtTranslator.load( + QString::fromUtf8("qt_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath) + )){ + qDebug("Qt %s locale recognized, using translation.", qPrintable(locale)); + }else{ + qDebug("Qt %s locale unrecognized, using default (en_GB).", qPrintable(locale)); + } + app.installTranslator(&qtTranslator); + if(translator.load(QString::fromUtf8(":/lang/qbittorrent_") + locale)){ + qDebug("%s locale recognized, using translation.", qPrintable(locale)); + }else{ + qDebug("%s locale unrecognized, using default (en_GB).", qPrintable(locale)); + } + app.installTranslator(&translator); +#ifndef DISABLE_GUI + if(locale.startsWith("ar")) { + qDebug("Right to Left mode"); + app.setLayoutDirection(Qt::RightToLeft); + } else { + app.setLayoutDirection(Qt::LeftToRight); + } +#endif + app.setApplicationName(QString::fromUtf8("qBittorrent")); + + // Check for executable parameters + if(argc > 1){ + if(QString::fromLocal8Bit(argv[1]) == QString::fromUtf8("--version")){ + std::cout << "qBittorrent " << VERSION << '\n'; + return 0; + } + if(QString::fromLocal8Bit(argv[1]) == QString::fromUtf8("--help")){ + UsageDisplay::displayUsage(argv[0]); + return 0; + } + + for(int i=1; i 0 && new_port <= 65535) { + Preferences().setWebUiPort(new_port); + } + } + } +#ifndef DISABLE_GUI + } +#endif + } + } + +#ifndef DISABLE_GUI + if(pref.isSlashScreenDisabled()) { + no_splash = true; + } + QSplashScreen *splash = 0; + if(!no_splash) { + QPixmap splash_img(":/Icons/skin/splash.png"); + QPainter painter(&splash_img); + QString version = VERSION; + painter.setPen(QPen(Qt::white)); + painter.setFont(QFont("Arial", 22, QFont::Black)); + painter.drawText(224 - painter.fontMetrics().width(version), 270, version); + splash = new QSplashScreen(splash_img, Qt::WindowStaysOnTopHint); + QTimer::singleShot(1500, splash, SLOT(deleteLater())); + splash->show(); + app.processEvents(); + } +#endif + // Set environment variable + if(putenv((char*)"QBITTORRENT="VERSION)) { + std::cerr << "Couldn't set environment variable...\n"; + } + +#ifndef DISABLE_GUI + app.setStyleSheet("QStatusBar::item { border-width: 0; }"); +#endif + + if(!LegalNotice::userAgreesWithNotice()) { + return 0; + } +#ifndef DISABLE_GUI + app.setQuitOnLastWindowClosed(false); +#endif +#if defined(Q_WS_X11) || defined(Q_WS_MAC) + signal(SIGABRT, sigabrtHandler); + signal(SIGTERM, sigtermHandler); + signal(SIGINT, sigintHandler); + signal(SIGSEGV, sigsegvHandler); +#endif + // Read torrents given on command line + QStringList torrentCmdLine = app.arguments(); + // Remove first argument (program name) + torrentCmdLine.removeFirst(); +#ifndef QT_NO_DEBUG_OUTPUT + foreach(const QString &argument, torrentCmdLine) { + qDebug() << "Command line argument:" << argument; + } +#endif + +#ifndef DISABLE_GUI + MainWindow window(0, torrentCmdLine); + QObject::connect(&app, SIGNAL(messageReceived(const QString&)), + &window, SLOT(processParams(const QString&))); + app.setActivationWindow(&window); +#else + // Load Headless class + HeadlessLoader loader(torrentCmdLine); + QObject::connect(&app, SIGNAL(messageReceived(const QString&)), + &loader, SLOT(processParams(const QString&))); +#endif + + int ret = app.exec(); + qDebug("Application has exited"); + return ret; +} + + diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp new file mode 100644 index 000000000..d28109acf --- /dev/null +++ b/src/mainwindow.cpp @@ -0,0 +1,1384 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#if defined(Q_WS_X11) && defined(QT_DBUS_LIB) +#include +#include "notifications.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "transferlistwidget.h" +#include "misc.h" +#include "torrentcreatordlg.h" +#include "downloadfromurldlg.h" +#include "torrentadditiondlg.h" +#include "searchengine.h" +#include "rss_imp.h" +#include "qbtsession.h" +#include "about_imp.h" +#include "trackerlogin.h" +#include "options_imp.h" +#include "speedlimitdlg.h" +#include "preferences.h" +#include "trackerlist.h" +#include "peerlistwidget.h" +#include "torrentpersistentdata.h" +#include "transferlistfilterswidget.h" +#include "propertieswidget.h" +#include "statusbar.h" +#include "hidabletabwidget.h" +#include "qinisettings.h" +#include "torrentimportdlg.h" +#include "rsssettings.h" +#include "torrentmodel.h" +#include "executionlog.h" +#include "iconprovider.h" +#ifdef Q_WS_MAC +#include "qmacapplication.h" +void qt_mac_set_dock_menu(QMenu *menu); +#endif +#include "lineedit.h" +#include "sessionapplication.h" +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) +#include "programupdater.h" +#endif +#include "powermanagement.h" + +using namespace libtorrent; + +#define TIME_TRAY_BALLOON 5000 +#define PREVENT_SUSPEND_INTERVAL 60000 + +/***************************************************** + * * + * GUI * + * * + *****************************************************/ + +// Constructor +MainWindow::MainWindow(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), m_posInitialized(false), force_exit(false) { + setupUi(this); + + Preferences pref; + ui_locked = pref.isUILocked(); + setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION))); + displaySpeedInTitle = pref.speedInTitleBar(); + // Clean exit on log out + connect(static_cast(qApp), SIGNAL(sessionIsShuttingDown()), this, SLOT(deleteBTSession())); + // Setting icons + this->setWindowIcon(QIcon(QString::fromUtf8(":/Icons/skin/qbittorrent32.png"))); + actionOpen->setIcon(IconProvider::instance()->getIcon("list-add")); + actionDownload_from_URL->setIcon(IconProvider::instance()->getIcon("insert-link")); + actionSet_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))); + actionSet_download_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/download.png"))); + actionSet_global_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))); + actionSet_global_download_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/download.png"))); + actionCreate_torrent->setIcon(IconProvider::instance()->getIcon("document-edit")); + actionAbout->setIcon(IconProvider::instance()->getIcon("help-about")); + actionBugReport->setIcon(IconProvider::instance()->getIcon("tools-report-bug")); + actionDecreasePriority->setIcon(IconProvider::instance()->getIcon("go-down")); + actionDelete->setIcon(IconProvider::instance()->getIcon("list-remove")); + actionDocumentation->setIcon(IconProvider::instance()->getIcon("help-contents")); + actionDonate_money->setIcon(IconProvider::instance()->getIcon("wallet-open")); + actionExit->setIcon(IconProvider::instance()->getIcon("application-exit")); + actionIncreasePriority->setIcon(IconProvider::instance()->getIcon("go-up")); + actionLock_qBittorrent->setIcon(IconProvider::instance()->getIcon("object-locked")); + actionOptions->setIcon(IconProvider::instance()->getIcon("preferences-system")); + actionPause->setIcon(IconProvider::instance()->getIcon("media-playback-pause")); + actionPause_All->setIcon(IconProvider::instance()->getIcon("media-playback-pause")); + actionStart->setIcon(IconProvider::instance()->getIcon("media-playback-start")); + actionStart_All->setIcon(IconProvider::instance()->getIcon("media-playback-start")); + action_Import_Torrent->setIcon(IconProvider::instance()->getIcon("document-import")); + menuAuto_Shutdown_on_downloads_completion->setIcon(IconProvider::instance()->getIcon("application-exit")); + + QMenu *startAllMenu = new QMenu(this); + startAllMenu->addAction(actionStart_All); + actionStart->setMenu(startAllMenu); + QMenu *pauseAllMenu = new QMenu(this); + pauseAllMenu->addAction(actionPause_All); + actionPause->setMenu(pauseAllMenu); + QMenu *lockMenu = new QMenu(this); + QAction *defineUiLockPasswdAct = lockMenu->addAction(tr("Set the password...")); + connect(defineUiLockPasswdAct, SIGNAL(triggered()), this, SLOT(defineUILockPassword())); + actionLock_qBittorrent->setMenu(lockMenu); + // Creating Bittorrent session + connect(QBtSession::instance(), SIGNAL(fullDiskError(QTorrentHandle, QString)), this, SLOT(fullDiskError(QTorrentHandle, QString))); + connect(QBtSession::instance(), SIGNAL(finishedTorrent(QTorrentHandle)), this, SLOT(finishedTorrent(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(trackerAuthenticationRequired(QTorrentHandle)), this, SLOT(trackerAuthenticationRequired(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString))); + connect(QBtSession::instance(), SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString))); + connect(QBtSession::instance(), SIGNAL(alternativeSpeedsModeChanged(bool)), this, SLOT(updateAltSpeedsBtn(bool))); + connect(QBtSession::instance(), SIGNAL(recursiveTorrentDownloadPossible(QTorrentHandle)), this, SLOT(askRecursiveTorrentDownloadConfirmation(QTorrentHandle))); +#ifdef Q_WS_MAC + connect(static_cast(qApp), SIGNAL(newFileOpenMacEvent(QString)), this, SLOT(processParams(QString))); +#endif + + qDebug("create tabWidget"); + tabs = new HidableTabWidget(); + connect(tabs, SIGNAL(currentChanged(int)), this, SLOT(tab_changed(int))); + vSplitter = new QSplitter(Qt::Horizontal); + //vSplitter->setChildrenCollapsible(false); + hSplitter = new QSplitter(Qt::Vertical); + hSplitter->setChildrenCollapsible(false); + hSplitter->setContentsMargins(0, 4, 0, 0); + + // Transfer List tab + transferList = new TransferListWidget(hSplitter, this, QBtSession::instance()); + properties = new PropertiesWidget(hSplitter, this, transferList); + transferListFilters = new TransferListFiltersWidget(vSplitter, transferList); + hSplitter->addWidget(transferList); + hSplitter->addWidget(properties); + vSplitter->addWidget(transferListFilters); + vSplitter->addWidget(hSplitter); + vSplitter->setCollapsible(0, true); + vSplitter->setCollapsible(1, false); + tabs->addTab(vSplitter, IconProvider::instance()->getIcon("folder-remote"), tr("Transfers")); + + vboxLayout->addWidget(tabs); + // Name filter + search_filter = new LineEdit(); + connect(search_filter, SIGNAL(textChanged(QString)), transferList, SLOT(applyNameFilter(QString))); + QAction *searchFilterAct = toolBar->insertWidget(actionLock_qBittorrent, search_filter); + search_filter->setFixedWidth(200); + QWidget *spacer = new QWidget(this); + spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + toolBar->insertWidget(searchFilterAct, spacer); + + + prioSeparator = toolBar->insertSeparator(actionDecreasePriority); + prioSeparatorMenu = menu_Edit->insertSeparator(actionDecreasePriority); + + // Transfer list slots + connect(actionStart, SIGNAL(triggered()), transferList, SLOT(startSelectedTorrents())); + connect(actionStart_All, SIGNAL(triggered()), QBtSession::instance(), SLOT(resumeAllTorrents())); + connect(actionPause, SIGNAL(triggered()), transferList, SLOT(pauseSelectedTorrents())); + connect(actionPause_All, SIGNAL(triggered()), QBtSession::instance(), SLOT(pauseAllTorrents())); + connect(actionDelete, SIGNAL(triggered()), transferList, SLOT(deleteSelectedTorrents())); + connect(actionIncreasePriority, SIGNAL(triggered()), transferList, SLOT(increasePrioSelectedTorrents())); + connect(actionDecreasePriority, SIGNAL(triggered()), transferList, SLOT(decreasePrioSelectedTorrents())); + + m_pwr = new PowerManagement(this); + preventTimer = new QTimer(this); + connect(preventTimer, SIGNAL(timeout()), SLOT(checkForActiveTorrents())); + + // Configure BT session according to options + loadPreferences(false); + + // Start connection checking timer + guiUpdater = new QTimer(this); + connect(guiUpdater, SIGNAL(timeout()), this, SLOT(updateGUI())); + guiUpdater->start(2000); + // Accept drag 'n drops + setAcceptDrops(true); + createKeyboardShortcuts(); + // Create status bar + status_bar = new StatusBar(QMainWindow::statusBar()); + connect(status_bar->connectionStatusButton(), SIGNAL(clicked()), SLOT(showConnectionSettings())); + connect(actionUse_alternative_speed_limits, SIGNAL(triggered()), status_bar, SLOT(toggleAlternativeSpeeds())); + +#ifdef Q_WS_MAC + setUnifiedTitleAndToolBarOnMac(true); +#endif + + // View settings + actionTop_tool_bar->setChecked(pref.isToolbarDisplayed()); + actionSpeed_in_title_bar->setChecked(pref.speedInTitleBar()); + actionRSS_Reader->setChecked(RssSettings().isRSSEnabled()); + actionSearch_engine->setChecked(pref.isSearchEnabled()); + actionExecution_Logs->setChecked(pref.isExecutionLogEnabled()); + displaySearchTab(actionSearch_engine->isChecked()); + displayRSSTab(actionRSS_Reader->isChecked()); + on_actionExecution_Logs_triggered(actionExecution_Logs->isChecked()); + + // Auto shutdown actions + QActionGroup * autoShutdownGroup = new QActionGroup(this); + autoShutdownGroup->setExclusive(true); + autoShutdownGroup->addAction(actionAutoShutdown_Disabled); + autoShutdownGroup->addAction(actionAutoExit_qBittorrent); + autoShutdownGroup->addAction(actionAutoShutdown_system); + autoShutdownGroup->addAction(actionAutoSuspend_system); +#if !defined(Q_WS_X11) || defined(QT_DBUS_LIB) + actionAutoShutdown_system->setChecked(pref.shutdownWhenDownloadsComplete()); + actionAutoSuspend_system->setChecked(pref.suspendWhenDownloadsComplete()); +#else + actionAutoShutdown_system->setDisabled(true); + actionAutoSuspend_system->setDisabled(true); +#endif + actionAutoExit_qBittorrent->setChecked(pref.shutdownqBTWhenDownloadsComplete()); + + if(!autoShutdownGroup->checkedAction()) + actionAutoShutdown_Disabled->setChecked(true); + + // Load Window state and sizes + readSettings(); + + if(!ui_locked) { + if(pref.startMinimized()) + showMinimized(); + else { + show(); + activateWindow(); + raise(); + } + } + + properties->readSettings(); + + // Start watching the executable for updates + executable_watcher = new QFileSystemWatcher(); + connect(executable_watcher, SIGNAL(fileChanged(QString)), this, SLOT(notifyOfUpdate(QString))); + executable_watcher->addPath(qApp->applicationFilePath()); + + // Resume unfinished torrents + QBtSession::instance()->startUpTorrents(); + // Add torrent given on command line + processParams(torrentCmdLine); + + // Populate the transfer list + transferList->getSourceModel()->populate(); + + // Update the number of torrents (tab) + updateNbTorrents(); + connect(transferList->getSourceModel(), SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(updateNbTorrents())); + connect(transferList->getSourceModel(), SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(updateNbTorrents())); + + qDebug("GUI Built"); +#ifdef Q_WS_WIN + if(!pref.neverCheckFileAssoc() && !Preferences::isFileAssocOk()) { + if(QMessageBox::question(0, tr("Torrent file association"), + tr("qBittorrent is not the default application to open torrent files or Magnet links.\nDo you want to associate qBittorrent to torrent files and Magnet links?"), + QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) { + Preferences::setFileAssoc(); + } else { + pref.setNeverCheckFileAssoc(); + } + } +#endif +#ifdef Q_WS_MAC + qt_mac_set_dock_menu(getTrayIconMenu()); +#endif +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) + // Check for update + if(pref.isUpdateCheckEnabled()) { + ProgramUpdater *updater = new ProgramUpdater(this); + connect(updater, SIGNAL(updateCheckFinished(bool, QString)), SLOT(handleUpdateCheckFinished(bool, QString))); + updater->checkForUpdates(); + } +#endif +} + +void MainWindow::deleteBTSession() { + guiUpdater->stop(); + status_bar->stopTimer(); + QBtSession::drop(); + m_pwr->setActivityState(false); + // Save window size, columns size + writeSettings(); + // Accept exit + qApp->exit(); +} + +// Destructor +MainWindow::~MainWindow() { + qDebug("GUI destruction"); + hide(); +#ifdef Q_WS_MAC + // Workaround to avoid bug http://bugreports.qt.nokia.com/browse/QTBUG-7305 + setUnifiedTitleAndToolBarOnMac(false); +#endif + disconnect(tabs, SIGNAL(currentChanged(int)), this, SLOT(tab_changed(int))); + // Delete other GUI objects + if(executable_watcher) + delete executable_watcher; + delete status_bar; + delete search_filter; + delete transferList; + delete guiUpdater; + if(createTorrentDlg) + delete createTorrentDlg; + if(m_executionLog) + delete m_executionLog; + if(aboutDlg) + delete aboutDlg; + if(options) + delete options; + if(downloadFromURLDialog) + delete downloadFromURLDialog; + if(rssWidget) + delete rssWidget; + if(searchEngine) + delete searchEngine; + delete transferListFilters; + delete properties; + delete hSplitter; + delete vSplitter; + if(systrayCreator) { + delete systrayCreator; + } + if(systrayIcon) { + delete systrayIcon; + } + if(myTrayIconMenu) { + delete myTrayIconMenu; + } + delete tabs; + // Keyboard shortcuts + delete switchSearchShortcut; + delete switchSearchShortcut2; + delete switchTransferShortcut; + delete switchRSSShortcut; + IconProvider::drop(); + // Delete QBtSession::instance() object + m_pwr->setActivityState(false); + qDebug("Deleting QBtSession::instance()"); + QBtSession::drop(); + qDebug("Exiting GUI destructor..."); +} + +void MainWindow::defineUILockPassword() { + QString old_pass_md5 = Preferences().getUILockPasswordMD5(); + if(old_pass_md5.isNull()) old_pass_md5 = ""; + bool ok = false; + QString new_clear_password = QInputDialog::getText(this, tr("UI lock password"), tr("Please type the UI lock password:"), QLineEdit::Password, old_pass_md5, &ok); + if(ok) { + new_clear_password = new_clear_password.trimmed(); + if(new_clear_password.size() < 3) { + QMessageBox::warning(this, tr("Invalid password"), tr("The password should contain at least 3 characters")); + return; + } + if(new_clear_password != old_pass_md5) { + Preferences().setUILockPassword(new_clear_password); + } + QMessageBox::information(this, tr("Password update"), tr("The UI lock password has been successfully updated")); + } +} + +void MainWindow::on_actionLock_qBittorrent_triggered() { + Preferences pref; + // Check if there is a password + if(pref.getUILockPasswordMD5().isEmpty()) { + // Ask for a password + bool ok = false; + QString clear_password = QInputDialog::getText(this, tr("UI lock password"), tr("Please type the UI lock password:"), QLineEdit::Password, "", &ok); + if(!ok) return; + pref.setUILockPassword(clear_password); + } + // Lock the interface + ui_locked = true; + pref.setUILocked(true); + myTrayIconMenu->setEnabled(false); + hide(); +} + +void MainWindow::displayRSSTab(bool enable) { + if(enable) { + // RSS tab + if(!rssWidget) { + rssWidget = new RSSImp(tabs); + int index_tab = tabs->addTab(rssWidget, tr("RSS")); + tabs->setTabIcon(index_tab, IconProvider::instance()->getIcon("application-rss+xml")); + } + } else { + if(rssWidget) { + delete rssWidget; + } + } +} + +void MainWindow::displaySearchTab(bool enable) { + if(enable) { + // RSS tab + if(!searchEngine) { + searchEngine = new SearchEngine(this); + tabs->insertTab(1, searchEngine, IconProvider::instance()->getIcon("edit-find"), tr("Search")); + } + } else { + if(searchEngine) { + delete searchEngine; + } + } +} + +void MainWindow::updateNbTorrents() { + tabs->setTabText(0, tr("Transfers (%1)").arg(transferList->getSourceModel()->rowCount())); +} + +void MainWindow::on_actionWebsite_triggered() const { + QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://www.qbittorrent.org"))); +} + +void MainWindow::on_actionDocumentation_triggered() const { + QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://doc.qbittorrent.org"))); +} + +void MainWindow::on_actionBugReport_triggered() const { + QDesktopServices::openUrl(QUrl(QString::fromUtf8("http://bugs.qbittorrent.org"))); +} + +void MainWindow::tab_changed(int new_tab) { + Q_UNUSED(new_tab); + // We cannot rely on the index new_tab + // because the tab order is undetermined now + if(tabs->currentWidget() == vSplitter) { + qDebug("Changed tab to transfer list, refreshing the list"); + properties->loadDynamicData(); + return; + } + if(tabs->currentWidget() == searchEngine) { + qDebug("Changed tab to search engine, giving focus to search input"); + searchEngine->giveFocusToSearchInput(); + } +} + +void MainWindow::writeSettings() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.beginGroup(QString::fromUtf8("MainWindow")); + settings.setValue("geometry", saveGeometry()); + // Splitter size + settings.setValue(QString::fromUtf8("vsplitterState"), vSplitter->saveState()); + settings.endGroup(); + properties->saveSettings(); +} + +void MainWindow::readSettings() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.beginGroup(QString::fromUtf8("MainWindow")); + if(settings.contains("geometry")) { + if(restoreGeometry(settings.value("geometry").toByteArray())) + m_posInitialized = true; + } + const QByteArray splitterState = settings.value("vsplitterState").toByteArray(); + if(splitterState.isEmpty()) { + // Default sizes + vSplitter->setSizes(QList() << 120 << vSplitter->width()-120); + } else { + vSplitter->restoreState(splitterState); + } + settings.endGroup(); +} + +void MainWindow::balloonClicked() { + if(isHidden()) { + show(); + if(isMinimized()) { + showNormal(); + } + raise(); + activateWindow(); + } +} + +// called when a torrent has finished +void MainWindow::finishedTorrent(const QTorrentHandle& h) const { + if(!TorrentPersistentData::isSeed(h.hash())) + showNotificationBaloon(tr("Download completion"), tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(h.name())); +} + +// Notification when disk is full +void MainWindow::fullDiskError(const QTorrentHandle& h, QString msg) const { + if(!h.is_valid()) return; + showNotificationBaloon(tr("I/O Error", "i.e: Input/Output Error"), tr("An I/O error occured for torrent %1.\n Reason: %2", "e.g: An error occured for torrent xxx.avi.\n Reason: disk is full.").arg(h.name()).arg(msg)); +} + +void MainWindow::createKeyboardShortcuts() { + actionCreate_torrent->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+N"))); + actionOpen->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+O"))); + actionExit->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Q"))); + switchTransferShortcut = new QShortcut(QKeySequence(tr("Alt+1", "shortcut to switch to first tab")), this); + connect(switchTransferShortcut, SIGNAL(activated()), this, SLOT(displayTransferTab())); + switchSearchShortcut = new QShortcut(QKeySequence(tr("Alt+2", "shortcut to switch to third tab")), this); + connect(switchSearchShortcut, SIGNAL(activated()), this, SLOT(displaySearchTab())); + switchSearchShortcut2 = new QShortcut(QKeySequence(tr("Ctrl+F", "shortcut to switch to search tab")), this); + connect(switchSearchShortcut2, SIGNAL(activated()), this, SLOT(displaySearchTab())); + switchRSSShortcut = new QShortcut(QKeySequence(tr("Alt+3", "shortcut to switch to fourth tab")), this); + connect(switchRSSShortcut, SIGNAL(activated()), this, SLOT(displayRSSTab())); + actionDocumentation->setShortcut(QKeySequence("F1")); + actionOptions->setShortcut(QKeySequence(QString::fromUtf8("Alt+O"))); + actionDelete->setShortcut(QKeySequence(QString::fromUtf8("Del"))); + actionStart->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+S"))); + actionStart_All->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Shift+S"))); + actionPause->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+P"))); + actionPause_All->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Shift+P"))); + actionDecreasePriority->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+-"))); + actionIncreasePriority->setShortcut(QKeySequence(QString::fromUtf8("Ctrl++"))); +} + +// Keyboard shortcuts slots +void MainWindow::displayTransferTab() const { + tabs->setCurrentWidget(transferList); +} + +void MainWindow::displaySearchTab() const { + if(searchEngine) + tabs->setCurrentWidget(searchEngine); +} + +void MainWindow::displayRSSTab() const { + if(rssWidget) + tabs->setCurrentWidget(rssWidget); +} + +// End of keyboard shortcuts slots + +void MainWindow::askRecursiveTorrentDownloadConfirmation(const QTorrentHandle &h) { + Preferences pref; + if(pref.recursiveDownloadDisabled()) return; + // Get Torrent name + QString torrent_name; + try { + torrent_name = h.name(); + } catch(invalid_handle&){ + return; + } + QMessageBox confirmBox(QMessageBox::Question, tr("Recursive download confirmation"), tr("The torrent %1 contains torrent files, do you want to proceed with their download?").arg(torrent_name)); + QPushButton *yes = confirmBox.addButton(tr("Yes"), QMessageBox::YesRole); + /*QPushButton *no = */confirmBox.addButton(tr("No"), QMessageBox::NoRole); + QPushButton *never = confirmBox.addButton(tr("Never"), QMessageBox::NoRole); + confirmBox.exec(); + if(confirmBox.clickedButton() == 0) return; + if(confirmBox.clickedButton() == yes) { + QBtSession::instance()->recursiveTorrentDownload(h); + return; + } + if(confirmBox.clickedButton() == never) { + pref.disableRecursiveDownload(); + } +} + +void MainWindow::handleDownloadFromUrlFailure(QString url, QString reason) const{ + // Display a message box + showNotificationBaloon(tr("Url download error"), tr("Couldn't download file at url: %1, reason: %2.").arg(url).arg(reason)); +} + +void MainWindow::on_actionSet_global_upload_limit_triggered() { + qDebug("actionSet_global_upload_limit_triggered"); + bool ok; +#if LIBTORRENT_VERSION_MINOR > 15 + int cur_limit = QBtSession::instance()->getSession()->settings().upload_rate_limit; +#else + int cur_limit = QBtSession::instance()->getSession()->upload_rate_limit(); +#endif + const long new_limit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Global Upload Speed Limit"), cur_limit); + if(ok) { + qDebug("Setting global upload rate limit to %.1fKb/s", new_limit/1024.); + QBtSession::instance()->setUploadRateLimit(new_limit); + if(new_limit <= 0) + Preferences().setGlobalUploadLimit(-1); + else + Preferences().setGlobalUploadLimit(new_limit/1024.); + } +} + +void MainWindow::on_actionSet_global_download_limit_triggered() { + qDebug("actionSet_global_download_limit_triggered"); + bool ok; +#if LIBTORRENT_VERSION_MINOR > 15 + int cur_limit = QBtSession::instance()->getSession()->settings().download_rate_limit; +#else + int cur_limit = QBtSession::instance()->getSession()->download_rate_limit(); +#endif + const long new_limit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Global Download Speed Limit"), cur_limit); + if(ok) { + qDebug("Setting global download rate limit to %.1fKb/s", new_limit/1024.); + QBtSession::instance()->setDownloadRateLimit(new_limit); + if(new_limit <= 0) + Preferences().setGlobalDownloadLimit(-1); + else + Preferences().setGlobalDownloadLimit(new_limit/1024.); + } +} + +// Necessary if we want to close the window +// in one time if "close to systray" is enabled +void MainWindow::on_actionExit_triggered() { + force_exit = true; + close(); +} + +QWidget* MainWindow::getCurrentTabWidget() const { + if(isMinimized() || !isVisible()) + return 0; + if(tabs->currentIndex() == 0) + return transferList; + return tabs->currentWidget(); +} + +void MainWindow::setTabText(int index, QString text) const { + tabs->setTabText(index, text); +} + +bool MainWindow::unlockUI() { + bool ok = false; + QString clear_password = QInputDialog::getText(this, tr("UI lock password"), tr("Please type the UI lock password:"), QLineEdit::Password, "", &ok); + if(!ok) return false; + Preferences pref; + QString real_pass_md5 = pref.getUILockPasswordMD5(); + QCryptographicHash md5(QCryptographicHash::Md5); + md5.addData(clear_password.toLocal8Bit()); + QString password_md5 = md5.result().toHex(); + if(real_pass_md5 == password_md5) { + ui_locked = false; + pref.setUILocked(false); + myTrayIconMenu->setEnabled(true); + return true; + } + QMessageBox::warning(this, tr("Invalid password"), tr("The password is invalid")); + return false; +} + +void MainWindow::notifyOfUpdate(QString) { + // Show restart message + status_bar->showRestartRequired(); + // Delete the executable watcher + delete executable_watcher; + executable_watcher = 0; +} + +// Toggle Main window visibility +void MainWindow::toggleVisibility(QSystemTrayIcon::ActivationReason e) { + if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) { + if(isHidden()) { + if(ui_locked) { + // Ask for UI lock password + if(!unlockUI()) + return; + } + show(); + if(isMinimized()) { + if(isMaximized()) { + showMaximized(); + }else{ + showNormal(); + } + } + raise(); + activateWindow(); + }else{ + hide(); + } + } +} + +// Display About Dialog +void MainWindow::on_actionAbout_triggered() { + //About dialog + if(aboutDlg) { + aboutDlg->setFocus(); + } else { + aboutDlg = new about(this); + } +} + +void MainWindow::showEvent(QShowEvent *e) { + qDebug("** Show Event **"); + + // Update status filters list height + transferListFilters->getStatusFilters()->updateHeight(); + + if(getCurrentTabWidget() == transferList) { + properties->loadDynamicData(); + } + + e->accept(); + + // Make sure the window is initially centered + if(!m_posInitialized) { + move(misc::screenCenter(this)); + m_posInitialized = true; + } +} + +// Called when we close the program +void MainWindow::closeEvent(QCloseEvent *e) { + Preferences pref; + const bool goToSystrayOnExit = pref.closeToTray(); + if(!force_exit && systrayIcon && goToSystrayOnExit && !this->isHidden()) { + hide(); + e->accept(); + return; + } + if(pref.confirmOnExit() && QBtSession::instance()->hasActiveTorrents()) { + if(e->spontaneous() || force_exit) { + if(!isVisible()) + show(); + QMessageBox confirmBox(QMessageBox::Question, tr("Exiting qBittorrent"), + tr("Some files are currently transferring.\nAre you sure you want to quit qBittorrent?"), + QMessageBox::NoButton, this); + QPushButton *noBtn = confirmBox.addButton(tr("No"), QMessageBox::NoRole); + QPushButton *yesBtn = confirmBox.addButton(tr("Yes"), QMessageBox::YesRole); + QPushButton *alwaysBtn = confirmBox.addButton(tr("Always"), QMessageBox::YesRole); + confirmBox.setDefaultButton(yesBtn); + confirmBox.exec(); + if(!confirmBox.clickedButton() || confirmBox.clickedButton() == noBtn) { + // Cancel exit + e->ignore(); + force_exit = false; + return; + } + if(confirmBox.clickedButton() == alwaysBtn) { + // Remember choice + Preferences().setConfirmOnExit(false); + } + } + } + hide(); + if(systrayIcon) { + // Hide tray icon + systrayIcon->hide(); + } + // Save window size, columns size + writeSettings(); + // Accept exit + e->accept(); + qApp->exit(); +} + +// Display window to create a torrent +void MainWindow::on_actionCreate_torrent_triggered() { + if(createTorrentDlg) { + createTorrentDlg->setFocus(); + } else { + createTorrentDlg = new TorrentCreatorDlg(this); + connect(createTorrentDlg, SIGNAL(torrent_to_seed(QString)), this, SLOT(addTorrent(QString))); + } +} + +bool MainWindow::event(QEvent * e) { + switch(e->type()) { + case QEvent::WindowStateChange: { + qDebug("Window change event"); + //Now check to see if the window is minimised + if(isMinimized()) { + qDebug("minimisation"); + if(systrayIcon && Preferences().minimizeToTray()) { + qDebug("Has active window: %d", (int)(qApp->activeWindow() != 0)); + // Check if there is a modal window + bool has_modal_window = false; + foreach (QWidget *widget, QApplication::allWidgets()) { + if(widget->isModal()) { + has_modal_window = true; + break; + } + } + // Iconify if there is no modal window + if(!has_modal_window) { + qDebug("Minimize to Tray enabled, hiding!"); + e->accept(); + QTimer::singleShot(0, this, SLOT(hide())); + return true; + } + } + } + break; + } +#ifdef Q_WS_MAC + case QEvent::ToolBarChange: { + qDebug("MAC: Received a toolbar change event!"); + bool ret = QMainWindow::event(e); + + qDebug("MAC: new toolbar visibility is %d", !actionTop_tool_bar->isChecked()); + actionTop_tool_bar->toggle(); + Preferences().setToolbarDisplayed(actionTop_tool_bar->isChecked()); + return ret; + } +#endif + default: + break; + } + return QMainWindow::event(e); +} + +// Action executed when a file is dropped +void MainWindow::dropEvent(QDropEvent *event) { + event->acceptProposedAction(); + QStringList files; + if(event->mimeData()->hasUrls()) { + const QList urls = event->mimeData()->urls(); + foreach(const QUrl &url, urls) { + if(!url.isEmpty()) { + if(url.scheme().compare("file", Qt::CaseInsensitive) == 0) + files << url.toLocalFile(); + else + files << url.toString(); + } + } + } else { + files = event->mimeData()->text().split(QString::fromUtf8("\n")); + } + // Add file to download list + Preferences pref; + const bool useTorrentAdditionDialog = pref.useAdditionDialog(); + foreach(QString file, files) { + qDebug("Dropped file %s on download list", qPrintable(file)); + if(misc::isUrl(file)) { + QBtSession::instance()->downloadFromUrl(file); + continue; + } + // Bitcomet or Magnet link + if(file.startsWith("bc://bt/", Qt::CaseInsensitive)) { + qDebug("Converting bc link to magnet link"); + file = misc::bcLinkToMagnet(file); + } + if(file.startsWith("magnet:", Qt::CaseInsensitive)) { + if(useTorrentAdditionDialog) { + torrentAdditionDialog *dialog = new torrentAdditionDialog(this); + dialog->showLoadMagnetURI(file); + } else { + QBtSession::instance()->addMagnetUri(file); + } + continue; + } + // Local file + if(useTorrentAdditionDialog) { + torrentAdditionDialog *dialog = new torrentAdditionDialog(this); + if(file.startsWith("file:", Qt::CaseInsensitive)) + file = QUrl(file).toLocalFile(); + dialog->showLoad(file); + }else{ + QBtSession::instance()->addTorrent(file); + } + } +} + +// Decode if we accept drag 'n drop or not +void MainWindow::dragEnterEvent(QDragEnterEvent *event) { + foreach(const QString &mime, event->mimeData()->formats()){ + qDebug("mimeData: %s", mime.toLocal8Bit().data()); + } + if (event->mimeData()->hasFormat(QString::fromUtf8("text/plain")) || event->mimeData()->hasFormat(QString::fromUtf8("text/uri-list"))) { + event->acceptProposedAction(); + } +} + +/***************************************************** + * * + * Torrent * + * * + *****************************************************/ + +// Display a dialog to allow user to add +// torrents to download list +void MainWindow::on_actionOpen_triggered() { + Preferences pref; + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + // Open File Open Dialog + // Note: it is possible to select more than one file + const QStringList pathsList = QFileDialog::getOpenFileNames(0, + tr("Open Torrent Files"), settings.value(QString::fromUtf8("MainWindowLastDir"), QDir::homePath()).toString(), + tr("Torrent Files")+QString::fromUtf8(" (*.torrent)")); + if(!pathsList.empty()) { + const bool useTorrentAdditionDialog = pref.useAdditionDialog(); + const uint listSize = pathsList.size(); + for(uint i=0; ishowLoad(pathsList.at(i)); + }else{ + QBtSession::instance()->addTorrent(pathsList.at(i)); + } + } + // Save last dir to remember it + QStringList top_dir = pathsList.at(0).split(QDir::separator()); + top_dir.removeLast(); + settings.setValue(QString::fromUtf8("MainWindowLastDir"), top_dir.join(QDir::separator())); + } +} + +// As program parameters, we can get paths or urls. +// This function parse the parameters and call +// the right addTorrent function, considering +// the parameter type. +void MainWindow::processParams(const QString& params_str) { + processParams(params_str.split("|", QString::SkipEmptyParts)); +} + +void MainWindow::processParams(const QStringList& params) { + Preferences pref; + const bool useTorrentAdditionDialog = pref.useAdditionDialog(); + foreach(QString param, params) { + param = param.trimmed(); + if(misc::isUrl(param)) { + QBtSession::instance()->downloadFromUrl(param); + }else{ + if(param.startsWith("bc://bt/", Qt::CaseInsensitive)) { + qDebug("Converting bc link to magnet link"); + param = misc::bcLinkToMagnet(param); + } + if(param.startsWith("magnet:", Qt::CaseInsensitive)) { + if(useTorrentAdditionDialog) { + torrentAdditionDialog *dialog = new torrentAdditionDialog(this); + dialog->showLoadMagnetURI(param); + } else { + QBtSession::instance()->addMagnetUri(param); + } + } else { + if(useTorrentAdditionDialog) { + torrentAdditionDialog *dialog = new torrentAdditionDialog(this); + dialog->showLoad(param); + }else{ + QBtSession::instance()->addTorrent(param); + } + } + } + } +} + +void MainWindow::addTorrent(QString path) { + QBtSession::instance()->addTorrent(path); +} + +void MainWindow::processDownloadedFiles(QString path, QString url) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + const bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); + if(useTorrentAdditionDialog) { + torrentAdditionDialog *dialog = new torrentAdditionDialog(this); + dialog->showLoad(path, url); + }else{ + QBtSession::instance()->addTorrent(path, false, url); + } +} + +void MainWindow::optionsSaved() { + loadPreferences(); +} + +// Load program preferences +void MainWindow::loadPreferences(bool configure_session) { + QBtSession::instance()->addConsoleMessage(tr("Options were saved successfully.")); + const Preferences pref; + const bool newSystrayIntegration = pref.systrayIntegration(); + actionLock_qBittorrent->setEnabled(newSystrayIntegration); + if(newSystrayIntegration != (systrayIcon!=0)) { + if(newSystrayIntegration) { + // create the trayicon + if(!QSystemTrayIcon::isSystemTrayAvailable()) { + if(!configure_session) { // Program startup + systrayCreator = new QTimer(this); + connect(systrayCreator, SIGNAL(timeout()), this, SLOT(createSystrayDelayed())); + systrayCreator->setSingleShot(true); + systrayCreator->start(2000); + qDebug("Info: System tray is unavailable, trying again later."); + } else { + qDebug("Warning: System tray is unavailable."); + } + } else { + createTrayIcon(); + } + } else { + // Destroy trayicon + delete systrayIcon; + delete myTrayIconMenu; + } + } + // Reload systray icon + if(newSystrayIntegration && systrayIcon) { + systrayIcon->setIcon(getSystrayIcon()); + } + // General + if(pref.isToolbarDisplayed()) { + toolBar->setVisible(true); + } else { + // Clear search filter before hiding the top toolbar + search_filter->clear(); + toolBar->setVisible(false); + } + + if(pref.preventFromSuspend()) + { + preventTimer->start(PREVENT_SUSPEND_INTERVAL); + } + else + { + preventTimer->stop(); + m_pwr->setActivityState(false); + } + + const uint new_refreshInterval = pref.getRefreshInterval(); + transferList->setRefreshInterval(new_refreshInterval); + transferList->setAlternatingRowColors(pref.useAlternatingRowColors()); + properties->getFilesList()->setAlternatingRowColors(pref.useAlternatingRowColors()); + properties->getTrackerList()->setAlternatingRowColors(pref.useAlternatingRowColors()); + properties->getPeerList()->setAlternatingRowColors(pref.useAlternatingRowColors()); + // Queueing System + if(pref.isQueueingSystemEnabled()) { + if(!actionDecreasePriority->isVisible()) { + transferList->hidePriorityColumn(false); + actionDecreasePriority->setVisible(true); + actionIncreasePriority->setVisible(true); + prioSeparator->setVisible(true); + prioSeparatorMenu->setVisible(true); + } + } else { + if(actionDecreasePriority->isVisible()) { + transferList->hidePriorityColumn(true); + actionDecreasePriority->setVisible(false); + actionIncreasePriority->setVisible(false); + prioSeparator->setVisible(false); + prioSeparatorMenu->setVisible(false); + } + } + + // Torrent properties + properties->reloadPreferences(); + + // Icon provider +#if defined(Q_WS_X11) && (QT_VERSION >= QT_VERSION_CHECK(4,6,0)) + IconProvider::instance()->useSystemIconTheme(pref.useSystemIconTheme()); +#endif + + if(configure_session) + QBtSession::instance()->configureSession(); + + qDebug("GUI settings loaded"); +} + +void MainWindow::addUnauthenticatedTracker(const QPair &tracker) { + // Trackers whose authentication was cancelled + if(unauthenticated_trackers.indexOf(tracker) < 0) { + unauthenticated_trackers << tracker; + } +} + +// Called when a tracker requires authentication +void MainWindow::trackerAuthenticationRequired(const QTorrentHandle& h) { + if(unauthenticated_trackers.indexOf(QPair(h, h.current_tracker())) < 0) { + // Tracker login + new trackerLogin(this, h); + } +} + +// Check connection status and display right icon +void MainWindow::updateGUI() { + // update global informations + if(systrayIcon) { +#if defined(Q_WS_X11) || defined(Q_WS_MAC) + QString html = "

"; + html += "
"; + html += " "+tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(QString::number(QBtSession::instance()->getPayloadDownloadRate()/1024., 'f', 1)); + html += "
"; + html += "
"; + html += " "+tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(QString::number(QBtSession::instance()->getPayloadUploadRate()/1024., 'f', 1)); + html += "
"; +#else + // OSes such as Windows do not support html here + QString html =tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(QString::number(QBtSession::instance()->getPayloadDownloadRate()/1024., 'f', 1)); + html += "\n"; + html += tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(QString::number(QBtSession::instance()->getPayloadUploadRate()/1024., 'f', 1)); +#endif + systrayIcon->setToolTip(html); // tray icon + } + if(displaySpeedInTitle) { + setWindowTitle(tr("qBittorrent %1 (Down: %2/s, Up: %3/s)", "%1 is qBittorrent version").arg(QString::fromUtf8(VERSION)).arg(misc::friendlyUnit(QBtSession::instance()->getSessionStatus().payload_download_rate)).arg(misc::friendlyUnit(QBtSession::instance()->getSessionStatus().payload_upload_rate))); + } +} + +void MainWindow::showNotificationBaloon(QString title, QString msg) const { + if(!Preferences().useProgramNotification()) return; +#if defined(Q_WS_X11) && defined(QT_DBUS_LIB) + org::freedesktop::Notifications notifications("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + QDBusConnection::sessionBus()); + if(notifications.isValid()) { + QVariantMap hints; + hints["desktop-entry"] = "qBittorrent"; + QDBusPendingReply reply = notifications.Notify("qBittorrent", 0, "qbittorrent", title, + msg, QStringList(), hints, -1); + reply.waitForFinished(); + if(!reply.isError()) + return; + } +#endif + if(systrayIcon && QSystemTrayIcon::supportsMessages()) + systrayIcon->showMessage(title, msg, QSystemTrayIcon::Information, TIME_TRAY_BALLOON); +} + +/***************************************************** + * * + * Utils * + * * + *****************************************************/ + +void MainWindow::downloadFromURLList(const QStringList& url_list) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + const bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); + foreach(QString url, url_list) { + if(url.startsWith("bc://bt/", Qt::CaseInsensitive)) { + qDebug("Converting bc link to magnet link"); + url = misc::bcLinkToMagnet(url); + } + if(url.startsWith("magnet:", Qt::CaseInsensitive)) { + if(useTorrentAdditionDialog) { + torrentAdditionDialog *dialog = new torrentAdditionDialog(this); + dialog->showLoadMagnetURI(url); + } else { + QBtSession::instance()->addMagnetUri(url); + } + } else { + QBtSession::instance()->downloadFromUrl(url); + } + } +} + +/***************************************************** + * * + * Options * + * * + *****************************************************/ + +void MainWindow::createSystrayDelayed() { + static int timeout = 20; + if(QSystemTrayIcon::isSystemTrayAvailable()) { + // Ok, systray integration is now supported + // Create systray icon + createTrayIcon(); + delete systrayCreator; + } else { + if(timeout) { + // Retry a bit later + systrayCreator->start(2000); + --timeout; + } else { + // Timed out, apparently system really does not + // support systray icon + delete systrayCreator; + // Disable it in program preferences to + // avoid trying at earch startup + Preferences().setSystrayIntegration(false); + } + } +} + +void MainWindow::updateAltSpeedsBtn(bool alternative) { + actionUse_alternative_speed_limits->setChecked(alternative); +} + +QMenu* MainWindow::getTrayIconMenu() { + if(myTrayIconMenu) + return myTrayIconMenu; + // Tray icon Menu + myTrayIconMenu = new QMenu(this); + myTrayIconMenu->addAction(actionOpen); + //myTrayIconMenu->addAction(actionDownload_from_URL); + myTrayIconMenu->addSeparator(); + const bool isAltBWEnabled = Preferences().isAltBandwidthEnabled(); + updateAltSpeedsBtn(isAltBWEnabled); + actionUse_alternative_speed_limits->setChecked(isAltBWEnabled); + myTrayIconMenu->addAction(actionUse_alternative_speed_limits); + myTrayIconMenu->addAction(actionSet_global_download_limit); + myTrayIconMenu->addAction(actionSet_global_upload_limit); + myTrayIconMenu->addSeparator(); + myTrayIconMenu->addAction(actionStart_All); + myTrayIconMenu->addAction(actionPause_All); + myTrayIconMenu->addSeparator(); + myTrayIconMenu->addAction(actionExit); + if(ui_locked) + myTrayIconMenu->setEnabled(false); + return myTrayIconMenu; +} + +void MainWindow::createTrayIcon() { + // Tray icon + systrayIcon = new QSystemTrayIcon(getSystrayIcon(), this); + + systrayIcon->setContextMenu(getTrayIconMenu()); + connect(systrayIcon, SIGNAL(messageClicked()), this, SLOT(balloonClicked())); + // End of Icon Menu + connect(systrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleVisibility(QSystemTrayIcon::ActivationReason))); + systrayIcon->show(); +} + +// Display Program Options +void MainWindow::on_actionOptions_triggered() { + if(options) { + // Get focus + options->setFocus(); + } else { + options = new options_imp(this); + connect(options, SIGNAL(status_changed()), this, SLOT(optionsSaved())); + } +} + +void MainWindow::on_actionTop_tool_bar_triggered() { + bool is_visible = static_cast(sender())->isChecked(); + toolBar->setVisible(is_visible); + Preferences().setToolbarDisplayed(is_visible); +} + +void MainWindow::on_actionSpeed_in_title_bar_triggered() { + displaySpeedInTitle = static_cast(sender())->isChecked(); + Preferences().showSpeedInTitleBar(displaySpeedInTitle); + if(displaySpeedInTitle) + updateGUI(); + else + setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION))); +} + +void MainWindow::on_actionRSS_Reader_triggered() { + RssSettings().setRSSEnabled(actionRSS_Reader->isChecked()); + displayRSSTab(actionRSS_Reader->isChecked()); +} + +void MainWindow::on_actionSearch_engine_triggered() { + Preferences().setSearchEnabled(actionSearch_engine->isChecked()); + displaySearchTab(actionSearch_engine->isChecked()); +} + +void MainWindow::on_action_Import_Torrent_triggered() +{ + TorrentImportDlg::importTorrent(); +} + +/***************************************************** + * * + * HTTP Downloader * + * * + *****************************************************/ + +// Display an input dialog to prompt user for +// an url +void MainWindow::on_actionDownload_from_URL_triggered() { + if(!downloadFromURLDialog) { + downloadFromURLDialog = new downloadFromURL(this); + connect(downloadFromURLDialog, SIGNAL(urlsReadyToBeDownloaded(QStringList)), this, SLOT(downloadFromURLList(QStringList))); + } +} + +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) + +void MainWindow::handleUpdateCheckFinished(bool update_available, QString new_version) +{ + if(update_available) { + if(QMessageBox::question(this, tr("A newer version is available"), + tr("A newer version of qBittorrent is available on Sourceforge.\nWould you like to update qBittorrent to version %1?").arg(new_version), + QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) { + // The user want to update, let's download the update + ProgramUpdater* updater = dynamic_cast(sender()); + connect(updater, SIGNAL(updateInstallFinished(QString)), SLOT(handleUpdateInstalled(QString))); + updater->updateProgram(); + return; + } + } + sender()->deleteLater(); +} + +void MainWindow::handleUpdateInstalled(QString error_msg) +{ + if(!error_msg.isEmpty()) { + QMessageBox::critical(this, tr("Impossible to update qBittorrent"), tr("qBittorrent failed to update, reason: %1").arg(error_msg)); + } +} + +#endif + +void MainWindow::on_actionDonate_money_triggered() +{ + QDesktopServices::openUrl(QUrl("http://sourceforge.net/donate/index.php?group_id=163414")); +} + +void MainWindow::showConnectionSettings() +{ + on_actionOptions_triggered(); + options->showConnectionTab(); +} + +void MainWindow::on_actionExecution_Logs_triggered(bool checked) +{ + if(checked) { + Q_ASSERT(!m_executionLog); + m_executionLog = new ExecutionLog(tabs); + int index_tab = tabs->addTab(m_executionLog, tr("Execution Log")); + tabs->setTabIcon(index_tab, IconProvider::instance()->getIcon("view-calendar-journal")); + } else { + if(m_executionLog) + delete m_executionLog; + } + Preferences().setExecutionLogEnabled(checked); +} + +void MainWindow::on_actionAutoExit_qBittorrent_toggled(bool enabled) +{ + qDebug() << Q_FUNC_INFO << enabled; + Preferences().setShutdownqBTWhenDownloadsComplete(enabled); +} + +void MainWindow::on_actionAutoSuspend_system_toggled(bool enabled) +{ + qDebug() << Q_FUNC_INFO << enabled; + Preferences().setSuspendWhenDownloadsComplete(enabled); +} + +void MainWindow::on_actionAutoShutdown_system_toggled(bool enabled) +{ + qDebug() << Q_FUNC_INFO << enabled; + Preferences().setShutdownWhenDownloadsComplete(enabled); +} + +void MainWindow::checkForActiveTorrents() +{ + const TorrentStatusReport report = transferList->getSourceModel()->getTorrentStatusReport(); + if(report.nb_active > 0) // Active torrents are present; prevent system from suspend + m_pwr->setActivityState(true); + else + m_pwr->setActivityState(false); +} + +QIcon MainWindow::getSystrayIcon() const +{ +#if defined(Q_WS_X11) + TrayIcon::Style style = Preferences().trayIconStyle(); + switch(style) { + case TrayIcon::MONO_DARK: + return QIcon(":/Icons/skin/qbittorrent_mono_dark.png"); + case TrayIcon::MONO_LIGHT: + return QIcon(":/Icons/skin/qbittorrent_mono_light.png"); + default: + break; + } +#endif + QIcon icon; + icon.addFile(":/Icons/skin/qbittorrent22.png", QSize(22, 22)); + icon.addFile(":/Icons/skin/qbittorrent16.png", QSize(16, 16)); + icon.addFile(":/Icons/skin/qbittorrent32.png", QSize(32, 32)); + return icon; +} diff --git a/src/mainwindow.h b/src/mainwindow.h new file mode 100644 index 000000000..38d4d4e8a --- /dev/null +++ b/src/mainwindow.h @@ -0,0 +1,211 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef GUI_H +#define GUI_H + +#include +#include +#include +#include "ui_mainwindow.h" +#include "qtorrenthandle.h" + +class QBtSession; +class downloadFromURL; +class SearchEngine; +class RSSImp; +class about; +class options_imp; +class TransferListWidget; +class TransferListFiltersWidget; +class PropertiesWidget; +class StatusBar; +class consoleDlg; +class about; +class TorrentCreatorDlg; +class downloadFromURL; +class HidableTabWidget; +class LineEdit; +class ExecutionLog; +class PowerManagement; + +QT_BEGIN_NAMESPACE +class QCloseEvent; +class QFileSystemWatcher; +class QShortcut; +class QSplitter; +class QTabWidget; +class QTimer; +QT_END_NAMESPACE + +class MainWindow : public QMainWindow, private Ui::MainWindow{ + Q_OBJECT + +public: + // Construct / Destruct + MainWindow(QWidget *parent=0, QStringList torrentCmdLine=QStringList()); + ~MainWindow(); + // Methods + QWidget* getCurrentTabWidget() const; + TransferListWidget* getTransferList() const { return transferList; } + QMenu* getTrayIconMenu(); + PropertiesWidget *getProperties() const { return properties; } + +public slots: + void trackerAuthenticationRequired(const QTorrentHandle& h); + void setTabText(int index, QString text) const; + void showNotificationBaloon(QString title, QString msg) const; + void downloadFromURLList(const QStringList& urls); + void updateAltSpeedsBtn(bool alternative); + void updateNbTorrents(); + void deleteBTSession(); + +protected slots: + // GUI related slots + void dropEvent(QDropEvent *event); + void dragEnterEvent(QDragEnterEvent *event); + void toggleVisibility(QSystemTrayIcon::ActivationReason e); + void on_actionAbout_triggered(); + void on_actionCreate_torrent_triggered(); + void on_actionWebsite_triggered() const; + void on_actionBugReport_triggered() const; + void balloonClicked(); + void writeSettings(); + void readSettings(); + void on_actionExit_triggered(); + void createTrayIcon(); + void fullDiskError(const QTorrentHandle& h, QString msg) const; + void handleDownloadFromUrlFailure(QString, QString) const; + void createSystrayDelayed(); + void tab_changed(int); + void on_actionLock_qBittorrent_triggered(); + void defineUILockPassword(); + bool unlockUI(); + void notifyOfUpdate(QString); + void showConnectionSettings(); + // Keyboard shortcuts + void createKeyboardShortcuts(); + void displayTransferTab() const; + void displaySearchTab() const; + void displayRSSTab() const; + // Torrent actions + void on_actionSet_global_upload_limit_triggered(); + void on_actionSet_global_download_limit_triggered(); + void on_actionDocumentation_triggered() const; + void on_actionOpen_triggered(); + void updateGUI(); + void loadPreferences(bool configure_session=true); + void processParams(const QString& params); + void processParams(const QStringList& params); + void addTorrent(QString path); + void addUnauthenticatedTracker(const QPair &tracker); + void processDownloadedFiles(QString path, QString url); + void finishedTorrent(const QTorrentHandle& h) const; + void askRecursiveTorrentDownloadConfirmation(const QTorrentHandle &h); + // Options slots + void on_actionOptions_triggered(); + void optionsSaved(); + // HTTP slots + void on_actionDownload_from_URL_triggered(); +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) + void handleUpdateCheckFinished(bool update_available, QString new_version); + void handleUpdateInstalled(QString error_msg); +#endif + +protected: + void closeEvent(QCloseEvent *); + void showEvent(QShowEvent *); + bool event(QEvent * event); + void displayRSSTab(bool enable); + void displaySearchTab(bool enable); + +private: + QIcon getSystrayIcon() const; + +private: + QFileSystemWatcher *executable_watcher; + // Bittorrent + QList > unauthenticated_trackers; // Still needed? + // GUI related + bool m_posInitialized; + QTimer *guiUpdater; + HidableTabWidget *tabs; + StatusBar *status_bar; + QPointer options; + QPointer console; + QPointer aboutDlg; + QPointer createTorrentDlg; + QPointer downloadFromURLDialog; + QPointer systrayIcon; + QPointer systrayCreator; + QPointer myTrayIconMenu; + TransferListWidget *transferList; + TransferListFiltersWidget *transferListFilters; + PropertiesWidget *properties; + bool displaySpeedInTitle; + bool force_exit; + bool ui_locked; + LineEdit *search_filter; + // Keyboard shortcuts + QShortcut *switchSearchShortcut; + QShortcut *switchSearchShortcut2; + QShortcut *switchTransferShortcut; + QShortcut *switchRSSShortcut; + // Widgets + QAction *prioSeparator; + QAction *prioSeparatorMenu; + QSplitter *hSplitter; + QSplitter *vSplitter; + // Search + QPointer searchEngine; + // RSS + QPointer rssWidget; + // Execution Log + QPointer m_executionLog; + // Power Management + PowerManagement *m_pwr; + QTimer *preventTimer; + +private slots: + void on_actionSearch_engine_triggered(); + void on_actionRSS_Reader_triggered(); + void on_actionSpeed_in_title_bar_triggered(); + void on_actionTop_tool_bar_triggered(); + void on_action_Import_Torrent_triggered(); + void on_actionDonate_money_triggered(); + void on_actionExecution_Logs_triggered(bool checked); + void on_actionAutoExit_qBittorrent_toggled(bool ); + void on_actionAutoSuspend_system_toggled(bool ); + void on_actionAutoShutdown_system_toggled(bool ); + // Check for active torrents and set preventing from suspend state + void checkForActiveTorrents(); +}; + +#endif diff --git a/src/mainwindow.ui b/src/mainwindow.ui new file mode 100644 index 000000000..9e53de6b1 --- /dev/null +++ b/src/mainwindow.ui @@ -0,0 +1,370 @@ + + + MainWindow + + + + 0 + 0 + 914 + 563 + + + + Qt::CustomContextMenu + + + + + + + + 0 + + + + + + + 0 + 0 + 914 + 25 + + + + + &Edit + + + + + + + + + + + + + &Help + + + + + + + + + + &Tools + + + + Auto-Shutdown on downloads completion + + + + + + + + + + + + + + + &File + + + + + + + + + &View + + + + + + + + + + + + + + + + + + + false + + + Qt::Horizontal + + + false + + + TopToolBarArea + + + false + + + + + + + + + + + + + + + + &Add torrent file... + + + + + Exit + + + Exit + + + + + &Options... + + + + + &About + + + + + &Resume + + + + + &Pause + + + + + &Delete + + + + + + :/Icons/skin/qbittorrent32.png:/Icons/skin/qbittorrent32.png + + + Visit &Website + + + + + Add &link to torrent... + + + + + Torrent &creator + + + + + Report a &bug + + + + + Set upload limit... + + + + + Set download limit... + + + + + &Documentation + + + + + Set global download limit... + + + + + Set global upload limit... + + + + + Decrease priority + + + true + + + + + Increase priority + + + true + + + + + true + + + Alternative speed limits + + + Alternative speed limits + + + + + true + + + Top &tool bar + + + Display top tool bar + + + + + true + + + &Speed in title bar + + + Show transfer speed in title bar + + + + + true + + + &RSS reader + + + + + true + + + Search &engine + + + + + Lock qBittorrent + + + Lock qBittorrent + + + Ctrl+L + + + + + Import existing torrent... + + + Import torrent... + + + + + Donate money + + + If you like qBittorrent, please donate! + + + + + R&esume All + + + + + P&ause All + + + + + true + + + Execution &Log + + + Execution Log + + + + + true + + + Exit qBittorrent + + + + + true + + + Suspend system + + + + + true + + + Shutdown system + + + + + true + + + Disabled + + + + + + + + diff --git a/src/menuicons/128x128/apps/qbittorrent.png b/src/menuicons/128x128/apps/qbittorrent.png new file mode 100644 index 0000000000000000000000000000000000000000..69c5ab73bfa5e51c0f20dd4d368b704f586d65fb GIT binary patch literal 21783 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 KMNUMnLSTY&_Z(3G literal 0 HcmV?d00001 diff --git a/src/menuicons/16x16/apps/qbittorrent.png b/src/menuicons/16x16/apps/qbittorrent.png new file mode 100644 index 0000000000000000000000000000000000000000..cff0194ec7077f939af2a341676b97b8365329bd GIT binary patch literal 954 zcmV;r14aCaP)LsPI-U(||HDQy)?m8xJwg!<-#6$HT- z1ws0tMT&)@R`eycL@L2(tAT8jG)XtByV)c=+1dZu-P!rSPNEi-;JMuU@Nv%hz6}j>)ksZNNHR~zr(cc#%=y`lP3^|>*x_eK4?TbS zRgYRlU2eb;pwUv%)(m*uE)a*4SuH|Qb*L>FuFyctOO*E1^`9nakH^D5`t*x07uHr_ z6ALUK1RLmpoAskmZldCtZ9oWhLg)%Q9c`qS(s<~}=U(7Be<$77pV$)!#S(2rfjAYjWp(LxQH8s!-gV~gb#f*ghZDCZ(HMsch?TMk`y)Gdd?=@@}#dukyvPH*W z6+GvI5Q!k0m%)0x@QXD}-pGNbDfGoc&ZLy{J%VsgBOuI`-bj7W$xRtS6(`GQkENq&Hedjq`f{LfAr+&>j$4Weu4|d2TZs( z8H}abm9^B(%U_)RwZ&!Cu)V3|VAg<(oPc6)umfid> c_YVOE0JW8 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

)-bts}z8$-&YNqN5+lOrvCDjZWsM2H|m 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 literal 0 HcmV?d00001 diff --git a/src/menuicons/22x22/apps/qbittorrent.png b/src/menuicons/22x22/apps/qbittorrent.png new file mode 100644 index 0000000000000000000000000000000000000000..0f573d05d51ecd87412f1b450d39f0c7042aa35f GIT binary patch literal 1456 zcmV;h1yA~kP)o-2KuKV$29UV(5ysmPFVc1+=%#VzY2F?$h z>hJ44{@ujHL;&|Yy1Tny{_^`X*Fq_6#t~CA?acLw=$mi7{hrxmu-yxj+y45_-5E*M zlHy+gg+f77)Pg1}>YcY_)3l-%&1%}U+nRRpi*HXj%N^bsQD1y@$L`;vnbBg2(wo-eG%wlWsjQZuuOLX;jYv*AcT>|29q#$TX!zH2?w?8L!)rIc@&3WR zxtzdMS_(*KMdU>Zq9{WseI*5jVi9hq4T)41*&MBt&2D56no7XeytJvx!I{qv^qstu zJcGgDK5*ppPeyNx-(R7^#1(ZQjesa-@H|H^PdhdEn`-fUa1!Z^NC{?PG8sWk;YvtG zdy7waX~VLIMn*=ivL)bEYu0V@%~|M=P6Q!KA`0M9?sCCaUJlM^2Fn`}nNA^|$`eQt zl2ky2+m8Ag4@?FglB^&Z4I?2N%AVc4ZEFcr2ku<^#D*vxR0y=(>4K-iifE!ud_8tFFK_dCPMgSs3&Wj$$|v1~G-s_6Bq=ZXi30aQHS_+G}e) z9*>VTnM@Y5#pcKfG8o=W;R*gV!g)=`JFglu%@NN+u9bOOyu= zv9th&lc1_a{fyCSEv@ShOS+e}f+||c7)yy@3M58ax4~!s9mr)y=CLheyMhj0t$|$rZRXG!D1R z27hxkqSI*@Ol1Tnz-;94Lf1U}JRF9@G8@}A&BNYrh9Ib{p2T=0bSoZ5?f^W)lypC}@{!{^BFPd-ha}8$h!E%3191Y^r4OUgK!7GV9Trqq+Od9lEw*lG#)Thy20nOa*G_5y z;$6VSLP5UJ-+OYweE)(~D_1rf4Ge5nBX|NUm76Q;js~)4m48u^P9YQeoZ|t z_xJSe-2U1&Q4k|D-XI*$TXyVvclT3Uc5Ihmv4vwk5sFe4*k-kl8$V|97FKC9i~CYQBrI+aYsr%NGc|LfeJ0t^6h+{btOM$^;)0000< KMNUMnLSTY77`%7KuEEZwT}$K5u_)_c z*@_@mXJ^ytFUCF}J@Kb^k7cvjByMwf9@+P!pS?9adS$9;ScdiOVee%n%liAJ+1v}i zeCg##Q@G`pH2eJi#H)u6y;l$|t0aG;&a@~kmSOyB(zCs1kLz^iV&1ZjpBfuq+qY)p zO_h6nzQpUtJ{lEBRuEN7)#_GFQmv{eTS85`F)LMjmFb;gX_{{31jw8&($`>TVMQXZWV7UU%)NrkLvP*j>^Os|{J zNogz+Lb)QMB#59WA<>y2@4%PSIYbgGqHPgx;N)M1Ke!Qr)5*mSzdv$DU}MXchEyyL z^Q2TKr%h1KLFtCa0^;!n1{v%eOm{2@3D0^3~auC_mCjzkYxp-P!P@WW~9;!I5$4oSeJ|f0t%JaCc-*lhieg2=$b}T;Bs+|%$~V$4X4LaRE!StJcFn94PbF3fJ#ln zLav1MJ-w?UO-*r*D&OM^Mk0cu!elrwEQiaJ~jhG7{8C~0^$7Rs~=i(a}%+vmCK_&wxO#?mcQH)*9(OCvw-VIffM6o8;>?F&@ zg_)UXI0&5-jZfxq&)qArvZoFHU;sO}--Y(J7~x}4*e(<*8ptVZ=xs$P;30~;@YsWE zu_)}tpU+Gq9P%R)4q)=~KQ5Ik<*bdEb#ZKTql(`7`%K0NJ$-&nWB!1(>3T8hqjgo+FK*&Ti$}>Z@+fbR{meTXyW4e@$C=n zd@#}36|;MfNeT^gLKt_BV*%>n%2jySg5*^c7W=MyhJ z_smbJQ3~I>(Uz@Tz3~rk48Jciq4j$=N@918& zigP->wuq`owdBNwOXo*E{^Zoj6CciIrq6w^e--~R+!R%u=RJPAZX~f*s|uAYJ!}6@ c@Sg$<0LcqNLk4O~)c^nh07*qoM6N<$g5zo^$N&HU literal 0 HcmV?d00001 diff --git a/src/menuicons/32x32/apps/qbittorrent.png b/src/menuicons/32x32/apps/qbittorrent.png new file mode 100644 index 0000000000000000000000000000000000000000..fd76d5f1eae023f03e5b2ed4083caa61f5adc8ea GIT binary patch literal 2531 zcmV<92^{u`P)9pRTGTb3+awxnH2tKIE)uQ3G%T1r^^ zj&`KG_dEA|=R4nB0e621*L~_&$6YUSCzru&68()$%`HtW%UkLfG}gOZ4v!!}C>Bd{ zJQj)cc3-lt{3!~k+y`PcaQ6OC?*yEaOkx+=hX$9?<#n0FxYywt?dE}+7->|C3PkUi?3>$uBtZ;?LWv0 zil&DmvVI|^>!0)t4{zMKaohhDym{&J%@=zHV#KN*Pi1t4q8AiZmkWw6<%={5x+LFX z&~I!`k>)Zy?L!&;bdRL>C1iQ$u3b;xi3o-2n!wsO-fMfuQyKJ^TQ&G>-~y*zg7ENh zgW%~_FbMop7ubUIN6IuB4X~I*{4+d-tZG4%-<1FE?yo;_>eT6@w*_D}n`;le_5N}H zqSh5tQyHvlcB52MXsDnaQE&$0YSfv39>`bbf>{(XmP&(C0RsUr7z{8G08KaGbjJh& zHFHp=kB>aMe(n0<;b`}4Oyl)x-}BtQ7an>1+uK5YF?^xk4iP0}r2+~?g%2t>6crjp zm47l&>^qmk2CLPCcrpz+uYgjlz)6BJLq0YGJy zf920#I<)`FSk9{FC(&4K$8;_ai2%s?0`dg{pr|~cqN*^8Mjk+ti|~5vuv$!rjHV!6 zotrOQ1zXbKv>MUT8-XS|ux8bY#plnR{xBAc^>cHXHJPnDp4w^i`aQ$L5tLa}9z30q z2&MqhWTAj&$h2rKU*wNXWn`q%Sw5$v&Uj9GT0)KhS=ynVo1-Wi9HNH)fg#A0 ztX+GaeR6j5BIn*@_CNH<_Dv)4B&O4oFa`V+NI@V_jWUm$LZD70~#1iB9_cz)q@+>mHWJPsfo#c4xpiNaZ6y{ z;`yPTA)ad%tfs~fr_+w`Kn%(8G*`CA<3w<7H3bB*p>kkUetbR?W6Qz-24g8ij&B;h6QmAjP^)FeveA(GEf1d%+)UslU!E7^TauTQ6L%Vjm?C88a zh*0MhzGHSNw0oA0>Z)=oIRnNgGL+*IDW4c15GT%bAUvD|t4j7=AMN;w%@3d

!~X zLmYIPs!OE`xo^qRW&&`O0T6=q3+k1U&P7E&0*BK{xh$cpFN$ow1fyZ5tgMt8=rhALvjfIO`&NqLF^_ye`Ivmz91PN$m* ziD^ltx`jdHB1}x=h-M=_ERwJ+$jVHFtO_)YO-M9H!Bn=$nbF8231#d^ABjZFMkBeIl>}tKFy+o>wQ$Af@)}0RB_yT_JT(r7m3F9cb~H+l zffme4Mb2J2SHf^2hlz}W=(tS5-B_}q3SIpv436cvV_Ga`n8*PJ!hHh_HBUirSE$pV z7vXX`XjswS6UWNtAl5zDOttMq??4jXGIFuy4JdQlktervIPBa7hvGS6Mdd=>vw120 z5gMVMki|nQ=i!+x_ftbM;@lZUEHE6Qp|=win;BkJjFZ%-wnqvc+&-$%9H zHITwvf4PJm8(Yx&z(TBAv5ppO`^qN>u1=s-`nujg{-H2~S^^w7uW{`SF!?a%HW^g2;Vba#cv z@rzf^VgB4QzE~_i#hLit?p9Kd0YeFiQ(05(#le$(c=>2I301wAAW?3! zOtz{Za>dhG138k!^&6`yveFkfM$WM-@-+ukj zo3n@3*=B_9(1o_YzIWu^g~3YHRC(bqcc7}m1)tYN;^V${oy?>6Ax7Z6^W87E-(a2p+AQLh$a8#1)Y{10KO0c2UOIBQl z6^(Nc4z+#y;*WmtLseDNw*mkuJDvQjw`*|Q<2$!lELKs~6qso-gJC99Z1LWqG(NgS z=`$F)Z-@kdnGb8hHmey95@s3gy1K%N`2iQ6To=UZ<_b(DBcspk*z(j=I(_;2n8uqA ziLs&n%aNh}(XVaY`moF46jh}FyWIr4)5d#&#UjE^psbW%o0aY@th~&ma0{oqdX59N z)ov1-3rztl)-RnyZMZ+ScjsfzT?zM{x%mz1wr@sjzPw@Ei@!Rs-(67`3=fTxmF7XV zPvX;fS1VB2saFpoA_>k+CBXo((~rw$M1|XmwTrw6U;N8uP{VNHcKu9+oR^D~J8?8FN5i7GO$+(cyJ*x}#2 zdf@jjzpR!@(c8T{-pRY6xn;$gFKyeoclW9HPL literal 0 HcmV?d00001 diff --git a/src/menuicons/36x36/apps/qbittorrent.png b/src/menuicons/36x36/apps/qbittorrent.png new file mode 100644 index 0000000000000000000000000000000000000000..aef62648edb4eeeab367e42c4141b51191b75cdf GIT binary patch literal 3032 zcmV;}3n%o6P)adt-A;z1?PYVGTi5RcRs~8y|@D z^@scV!bPbR!`Sj{7iZ2f&2p>&vo|$0En2;1?PW_>UV3rI{Dlib!5W{-X(o%gGDybO zQi&*&6{WG^NO=Ey+qQRgzVymF@9fxt$KtF}eGU*yb5qm#8y@)0U*G&-ICW@T*Q27Y z=Ve`2HT_dpS=IHdr0GLxO+TE_^+Qpq{9>F6i{JB^@0}un_``)^BxAzSU zkMHU)>b)^pmz5KsILTEgsrsSOqP}}r)sM!c(t{fxe$-*Ng}w+NqaXO4PJi{1m5_=>r>0Lb;{b)+pJKuP-yS}cr6+eW7yat<}hH9SW(}yH?ALw z>-x6$_Pu{1Pz;NK|M{3@EKHtT*8hCtkJoRwF+7;0(_38Rw&-SE#2yK?^Tf zx%|$1?!D{yM4#y)ArK6m^?cXvuA<pUM z$nSI0SUgRMlt?C{z}&<=#LQ+jQ#@0mZAUV6>f8qE2wCLou3YiWci-Ll`iVSbzwSr3 z-|Y6c)btG{C}5RHR~5?Oq$0DNM93S;6-tzc<%%-Aq7cJaf&j5GrBX!$*>~g*ADf$; z%busQMe^8tkf7K^qD-!UO^T$HHNJ5&lgB;wU9A986h1GDdu$Gy%l=OzYz0Z7P?e1a zBLg%V7wL>8E0>>l-uX*EQ978{FIls8jl);#iT3r7Di_IQGV+alUKa(btB@a+P!}bf zG@T`v%R!o|QGa-thpY@&$&-KzMTH!8E6tlzhn#Zod(1-vqZ1TMisW(GDVrIh@%RL_ z*0q|hy!ty=?%K8MKNzM?0rD+dwPs}s049vjj0U$^q4c>Rab@oOWs~m8AmW4u+E3?V_4sfYO-)9q2iV&s@coNK^*$^wT;> zl2uZ%Fw3(HLNv*C4*LBM2dQ@;hJ(o@V9w$N&9vy023pWwi%|8Fh7+Ze8O+PmoQ5`B zbK9o@wX}7#xx9XFBsPM0m&t6zi2~IGEu?)1duebajsjY7W|=XLl62~Pji;c3D5Y^? zxm?EFO2~E}8l>%eddX@tkpPx4U3%-iqf{TNBEQ!`E{6@drIOKvoXi)<+*oIApWDFz z?clrAHMTSujApPy!NSq!%6@bjc0kdN(wIwWhnL}c;`!M~WJAnZn3*cRmFVegR`a?ws^vzhCg4!}c01EbS`1|z-wazQLP z?RIj40TNDlBpm17T5;h*3I=@qq$)zWU|thlv3l`jdrh1GCbN~|X^Dq|lf>_aHyrRp zmIlXgaOB_*EN1)T?HztVp7yQA2GNy}f^o zUg!=Zyk#Czzt;xMF+rzPiXo@WW+T-G+`Oz*15_P^vXF{pyE?bL#xTqTL?0g5^X{G< z-EW_H;n!CsQh98yP`>0s@*0qo60c{Bn1b2DWr2l4g_~p*H7Tu7O3d)IVpt3YGpBky zQ${kEc`syzhI!$6FTnV#-4v{LQfp&1z4YY9Eu*8O2d5fOVMarn-Td48AF&9ETwmj* zT3Ah$11E8SZ4R)(#syNt8JK87$jD%1rK6%-DDd1=-3Sx78Bl_lsxvTdw*!^m27-8~ z4qj>wx=4%<$DVrZkv}jYKfWL0*P#z~z4hEvzuPpo$%jcEY79E5KIq{w_b^r#QOw%}vWyz=5%ODnGlaD;`i}g&nS@}EJTL-_Y0-=s4p8MC|I~Jb3 z_;7!e##04K7j^V5G74@HHBRPQ#X3e_NZA4P%3FpJ)qu%>4Pe|Z3liH7Hrc7AnrPkf z79_bqk8l1{=WRFLa1-{9O(pYZ0-6H#;N#D1x?tJri~EL>CR-t5_LeOk&J(In3PL@Q~ADpmW;YbZ&>2?!5b+O~1bXm-n$(zL{V?7ZAJ57HjC{ zpWS=My6bPfSys)KVf5Qcu}G{!u-1ne>zOpY;vqEa2$z8@%tHv7(`tku+NnMO@ytbz z-G9#=zuLO>pU+PI@Sx7-Me&5VzH;u;RX5zS{wL>NxN4PVuo{zSUDIf3nNV^-T%p

"); + ui->lineContains->setToolTip(tip); + tip = tr("Wildcard mode: you can use
  • ? to match any single character
  • * to match zero or more of any characters
  • | is used as OR operator
"); + ui->lineNotContains->setToolTip(tip); + } +} + +void AutomatedRssDownloader::updateMustLineValidity() +{ + const QString text = ui->lineContains->text(); + bool valid = true; + QStringList tokens; + if(ui->checkRegex->isChecked()) + tokens << text; + else + tokens << text.split(" "); + foreach(const QString &token, tokens) { + QRegExp reg(token, Qt::CaseInsensitive, ui->checkRegex->isChecked() ? QRegExp::RegExp : QRegExp::Wildcard); + if(!reg.isValid()) { + valid = false; + break; + } + } + if(valid) { + ui->lineContains->setStyleSheet(""); + ui->lbl_must_stat->setPixmap(QPixmap()); + } else { + ui->lineContains->setStyleSheet("QLineEdit { color: #ff0000; }"); + ui->lbl_must_stat->setPixmap(IconProvider::instance()->getIcon("task-attention").pixmap(16, 16)); + } +} + +void AutomatedRssDownloader::updateMustNotLineValidity() +{ + const QString text = ui->lineNotContains->text(); + bool valid = true; + QStringList tokens; + if(ui->checkRegex->isChecked()) + tokens << text; + else + tokens << text.split(QRegExp("[\\s|]")); + foreach(const QString &token, tokens) { + QRegExp reg(token, Qt::CaseInsensitive, ui->checkRegex->isChecked() ? QRegExp::RegExp : QRegExp::Wildcard); + if(!reg.isValid()) { + valid = false; + break; + } + } + if(valid) { + ui->lineNotContains->setStyleSheet(""); + ui->lbl_mustnot_stat->setPixmap(QPixmap()); + } else { + ui->lineNotContains->setStyleSheet("QLineEdit { color: #ff0000; }"); + ui->lbl_mustnot_stat->setPixmap(IconProvider::instance()->getIcon("task-attention").pixmap(16, 16)); + } +} + + diff --git a/src/rss/automatedrssdownloader.h b/src/rss/automatedrssdownloader.h new file mode 100644 index 000000000..b685a9943 --- /dev/null +++ b/src/rss/automatedrssdownloader.h @@ -0,0 +1,93 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef AUTOMATEDRSSDOWNLOADER_H +#define AUTOMATEDRSSDOWNLOADER_H + +#include +#include "rssdownloadrule.h" + +QT_BEGIN_NAMESPACE +namespace Ui { +class AutomatedRssDownloader; +} +QT_END_NAMESPACE + +class RssDownloadRuleList; + +QT_BEGIN_NAMESPACE +class QListWidgetItem; +QT_END_NAMESPACE + +class AutomatedRssDownloader : public QDialog +{ + Q_OBJECT + +public: + explicit AutomatedRssDownloader(QWidget *parent = 0); + ~AutomatedRssDownloader(); + bool isRssDownloaderEnabled() const; + +protected slots: + void loadSettings(); + void saveSettings(); + void loadRulesList(); + void handleFeedCheckStateChange(QListWidgetItem* feed_item); + void updateRuleDefinitionBox(); + void clearRuleDefinitionBox(); + void saveEditedRule(); + void loadFeedList(); + void updateFeedList(); + +private slots: + void displayRulesListMenu(const QPoint& pos); + void on_addRuleBtn_clicked(); + void on_removeRuleBtn_clicked(); + void on_browseSP_clicked(); + void on_exportBtn_clicked(); + void on_importBtn_clicked(); + void renameSelectedRule(); + void updateMatchingArticles(); + void updateFieldsToolTips(bool regex); + void updateMustLineValidity(); + void updateMustNotLineValidity(); + +private: + RssDownloadRule getCurrentRule() const; + void initLabelCombobox(); + void addFeedArticlesToTree(const RssFeed *feed, const QStringList& articles); + +private: + Ui::AutomatedRssDownloader *ui; + QListWidgetItem* m_editedRule; + RssDownloadRuleList *m_ruleList; +}; + +#endif // AUTOMATEDRSSDOWNLOADER_H diff --git a/src/rss/automatedrssdownloader.ui b/src/rss/automatedrssdownloader.ui new file mode 100644 index 000000000..563914dff --- /dev/null +++ b/src/rss/automatedrssdownloader.ui @@ -0,0 +1,476 @@ + + + AutomatedRssDownloader + + + + 0 + 0 + 816 + 494 + + + + Automated RSS Downloader + + + + + + + 75 + true + + + + Enable the automated RSS downloader + + + + + + + Qt::Horizontal + + + + + + + + + + 75 + true + + + + Download rules + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + + + 24 + 20 + + + + + + + + + + + + 24 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::CustomContextMenu + + + + + + + + + + + Rule definition + + + + + + Use regular expressions + + + + + + + + + Must contain: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + 0 + 0 + + + + + 18 + 18 + + + + + 18 + 18 + + + + + + + + + + + + + Must not contain: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + 0 + 0 + + + + + 18 + 18 + + + + + 18 + 18 + + + + + + + + + + + + + + + Qt::Horizontal + + + + + + + + + Assign label: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + true + + + + + + + + + Save to a different directory + + + + + + + + + false + + + Save to: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + false + + + + + + + false + + + ... + + + + + + + + + + + + + + + + + 50 + false + + + + Apply rule to feeds: + + + + + + + + + + + + + + + + + 75 + true + + + + Matching RSS articles + + + + + + + false + + + + 1 + + + + + + + + + + + + + + Import... + + + + + + + Export... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + + + buttonBox + accepted() + AutomatedRssDownloader + accept() + + + 750 + 483 + + + 157 + 274 + + + + + buttonBox + rejected() + AutomatedRssDownloader + reject() + + + 805 + 483 + + + 286 + 274 + + + + + saveDiffDir_check + toggled(bool) + label_6 + setEnabled(bool) + + + 304 + 171 + + + 377 + 205 + + + + + saveDiffDir_check + toggled(bool) + lineSavePath + setEnabled(bool) + + + 474 + 174 + + + 476 + 204 + + + + + saveDiffDir_check + toggled(bool) + browseSP + setEnabled(bool) + + + 544 + 166 + + + 549 + 209 + + + + + diff --git a/src/rss/cookiesdlg.cpp b/src/rss/cookiesdlg.cpp new file mode 100644 index 000000000..b1a092e69 --- /dev/null +++ b/src/rss/cookiesdlg.cpp @@ -0,0 +1,104 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org arnaud@qbittorrent.org + */ + +#include "cookiesdlg.h" +#include "ui_cookiesdlg.h" +#include "iconprovider.h" + +#include + +enum CookiesCols { COOKIE_KEY, COOKIE_VALUE}; + +CookiesDlg::CookiesDlg(QWidget *parent, const QList &raw_cookies) : + QDialog(parent), + ui(new Ui::CookiesDlg) +{ + ui->setupUi(this); + // Icons + ui->add_btn->setIcon(IconProvider::instance()->getIcon("list-add")); + ui->del_btn->setIcon(IconProvider::instance()->getIcon("list-remove")); + + ui->infos_lbl->setText(tr("Common keys for cookies are : '%1', '%2'.\nYou should get this information from your Web browser preferences.").arg("uid").arg("pass")); + foreach(const QByteArray &raw_cookie, raw_cookies) { + QList cookie_parts = raw_cookie.split('='); + if(cookie_parts.size() != 2) continue; + const int i = ui->cookiesTable->rowCount(); + ui->cookiesTable->setRowCount(i+1); + ui->cookiesTable->setItem(i, COOKIE_KEY, new QTableWidgetItem(cookie_parts.first().data())); + ui->cookiesTable->setItem(i, COOKIE_VALUE, new QTableWidgetItem(cookie_parts.last().data())); + } +} + +CookiesDlg::~CookiesDlg() +{ + delete ui; +} + +void CookiesDlg::on_add_btn_clicked() { + ui->cookiesTable->setRowCount(ui->cookiesTable->rowCount()+1); + // Edit first column + ui->cookiesTable->editItem(ui->cookiesTable->item(ui->cookiesTable->rowCount()-1, COOKIE_KEY)); +} + +void CookiesDlg::on_del_btn_clicked() { + // Get selected cookie + QList selection = ui->cookiesTable->selectedItems(); + if(!selection.isEmpty()) { + ui->cookiesTable->removeRow(selection.first()->row()); + } +} + +QList CookiesDlg::getCookies() const { + QList ret; + for(int i=0; icookiesTable->rowCount(); ++i) { + QString key; + if(ui->cookiesTable->item(i, COOKIE_KEY)) + key = ui->cookiesTable->item(i, COOKIE_KEY)->text().trimmed(); + QString value; + if(ui->cookiesTable->item(i, COOKIE_VALUE)) + value = ui->cookiesTable->item(i, COOKIE_VALUE)->text().trimmed(); + if(!key.isEmpty() && !value.isEmpty()) { + const QString raw_cookie = key+"="+value; + qDebug("Cookie: %s", qPrintable(raw_cookie)); + ret << raw_cookie.toLocal8Bit(); + } + } + return ret; +} + +QList CookiesDlg::askForCookies(QWidget *parent, const QList &raw_cookies, bool *ok) { + CookiesDlg dlg(parent, raw_cookies); + if(dlg.exec()) { + *ok = true; + return dlg.getCookies(); + } + *ok = false; + return QList(); +} diff --git a/src/rss/cookiesdlg.h b/src/rss/cookiesdlg.h new file mode 100644 index 000000000..3e7469973 --- /dev/null +++ b/src/rss/cookiesdlg.h @@ -0,0 +1,60 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org arnaud@qbittorrent.org + */ + +#ifndef COOKIESDLG_H +#define COOKIESDLG_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { + class CookiesDlg; +} +QT_END_NAMESPACE + +class CookiesDlg : public QDialog +{ + Q_OBJECT + +public: + explicit CookiesDlg(QWidget *parent = 0, const QList &raw_cookies = QList()); + ~CookiesDlg(); + QList getCookies() const; + static QList askForCookies(QWidget *parent, const QList &raw_cookies, bool *ok); + + protected slots: + void on_add_btn_clicked(); + void on_del_btn_clicked(); + +private: + Ui::CookiesDlg *ui; +}; + +#endif // COOKIESDLG_H diff --git a/src/rss/cookiesdlg.ui b/src/rss/cookiesdlg.ui new file mode 100644 index 000000000..ebaf4e03f --- /dev/null +++ b/src/rss/cookiesdlg.ui @@ -0,0 +1,172 @@ + + + CookiesDlg + + + + 0 + 0 + 400 + 300 + + + + Cookies management + + + + + + true + + + QAbstractItemView::SingleSelection + + + true + + + false + + + false + + + + Key + + + + + Value + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + 20 + 20 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 5 + + + + + + + + + + + + 20 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + TextLabel + + + + + + + + + buttonBox + accepted() + CookiesDlg + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + CookiesDlg + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/rss/feedlistwidget.cpp b/src/rss/feedlistwidget.cpp new file mode 100644 index 000000000..17a286cc3 --- /dev/null +++ b/src/rss/feedlistwidget.cpp @@ -0,0 +1,221 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#include "feedlistwidget.h" +#include "rssmanager.h" +#include "rssfeed.h" +#include "iconprovider.h" + +FeedListWidget::FeedListWidget(QWidget *parent, RssManager *rssmanager): QTreeWidget(parent), m_rssManager(rssmanager) { + setContextMenuPolicy(Qt::CustomContextMenu); + setDragDropMode(QAbstractItemView::InternalMove); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setColumnCount(1); + headerItem()->setText(0, tr("RSS feeds")); + m_unreadStickyItem = new QTreeWidgetItem(this); + m_unreadStickyItem->setText(0, tr("Unread") + QString::fromUtf8(" (") + QString::number(rssmanager->unreadCount(), 10)+ QString(")")); + m_unreadStickyItem->setData(0,Qt::DecorationRole, IconProvider::instance()->getIcon("mail-folder-inbox")); + itemAdded(m_unreadStickyItem, rssmanager); + connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(updateCurrentFeed(QTreeWidgetItem*))); + setCurrentItem(m_unreadStickyItem); +} + +FeedListWidget::~FeedListWidget() { + delete m_unreadStickyItem; +} + +void FeedListWidget::itemAdded(QTreeWidgetItem *item, IRssFile* file) { + m_rssMapping[item] = file; + if(file->type() == IRssFile::FEED) { + m_feedsItems[file->id()] = item; + } +} + +void FeedListWidget::itemAboutToBeRemoved(QTreeWidgetItem *item) { + IRssFile* file = m_rssMapping.take(item); + if(file->type() == IRssFile::FEED) { + m_feedsItems.remove(file->id()); + } else { + QList feeds = ((RssFolder*)file)->getAllFeeds(); + foreach(RssFeed* feed, feeds) { + m_feedsItems.remove(feed->id()); + } + } +} + +bool FeedListWidget::hasFeed(const QString &url) const { + return m_feedsItems.contains(QUrl(url).toString()); +} + +QList FeedListWidget::getAllFeedItems() const { + return m_feedsItems.values(); +} + +QTreeWidgetItem* FeedListWidget::stickyUnreadItem() const { + return m_unreadStickyItem; +} + +QStringList FeedListWidget::getItemPath(QTreeWidgetItem* item) const { + QStringList path; + if(item) { + if(item->parent()) + path << getItemPath(item->parent()); + path.append(getRSSItem(item)->id()); + } + return path; +} + +QList FeedListWidget::getAllOpenFolders(QTreeWidgetItem *parent) const { + QList open_folders; + int nbChildren; + if(parent) + nbChildren = parent->childCount(); + else + nbChildren = topLevelItemCount(); + for(int i=0; ichild(i); + else + item = topLevelItem(i); + if(getItemType(item) == IRssFile::FOLDER && item->isExpanded()) { + QList open_subfolders = getAllOpenFolders(item); + if(!open_subfolders.empty()) { + open_folders << open_subfolders; + } else { + open_folders << item; + } + } + } + return open_folders; +} + +QList FeedListWidget::getAllFeedItems(QTreeWidgetItem* folder) { + QList feeds; + const int nbChildren = folder->childCount(); + for(int i=0; ichild(i); + if(getItemType(item) == IRssFile::FEED) { + feeds << item; + } else { + feeds << getAllFeedItems(item); + } + } + return feeds; +} + +IRssFile* FeedListWidget::getRSSItem(QTreeWidgetItem *item) const { + return m_rssMapping.value(item, 0); +} + +IRssFile::FileType FeedListWidget::getItemType(QTreeWidgetItem *item) const { + return m_rssMapping.value(item)->type(); +} + +QString FeedListWidget::getItemID(QTreeWidgetItem *item) const { + return m_rssMapping.value(item)->id(); +} + +QTreeWidgetItem* FeedListWidget::getTreeItemFromUrl(const QString &url) const{ + return m_feedsItems.value(url, 0); +} + +RssFeed* FeedListWidget::getRSSItemFromUrl(const QString &url) const { + return dynamic_cast(getRSSItem(getTreeItemFromUrl(url))); +} + +QTreeWidgetItem* FeedListWidget::currentItem() const { + return m_currentFeed; +} + +QTreeWidgetItem* FeedListWidget::currentFeed() const { + return m_currentFeed; +} + +void FeedListWidget::updateCurrentFeed(QTreeWidgetItem* new_item) { + if(!new_item) return; + if(!m_rssMapping.contains(new_item)) return; + if((getItemType(new_item) == IRssFile::FEED) || new_item == m_unreadStickyItem) + m_currentFeed = new_item; +} + +void FeedListWidget::dragMoveEvent(QDragMoveEvent * event) { + QTreeWidgetItem *item = itemAt(event->pos()); + if(item == m_unreadStickyItem) { + event->ignore(); + } else { + if(item && getItemType(item) != IRssFile::FOLDER) + event->ignore(); + else { + if(selectedItems().contains(m_unreadStickyItem)) { + event->ignore(); + } else { + QTreeWidget::dragMoveEvent(event); + } + } + } +} + +void FeedListWidget::dropEvent(QDropEvent *event) { + qDebug("dropEvent"); + QList folders_altered; + QTreeWidgetItem *dest_folder_item = itemAt(event->pos()); + RssFolder *dest_folder; + if(dest_folder_item) { + dest_folder = (RssFolder*)getRSSItem(dest_folder_item); + folders_altered << dest_folder_item; + } else { + dest_folder = m_rssManager; + } + QList src_items = selectedItems(); + // Check if there is not going to overwrite another file + foreach(QTreeWidgetItem *src_item, src_items) { + IRssFile *file = getRSSItem(src_item); + if(dest_folder->hasChild(file->id())) { + emit overwriteAttempt(file->id()); + return; + } + } + // Proceed with the move + foreach(QTreeWidgetItem *src_item, src_items) { + QTreeWidgetItem *parent_folder = src_item->parent(); + if(parent_folder && !folders_altered.contains(parent_folder)) + folders_altered << parent_folder; + // Actually move the file + IRssFile *file = getRSSItem(src_item); + m_rssManager->moveFile(file, dest_folder); + } + QTreeWidget::dropEvent(event); + if(dest_folder_item) + dest_folder_item->setExpanded(true); + // Emit signal for update + if(!folders_altered.empty()) + emit foldersAltered(folders_altered); +} diff --git a/src/rss/feedlistwidget.h b/src/rss/feedlistwidget.h new file mode 100644 index 000000000..cae497e76 --- /dev/null +++ b/src/rss/feedlistwidget.h @@ -0,0 +1,91 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#ifndef FEEDLIST_H +#define FEEDLIST_H + +#include +#include +#include +#include +#include +#include +#include + +#include "rssfile.h" + +class RssManager; +class RssFeed; + +class FeedListWidget: public QTreeWidget { + Q_OBJECT + +public: + FeedListWidget(QWidget *parent, RssManager *m_rssManager); + ~FeedListWidget(); + + bool hasFeed(const QString &url) const; + QList getAllFeedItems() const; + QTreeWidgetItem* stickyUnreadItem() const; + QStringList getItemPath(QTreeWidgetItem* item) const; + QList getAllOpenFolders(QTreeWidgetItem *parent=0) const; + QList getAllFeedItems(QTreeWidgetItem* folder); + IRssFile* getRSSItem(QTreeWidgetItem *item) const; + IRssFile::FileType getItemType(QTreeWidgetItem *item) const; + QString getItemID(QTreeWidgetItem *item) const; + QTreeWidgetItem* getTreeItemFromUrl(const QString &url) const; + RssFeed* getRSSItemFromUrl(const QString &url) const; + QTreeWidgetItem* currentItem() const; + QTreeWidgetItem* currentFeed() const; + +public slots: + void itemAdded(QTreeWidgetItem *item, IRssFile* file); + void itemAboutToBeRemoved(QTreeWidgetItem *item); + +signals: + void foldersAltered(const QList &folders); + void overwriteAttempt(const QString &filename); + +private slots: + void updateCurrentFeed(QTreeWidgetItem* new_item); + +protected: + void dragMoveEvent(QDragMoveEvent * event); + void dropEvent(QDropEvent *event); + +private: + RssManager *m_rssManager; + QHash m_rssMapping; + QHash m_feedsItems; + QTreeWidgetItem* m_currentFeed; + QTreeWidgetItem *m_unreadStickyItem; +}; + +#endif // FEEDLIST_H diff --git a/src/rss/rss.pri b/src/rss/rss.pri new file mode 100644 index 000000000..2dbcec27e --- /dev/null +++ b/src/rss/rss.pri @@ -0,0 +1,34 @@ +INCLUDEPATH += $$PWD + +HEADERS += $$PWD/rss_imp.h \ + $$PWD/rsssettingsdlg.h \ + $$PWD/feedlistwidget.h \ + $$PWD/rssmanager.h \ + $$PWD/rssfeed.h \ + $$PWD/rssfolder.h \ + $$PWD/rssfile.h \ + $$PWD/rssarticle.h \ + $$PWD/automatedrssdownloader.h \ + $$PWD/rsssettings.h \ + $$PWD/rssdownloadrule.h \ + $$PWD/rssdownloadrulelist.h \ + $$PWD/cookiesdlg.h \ + $$PWD/rssarticle_p.h + +SOURCES += $$PWD/rss_imp.cpp \ + $$PWD/rsssettingsdlg.cpp \ + $$PWD/feedlistwidget.cpp \ + $$PWD/rssmanager.cpp \ + $$PWD/rssfeed.cpp \ + $$PWD/rssfolder.cpp \ + $$PWD/rssarticle.cpp \ + $$PWD/automatedrssdownloader.cpp \ + $$PWD/rssdownloadrule.cpp \ + $$PWD/rssdownloadrulelist.cpp \ + $$PWD/cookiesdlg.cpp \ + rss/rssfile.cpp + +FORMS += $$PWD/rss.ui \ + $$PWD/rsssettingsdlg.ui \ + $$PWD/automatedrssdownloader.ui \ + $$PWD/cookiesdlg.ui diff --git a/src/rss/rss.ui b/src/rss/rss.ui new file mode 100644 index 000000000..1be250968 --- /dev/null +++ b/src/rss/rss.ui @@ -0,0 +1,217 @@ + + + RSS + + + + 0 + 0 + 811 + 447 + + + + false + + + Search + + + + + + + + New subscription + + + Qt::ToolButtonTextBesideIcon + + + + + + + Mark items read + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 32 + 32 + + + + Refresh RSS streams + + + Update all + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + RSS Downloader... + + + + + + + Settings... + + + + + + + + + Qt::Horizontal + + + + + + + + 50 + false + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Torrents:</span> <span style=" font-style:italic;">(double-click to download)</span></p></body></html> + + + + + + + Qt::Vertical + + + + Qt::CustomContextMenu + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectItems + + + + + + + + + + + + + Delete + + + Delete + + + + + Rename... + + + Rename + + + + + Update + + + Update + + + + + New subscription... + + + + + Update all feeds + + + Update all feeds + + + + + Mark items read + + + Mark items read + + + + + Download torrent + + + + + Open news URL + + + + + Copy feed URL + + + + + New folder... + + + + + Manage cookies... + + + + + + diff --git a/src/rss/rss_imp.cpp b/src/rss/rss_imp.cpp new file mode 100644 index 000000000..6b49ef4b6 --- /dev/null +++ b/src/rss/rss_imp.cpp @@ -0,0 +1,685 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org arnaud@qbittorrent.org + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rss_imp.h" +#include "feedlistwidget.h" +#include "qbtsession.h" +#include "cookiesdlg.h" +#include "preferences.h" +#include "rsssettingsdlg.h" +#include "rssmanager.h" +#include "rssfolder.h" +#include "rssarticle.h" +#include "rssfeed.h" +#include "rsssettings.h" +#include "automatedrssdownloader.h" +#include "iconprovider.h" + +namespace Article { +enum ArticleRoles { + TitleRole = Qt::DisplayRole, + IconRole = Qt::DecorationRole, + ColorRole = Qt::ForegroundRole, + IdRole = Qt::UserRole + 1, + FeedUrlRole = Qt::UserRole + 2 +}; +} + +// display a right-click menu +void RSSImp::displayRSSListMenu(const QPoint& pos){ + if(!m_feedList->indexAt(pos).isValid()) { + // No item under the mouse, clear selection + m_feedList->clearSelection(); + } + QMenu myRSSListMenu(this); + QList selectedItems = m_feedList->selectedItems(); + if(selectedItems.size() > 0) { + myRSSListMenu.addAction(actionUpdate); + myRSSListMenu.addAction(actionMark_items_read); + myRSSListMenu.addSeparator(); + if(selectedItems.size() == 1) { + if(m_feedList->getRSSItem(selectedItems.first()) != m_rssManager) { + myRSSListMenu.addAction(actionRename); + myRSSListMenu.addAction(actionDelete); + myRSSListMenu.addSeparator(); + if(m_feedList->getItemType(selectedItems.first()) == IRssFile::FOLDER) { + myRSSListMenu.addAction(actionNew_folder); + } else { + myRSSListMenu.addAction(actionManage_cookies); + } + } + } + myRSSListMenu.addAction(actionNew_subscription); + if(m_feedList->getItemType(selectedItems.first()) == IRssFile::FEED) { + myRSSListMenu.addSeparator(); + myRSSListMenu.addAction(actionCopy_feed_URL); + } + }else{ + myRSSListMenu.addAction(actionNew_subscription); + myRSSListMenu.addAction(actionNew_folder); + myRSSListMenu.addSeparator(); + myRSSListMenu.addAction(actionUpdate_all_feeds); + } + myRSSListMenu.exec(QCursor::pos()); +} + +void RSSImp::displayItemsListMenu(const QPoint&){ + QMenu myItemListMenu(this); + QList selectedItems = listArticles->selectedItems(); + if(selectedItems.size() > 0) { + bool has_attachment = false; + foreach(const QListWidgetItem *item, selectedItems) { + qDebug("text(3) URL: %s", qPrintable(item->data(Article::FeedUrlRole).toString())); + qDebug("text(2) TITLE: %s", qPrintable(item->data(Article::TitleRole).toString())); + if(m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString()) + ->getItem(item->data(Article::IdRole).toString()).hasAttachment()) { + has_attachment = true; + break; + } + } + if(has_attachment) + myItemListMenu.addAction(actionDownload_torrent); + myItemListMenu.addAction(actionOpen_news_URL); + } + myItemListMenu.exec(QCursor::pos()); +} + +void RSSImp::on_actionManage_cookies_triggered() { + Q_ASSERT(!m_feedList->selectedItems().empty()); + // Get feed hostname + QString feed_url = m_feedList->getItemID(m_feedList->selectedItems().first()); + QString feed_hostname = QUrl::fromEncoded(feed_url.toLocal8Bit()).host(); + qDebug("RSS Feed hostname is: %s", qPrintable(feed_hostname)); + Q_ASSERT(!feed_hostname.isEmpty()); + bool ok = false; + RssSettings settings; + QList raw_cookies = CookiesDlg::askForCookies(this, settings.getHostNameCookies(feed_hostname), &ok); + if(ok) { + settings.setHostNameCookies(feed_hostname, raw_cookies); + } +} + +void RSSImp::askNewFolder() { + QTreeWidgetItem *parent_item = 0; + RssFolder *rss_parent; + if(m_feedList->selectedItems().size() > 0) { + parent_item = m_feedList->selectedItems().at(0); + rss_parent = dynamic_cast(m_feedList->getRSSItem(parent_item)); + Q_ASSERT(rss_parent->type() == IRssFile::FOLDER); + } else { + rss_parent = m_rssManager; + } + bool ok; + QString new_name = QInputDialog::getText(this, tr("Please choose a folder name"), tr("Folder name:"), QLineEdit::Normal, tr("New folder"), &ok); + if(ok) { + RssFolder* new_folder = rss_parent->addFolder(new_name); + QTreeWidgetItem* folder_item; + if(parent_item) + folder_item = new QTreeWidgetItem(parent_item); + else + folder_item = new QTreeWidgetItem(m_feedList); + // Notify TreeWidget + m_feedList->itemAdded(folder_item, new_folder); + // Set Text + folder_item->setText(0, new_folder->displayName() + QString::fromUtf8(" (0)")); + folder_item->setData(0,Qt::DecorationRole, QVariant(IconProvider::instance()->getIcon("inode-directory"))); + // Expand parent folder to display new folder + if(parent_item) + parent_item->setExpanded(true); + m_rssManager->saveStreamList(); + } +} + +void RSSImp::displayOverwriteError(const QString &filename) { + QMessageBox::warning(this, tr("Overwrite attempt"), + tr("You cannot overwrite %1 item.", "You cannot overwrite myFolder item.").arg(filename), + QMessageBox::Ok); +} + +// add a stream by a button +void RSSImp::on_newFeedButton_clicked() { + // Determine parent folder for new feed + QTreeWidgetItem *parent_item = 0; + QList selected_items = m_feedList->selectedItems(); + if(!selected_items.empty()) { + parent_item = selected_items.first(); + // Consider the case where the user clicked on Unread item + if(parent_item == m_feedList->stickyUnreadItem()) { + parent_item = 0; + } else { + if(m_feedList->getItemType(parent_item) != IRssFile::FOLDER) + parent_item = parent_item->parent(); + } + } + RssFolder *rss_parent; + if(parent_item) { + rss_parent = (RssFolder*)m_feedList->getRSSItem(parent_item); + } else { + rss_parent = m_rssManager; + } + // Ask for feed URL + bool ok; + QString clip_txt = qApp->clipboard()->text(); + QString default_url = "http://"; + if(clip_txt.startsWith("http://", Qt::CaseInsensitive) || clip_txt.startsWith("https://", Qt::CaseInsensitive) || clip_txt.startsWith("ftp://", Qt::CaseInsensitive)) { + default_url = clip_txt; + } + QString newUrl = QInputDialog::getText(this, tr("Please type a rss stream url"), tr("Stream URL:"), QLineEdit::Normal, default_url, &ok); + if(ok) { + newUrl = newUrl.trimmed(); + if(!newUrl.isEmpty()){ + if(m_feedList->hasFeed(newUrl)) { + QMessageBox::warning(this, tr("qBittorrent"), + tr("This rss feed is already in the list."), + QMessageBox::Ok); + return; + } + RssFeed *stream = rss_parent->addStream(newUrl); + // Create TreeWidget item + QTreeWidgetItem* item; + if(parent_item) + item = new QTreeWidgetItem(parent_item); + else + item = new QTreeWidgetItem(m_feedList); + // Notify TreeWidget + m_feedList->itemAdded(item, stream); + // Set text + item->setText(0, stream->displayName() + QString::fromUtf8(" (0)")); + item->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/loading.png"))); + stream->refresh(); + m_rssManager->saveStreamList(); + } + } +} + +// delete a stream by a button +void RSSImp::deleteSelectedItems() { + QList selectedItems = m_feedList->selectedItems(); + if(selectedItems.size() == 0) return; + int ret; + if(selectedItems.size() > 1) + ret = QMessageBox::question(this, tr("Are you sure? -- qBittorrent"), tr("Are you sure you want to delete these elements from the list?"), + tr("&Yes"), tr("&No"), + QString(), 0, 1); + else + ret = QMessageBox::question(this, tr("Are you sure? -- qBittorrent"), tr("Are you sure you want to delete this element from the list?"), + tr("&Yes"), tr("&No"), + QString(), 0, 1); + if(!ret) { + foreach(QTreeWidgetItem *item, selectedItems){ + if(m_feedList->currentFeed() == item){ + textBrowser->clear(); + m_currentArticle = 0; + listArticles->clear(); + } + IRssFile *rss_item = m_feedList->getRSSItem(item); + // Notify TreeWidget + m_feedList->itemAboutToBeRemoved(item); + // Actually delete the item + rss_item->parent()->removeChild(rss_item->id()); + delete item; + } + m_rssManager->saveStreamList(); + // Update Unread items + updateItemInfos(m_feedList->stickyUnreadItem()); + } +} + +void RSSImp::loadFoldersOpenState() { + QIniSettings settings("qBittorrent", "qBittorrent"); + settings.beginGroup("Rss"); + QStringList open_folders = settings.value("open_folders", QStringList()).toStringList(); + settings.endGroup(); + foreach(QString var_path, open_folders) { + QStringList path = var_path.split("\\"); + QTreeWidgetItem *parent = 0; + foreach(QString name, path) { + int nbChildren = 0; + if(parent) + nbChildren = parent->childCount(); + else + nbChildren = m_feedList->topLevelItemCount(); + for(int i=0; ichild(i); + else + child = m_feedList->topLevelItem(i); + if(m_feedList->getRSSItem(child)->id() == name) { + parent = child; + parent->setExpanded(true); + qDebug("expanding folder %s", qPrintable(name)); + break; + } + } + } + } +} + +void RSSImp::saveFoldersOpenState() { + QStringList open_folders; + QList items = m_feedList->getAllOpenFolders(); + foreach(QTreeWidgetItem* item, items) { + QString path = m_feedList->getItemPath(item).join("\\"); + qDebug("saving open folder: %s", qPrintable(path)); + open_folders << path; + } + QIniSettings settings("qBittorrent", "qBittorrent"); + settings.beginGroup("Rss"); + settings.setValue("open_folders", open_folders); + settings.endGroup(); +} + +// refresh all streams by a button +void RSSImp::on_updateAllButton_clicked() { + foreach(QTreeWidgetItem *item, m_feedList->getAllFeedItems()) { + item->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/loading.png"))); + } + m_rssManager->refresh(); +} + +void RSSImp::downloadTorrent() { + QList selected_items = listArticles->selectedItems(); + foreach(const QListWidgetItem* item, selected_items) { + const RssArticle article = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString()) + ->getItem(item->data(Article::IdRole).toString()); + if(article.hasAttachment()) { + QBtSession::instance()->downloadFromUrl(article.torrentUrl()); + } else { + QBtSession::instance()->downloadFromUrl(article.link()); + } + } +} + +// open the url of the news in a browser +void RSSImp::openNewsUrl() { + QList selected_items = listArticles->selectedItems(); + foreach(const QListWidgetItem* item, selected_items) { + const RssArticle news = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString()) + ->getItem(item->data(Article::IdRole).toString()); + const QString link = news.link(); + if(!link.isEmpty()) + QDesktopServices::openUrl(QUrl(link)); + } +} + +//right-click on stream : give it an alias +void RSSImp::renameFiles() { + QList selectedItems = m_feedList->selectedItems(); + Q_ASSERT(selectedItems.size() == 1); + QTreeWidgetItem *item = selectedItems.at(0); + IRssFile *rss_item = m_feedList->getRSSItem(item); + bool ok; + QString newName; + do { + newName = QInputDialog::getText(this, tr("Please choose a new name for this RSS feed"), tr("New feed name:"), QLineEdit::Normal, m_feedList->getRSSItem(item)->displayName(), &ok); + // Check if name is already taken + if(ok) { + if(rss_item->parent()->hasChild(newName)) { + QMessageBox::warning(0, tr("Name already in use"), tr("This name is already used by another item, please choose another one.")); + ok = false; + } + } else { + return; + } + }while(!ok); + // Rename item + rss_item->rename(newName); + // Update TreeWidget + updateItemInfos(item); +} + +//right-click on stream : refresh it +void RSSImp::refreshSelectedItems() { + QList selectedItems = m_feedList->selectedItems(); + foreach(QTreeWidgetItem* item, selectedItems){ + IRssFile* file = m_feedList->getRSSItem(item); + // Update icons + if(item == m_feedList->stickyUnreadItem()) { + foreach(QTreeWidgetItem *feed, m_feedList->getAllFeedItems()) { + feed->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/loading.png"))); + } + file->refresh(); + break; + } else { + if(file->type() == IRssFile::FEED) { + item->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/loading.png"))); + } else { + // Update feeds in the folder + foreach(QTreeWidgetItem *feed, m_feedList->getAllFeedItems(item)) { + feed->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/loading.png"))); + } + } + } + // Actually refresh + file->refresh(); + } +} + +void RSSImp::copySelectedFeedsURL() { + QStringList URLs; + QList selectedItems = m_feedList->selectedItems(); + QTreeWidgetItem* item; + foreach(item, selectedItems){ + if(m_feedList->getItemType(item) == IRssFile::FEED) + URLs << m_feedList->getItemID(item); + } + qApp->clipboard()->setText(URLs.join("\n")); +} + +void RSSImp::on_markReadButton_clicked() { + QList selectedItems = m_feedList->selectedItems(); + QTreeWidgetItem* item; + foreach(item, selectedItems){ + IRssFile *rss_item = m_feedList->getRSSItem(item); + rss_item->markAsRead(); + updateItemInfos(item); + } + if(selectedItems.size()) + refreshArticleList(m_feedList->currentItem()); +} + +void RSSImp::fillFeedsList(QTreeWidgetItem *parent, RssFolder *rss_parent) { + QList children; + if(parent) { + children = rss_parent->getContent(); + } else { + children = m_rssManager->getContent(); + } + foreach(IRssFile* rss_child, children){ + QTreeWidgetItem* item; + if(!parent) + item = new QTreeWidgetItem(m_feedList); + else + item = new QTreeWidgetItem(parent); + item->setData(0, Qt::DisplayRole, QVariant(rss_child->displayName()+ QString::fromUtf8(" (")+QString::number(rss_child->unreadCount(), 10)+QString(")"))); + // Notify TreeWidget of item addition + m_feedList->itemAdded(item, rss_child); + // Set Icon + if(rss_child->type() == IRssFile::FEED) { + item->setData(0,Qt::DecorationRole, QVariant(QIcon(QString::fromUtf8(":/Icons/loading.png")))); + } else { + item->setData(0,Qt::DecorationRole, QVariant(IconProvider::instance()->getIcon("inode-directory"))); + // Recurvive call to load sub folders/files + fillFeedsList(item, (RssFolder*)rss_child); + } + } +} + +// fills the newsList +void RSSImp::refreshArticleList(QTreeWidgetItem* item) { + if(!item) { + listArticles->clear(); + return; + } + + IRssFile *rss_item = m_feedList->getRSSItem(item); + if(!rss_item) return; + + qDebug("Getting the list of news"); + QList news; + if(rss_item == m_rssManager) + news = RssManager::sortNewsList(rss_item->unreadArticleList()); + else if(rss_item) + news = RssManager::sortNewsList(rss_item->articleList()); + // Clear the list first + textBrowser->clear(); + m_currentArticle = 0; + listArticles->clear(); + qDebug("Got the list of news"); + foreach(const RssArticle &article, news){ + QListWidgetItem* it = new QListWidgetItem(listArticles); + it->setData(Article::TitleRole, article.title()); + it->setData(Article::FeedUrlRole, article.parent()->url()); + it->setData(Article::IdRole, article.guid()); + if(article.isRead()){ + it->setData(Article::ColorRole, QVariant(QColor("grey"))); + it->setData(Article::IconRole, QVariant(QIcon(":/Icons/sphere.png"))); + }else{ + it->setData(Article::ColorRole, QVariant(QColor("blue"))); + it->setData(Article::IconRole, QVariant(QIcon(":/Icons/sphere2.png"))); + } + } + qDebug("Added all news to the GUI"); + qDebug("First news selected"); +} + +// display a news +void RSSImp::refreshTextBrowser() { + QList selection = listArticles->selectedItems(); + if(selection.empty()) return; + Q_ASSERT(selection.size() == 1); + QListWidgetItem *item = selection.first(); + Q_ASSERT(item); + if(item == m_currentArticle) return; + // Stop displaying previous news if necessary + if(m_feedList->currentFeed() == m_feedList->stickyUnreadItem()) { + if(m_currentArticle) { + disconnect(listArticles, SIGNAL(itemSelectionChanged()), this, SLOT(refreshTextBrowser())); + listArticles->removeItemWidget(m_currentArticle); + Q_ASSERT(m_currentArticle); + delete m_currentArticle; + connect(listArticles, SIGNAL(itemSelectionChanged()), this, SLOT(refreshTextBrowser())); + } + m_currentArticle = item; + } + RssFeed *stream = m_feedList->getRSSItemFromUrl(item->data(Article::FeedUrlRole).toString()); + RssArticle &article = stream->getItem(item->data(Article::IdRole).toString()); + QString html; + html += "
"; + html += "
"+article.title() + "
"; + if(article.date().isValid()) { + html += "
"+tr("Date: ")+""+article.date().toLocalTime().toString(Qt::SystemLocaleLongDate)+"
"; + } + if(!article.author().isEmpty()) { + html += "
"+tr("Author: ")+""+article.author()+"
"; + } + html += "
"; + html += ""+article.description()+""; + textBrowser->setHtml(html); + article.markAsRead(); + item->setData(Article::ColorRole, QVariant(QColor("grey"))); + item->setData(Article::IconRole, QVariant(QIcon(":/Icons/sphere.png"))); + // Decrement feed nb unread news + updateItemInfos(m_feedList->stickyUnreadItem()); + updateItemInfos(m_feedList->getTreeItemFromUrl(item->data(Article::FeedUrlRole).toString())); +} + +void RSSImp::saveSlidersPosition() { + // Remember sliders positions + QIniSettings settings("qBittorrent", "qBittorrent"); + settings.setValue("rss/splitter_h", splitter_h->saveState()); + settings.setValue("rss/splitter_v", splitter_v->saveState()); + qDebug("Splitters position saved"); +} + +void RSSImp::restoreSlidersPosition() { + QIniSettings settings("qBittorrent", "qBittorrent"); + QByteArray pos_h = settings.value("rss/splitter_h", QByteArray()).toByteArray(); + if(!pos_h.isNull()) { + splitter_h->restoreState(pos_h); + } + QByteArray pos_v = settings.value("rss/splitter_v", QByteArray()).toByteArray(); + if(!pos_v.isNull()) { + splitter_v->restoreState(pos_v); + } +} + +void RSSImp::updateItemsInfos(const QList &items) { + foreach(QTreeWidgetItem* item, items) { + updateItemInfos(item); + } +} + +void RSSImp::updateItemInfos(QTreeWidgetItem *item) { + IRssFile *rss_item = m_feedList->getRSSItem(item); + QString name; + if(rss_item == m_rssManager) + name = tr("Unread"); + else + name = rss_item->displayName(); + item->setText(0, name + QString::fromUtf8(" (") + QString::number(rss_item->unreadCount(), 10)+ QString(")")); + // If item has a parent, update it too + if(item->parent()) + updateItemInfos(item->parent()); +} + +void RSSImp::updateFeedIcon(const QString &url, const QString &icon_path){ + QTreeWidgetItem *item = m_feedList->getTreeItemFromUrl(url); + item->setData(0,Qt::DecorationRole, QVariant(QIcon(icon_path))); +} + +void RSSImp::updateFeedInfos(const QString &url, const QString &display_name, uint nbUnread){ + qDebug() << Q_FUNC_INFO << display_name; + QTreeWidgetItem *item = m_feedList->getTreeItemFromUrl(url); + RssFeed *stream = (RssFeed*)m_feedList->getRSSItem(item); + item->setText(0, display_name + QString::fromUtf8(" (") + QString::number(nbUnread, 10)+ QString(")")); + if(!stream->isLoading()) + item->setData(0,Qt::DecorationRole, QVariant(QIcon(stream->icon()))); + // Update parent + if(item->parent()) + updateItemInfos(item->parent()); + // Update Unread item + updateItemInfos(m_feedList->stickyUnreadItem()); + // If the feed is selected, update the displayed news + if(m_feedList->currentItem() == item ){ + refreshArticleList(item); + } else { + // Update unread items + if(m_feedList->currentItem() == m_feedList->stickyUnreadItem()) { + refreshArticleList(m_feedList->stickyUnreadItem()); + } + } +} + +void RSSImp::updateRefreshInterval(uint val) { + m_rssManager->updateRefreshInterval(val); +} + +RSSImp::RSSImp(QWidget *parent) : QWidget(parent) { + setupUi(this); + // Icons + actionCopy_feed_URL->setIcon(IconProvider::instance()->getIcon("edit-copy")); + actionDelete->setIcon(IconProvider::instance()->getIcon("edit-delete")); + actionDownload_torrent->setIcon(IconProvider::instance()->getIcon("download")); + actionManage_cookies->setIcon(IconProvider::instance()->getIcon("preferences-web-browser-cookies")); + actionMark_items_read->setIcon(IconProvider::instance()->getIcon("mail-mark-read")); + actionNew_folder->setIcon(IconProvider::instance()->getIcon("folder-new")); + actionNew_subscription->setIcon(IconProvider::instance()->getIcon("list-add")); + actionOpen_news_URL->setIcon(IconProvider::instance()->getIcon("application-x-mswinurl")); + actionRename->setIcon(IconProvider::instance()->getIcon("edit-rename")); + actionUpdate->setIcon(IconProvider::instance()->getIcon("view-refresh")); + actionUpdate_all_feeds->setIcon(IconProvider::instance()->getIcon("view-refresh")); + newFeedButton->setIcon(IconProvider::instance()->getIcon("list-add")); + markReadButton->setIcon(IconProvider::instance()->getIcon("mail-mark-read")); + updateAllButton->setIcon(IconProvider::instance()->getIcon("view-refresh")); + rssDownloaderBtn->setIcon(IconProvider::instance()->getIcon("download")); + settingsButton->setIcon(IconProvider::instance()->getIcon("preferences-system")); + + m_rssManager = RssManager::instance(); + + m_feedList = new FeedListWidget(splitter_h, m_rssManager); + splitter_h->insertWidget(0, m_feedList); + listArticles->setSelectionBehavior(QAbstractItemView::SelectItems); + listArticles->setSelectionMode(QAbstractItemView::SingleSelection); + + m_rssManager->loadStreamList(); + fillFeedsList(); + refreshArticleList(m_feedList->currentItem()); + + loadFoldersOpenState(); + connect(m_rssManager, SIGNAL(feedInfosChanged(QString, QString, unsigned int)), this, SLOT(updateFeedInfos(QString, QString, unsigned int))); + connect(m_rssManager, SIGNAL(feedIconChanged(QString, QString)), this, SLOT(updateFeedIcon(QString, QString))); + + connect(m_feedList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayRSSListMenu(const QPoint&))); + connect(listArticles, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayItemsListMenu(const QPoint&))); + + // Feeds list actions + connect(actionDelete, SIGNAL(triggered()), this, SLOT(deleteSelectedItems())); + connect(actionRename, SIGNAL(triggered()), this, SLOT(renameFiles())); + connect(actionUpdate, SIGNAL(triggered()), this, SLOT(refreshSelectedItems())); + connect(actionNew_folder, SIGNAL(triggered()), this, SLOT(askNewFolder())); + connect(actionNew_subscription, SIGNAL(triggered()), this, SLOT(on_newFeedButton_clicked())); + connect(actionUpdate_all_feeds, SIGNAL(triggered()), this, SLOT(on_updateAllButton_clicked())); + connect(actionCopy_feed_URL, SIGNAL(triggered()), this, SLOT(copySelectedFeedsURL())); + connect(actionMark_items_read, SIGNAL(triggered()), this, SLOT(on_markReadButton_clicked())); + // News list actions + connect(actionOpen_news_URL, SIGNAL(triggered()), this, SLOT(openNewsUrl())); + connect(actionDownload_torrent, SIGNAL(triggered()), this, SLOT(downloadTorrent())); + + connect(m_feedList, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(refreshArticleList(QTreeWidgetItem*))); + connect(m_feedList, SIGNAL(foldersAltered(QList)), this, SLOT(updateItemsInfos(QList))); + connect(m_feedList, SIGNAL(overwriteAttempt(QString)), this, SLOT(displayOverwriteError(QString))); + + connect(listArticles, SIGNAL(itemSelectionChanged()), this, SLOT(refreshTextBrowser())); + connect(listArticles, SIGNAL(itemDoubleClicked(QListWidgetItem *)), this, SLOT(downloadTorrent())); + + // Refresh all feeds + m_rssManager->refresh(); + // Restore sliders position + restoreSlidersPosition(); + // Bind saveSliders slots + connect(splitter_v, SIGNAL(splitterMoved(int, int)), this, SLOT(saveSlidersPosition())); + connect(splitter_h, SIGNAL(splitterMoved(int, int)), this, SLOT(saveSlidersPosition())); + + qDebug("RSSImp constructed"); +} + +RSSImp::~RSSImp(){ + qDebug("Deleting RSSImp..."); + saveFoldersOpenState(); + delete m_feedList; + RssManager::drop(); + qDebug("RSSImp deleted"); +} + + +void RSSImp::on_settingsButton_clicked() { + RssSettingsDlg dlg(this); + if(dlg.exec()) + updateRefreshInterval(RssSettings().getRSSRefreshInterval()); +} + +void RSSImp::on_rssDownloaderBtn_clicked() +{ + AutomatedRssDownloader dlg(this); + dlg.exec(); + if(dlg.isRssDownloaderEnabled()) + on_updateAllButton_clicked(); +} diff --git a/src/rss/rss_imp.h b/src/rss/rss_imp.h new file mode 100644 index 000000000..fc0aac51d --- /dev/null +++ b/src/rss/rss_imp.h @@ -0,0 +1,93 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org arnaud@qbittorrent.org + */ +#ifndef __RSS_IMP_H__ +#define __RSS_IMP_H__ + +#define REFRESH_MAX_LATENCY 600000 + +#include + +#include "ui_rss.h" + +class FeedListWidget; +class RssFolder; +class RssManager; + +QT_BEGIN_NAMESPACE +class QTreeWidgetItem; +QT_END_NAMESPACE + +class RSSImp : public QWidget, public Ui::RSS { + Q_OBJECT + +public: + RSSImp(QWidget *parent); + ~RSSImp(); + +public slots: + void deleteSelectedItems(); + void updateRefreshInterval(uint val); + +private slots: + void on_newFeedButton_clicked(); + void on_updateAllButton_clicked(); + void on_markReadButton_clicked(); + void displayRSSListMenu(const QPoint&); + void displayItemsListMenu(const QPoint&); + void renameFiles(); + void refreshSelectedItems(); + void copySelectedFeedsURL(); + void refreshArticleList(QTreeWidgetItem* item); + void refreshTextBrowser(); + void updateFeedIcon(const QString &url, const QString &icon_path); + void updateFeedInfos(const QString &url, const QString &display_name, uint nbUnread); + void updateItemsInfos(const QList &items); + void updateItemInfos(QTreeWidgetItem *item); + void openNewsUrl(); + void downloadTorrent(); + void fillFeedsList(QTreeWidgetItem *parent=0, RssFolder *rss_parent=0); + void saveSlidersPosition(); + void restoreSlidersPosition(); + void askNewFolder(); + void saveFoldersOpenState(); + void loadFoldersOpenState(); + void displayOverwriteError(const QString &filename); + void on_actionManage_cookies_triggered(); + void on_settingsButton_clicked(); + void on_rssDownloaderBtn_clicked(); + +private: + RssManager *m_rssManager; + FeedListWidget *m_feedList; + QListWidgetItem* m_currentArticle; + +}; + +#endif diff --git a/src/rss/rssarticle.cpp b/src/rss/rssarticle.cpp new file mode 100644 index 000000000..8a557e93e --- /dev/null +++ b/src/rss/rssarticle.cpp @@ -0,0 +1,330 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#include +#include +#include + +#include + +#include "rssarticle.h" +#include "rssarticle_p.h" + +static const char shortDay[][4] = { + "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat", + "Sun" +}; +static const char longDay[][10] = { + "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday", + "Sunday" +}; +static const char shortMonth[][4] = { + "Jan", "Feb", "Mar", "Apr", + "May", "Jun", "Jul", "Aug", + "Sep", "Oct", "Nov", "Dec" +}; +static const char longMonth[][10] = { + "January", "February", "March", + "April", "May", "June", + "July", "August", "September", + "October", "November", "December" +}; + +// Ported to Qt4 from KDElibs4 +QDateTime RssArticle::parseDate(const QString &string) { + const QString str = string.trimmed(); + if (str.isEmpty()) + return QDateTime::currentDateTime(); + + int nyear = 6; // indexes within string to values + int nmonth = 4; + int nday = 2; + int nwday = 1; + int nhour = 7; + int nmin = 8; + int nsec = 9; + // Also accept obsolete form "Weekday, DD-Mon-YY HH:MM:SS ±hhmm" + QRegExp rx("^(?:([A-Z][a-z]+),\\s*)?(\\d{1,2})(\\s+|-)([^-\\s]+)(\\s+|-)(\\d{2,4})\\s+(\\d\\d):(\\d\\d)(?::(\\d\\d))?\\s+(\\S+)$"); + QStringList parts; + if (!str.indexOf(rx)) { + // Check that if date has '-' separators, both separators are '-'. + parts = rx.capturedTexts(); + bool h1 = (parts[3] == QLatin1String("-")); + bool h2 = (parts[5] == QLatin1String("-")); + if (h1 != h2) + return QDateTime::currentDateTime(); + } else { + // Check for the obsolete form "Wdy Mon DD HH:MM:SS YYYY" + rx = QRegExp("^([A-Z][a-z]+)\\s+(\\S+)\\s+(\\d\\d)\\s+(\\d\\d):(\\d\\d):(\\d\\d)\\s+(\\d\\d\\d\\d)$"); + if (str.indexOf(rx)) + return QDateTime::currentDateTime(); + nyear = 7; + nmonth = 2; + nday = 3; + nwday = 1; + nhour = 4; + nmin = 5; + nsec = 6; + parts = rx.capturedTexts(); + } + bool ok[4]; + const int day = parts[nday].toInt(&ok[0]); + int year = parts[nyear].toInt(&ok[1]); + const int hour = parts[nhour].toInt(&ok[2]); + const int minute = parts[nmin].toInt(&ok[3]); + if (!ok[0] || !ok[1] || !ok[2] || !ok[3]) + return QDateTime::currentDateTime(); + int second = 0; + if (!parts[nsec].isEmpty()) { + second = parts[nsec].toInt(&ok[0]); + if (!ok[0]) + return QDateTime::currentDateTime(); + } + bool leapSecond = (second == 60); + if (leapSecond) + second = 59; // apparently a leap second - validate below, once time zone is known + int month = 0; + for ( ; month < 12 && parts[nmonth] != shortMonth[month]; ++month) ; + int dayOfWeek = -1; + if (!parts[nwday].isEmpty()) { + // Look up the weekday name + while (++dayOfWeek < 7 && shortDay[dayOfWeek] != parts[nwday]) ; + if (dayOfWeek >= 7) + for (dayOfWeek = 0; dayOfWeek < 7 && longDay[dayOfWeek] != parts[nwday]; ++dayOfWeek) ; + } + // if (month >= 12 || dayOfWeek >= 7 + // || (dayOfWeek < 0 && format == RFCDateDay)) + // return QDateTime; + int i = parts[nyear].size(); + if (i < 4) { + // It's an obsolete year specification with less than 4 digits + year += (i == 2 && year < 50) ? 2000: 1900; + } + + // Parse the UTC offset part + int offset = 0; // set default to '-0000' + bool negOffset = false; + if (parts.count() > 10) { + rx = QRegExp("^([+-])(\\d\\d)(\\d\\d)$"); + if (!parts[10].indexOf(rx)) { + // It's a UTC offset ±hhmm + parts = rx.capturedTexts(); + offset = parts[2].toInt(&ok[0]) * 3600; + int offsetMin = parts[3].toInt(&ok[1]); + if (!ok[0] || !ok[1] || offsetMin > 59) + return QDateTime(); + offset += offsetMin * 60; + negOffset = (parts[1] == QLatin1String("-")); + if (negOffset) + offset = -offset; + } else { + // Check for an obsolete time zone name + QByteArray zone = parts[10].toLatin1(); + if (zone.length() == 1 && isalpha(zone[0]) && toupper(zone[0]) != 'J') + negOffset = true; // military zone: RFC 2822 treats as '-0000' + else if (zone != "UT" && zone != "GMT") { // treated as '+0000' + offset = (zone == "EDT") ? -4*3600 + : (zone == "EST" || zone == "CDT") ? -5*3600 + : (zone == "CST" || zone == "MDT") ? -6*3600 + : (zone == "MST" || zone == "PDT") ? -7*3600 + : (zone == "PST") ? -8*3600 + : 0; + if (!offset) { + // Check for any other alphabetic time zone + bool nonalpha = false; + for (int i = 0, end = zone.size(); i < end && !nonalpha; ++i) + nonalpha = !isalpha(zone[i]); + if (nonalpha) + return QDateTime(); + // TODO: Attempt to recognize the time zone abbreviation? + negOffset = true; // unknown time zone: RFC 2822 treats as '-0000' + } + } + } + } + QDate qdate(year, month+1, day); // convert date, and check for out-of-range + if (!qdate.isValid()) + return QDateTime::currentDateTime(); + QDateTime result(qdate, QTime(hour, minute, second)); + if (!result.isValid() + || (dayOfWeek >= 0 && result.date().dayOfWeek() != dayOfWeek+1)) + return QDateTime::currentDateTime(); // invalid date/time, or weekday doesn't correspond with date + if (!offset) { + result.setTimeSpec(Qt::UTC); + } + if (leapSecond) { + // Validate a leap second time. Leap seconds are inserted after 23:59:59 UTC. + // Convert the time to UTC and check that it is 00:00:00. + if ((hour*3600 + minute*60 + 60 - offset + 86400*5) % 86400) // (max abs(offset) is 100 hours) + return QDateTime::currentDateTime(); // the time isn't the last second of the day + } + return result; +} + +// public constructor +RssArticle::RssArticle(RssFeed* parent, QXmlStreamReader& xml) +{ + d = new RssArticleData; + d->parent = parent; + while(!xml.atEnd()) { + xml.readNext(); + + if(xml.isEndElement() && xml.name() == "item") + break; + + if(xml.isStartElement()) { + if(xml.name() == "title") { + d->title = xml.readElementText(); + } + else if(xml.name() == "enclosure") { + if(xml.attributes().value("type") == "application/x-bittorrent") { + d->torrentUrl = xml.attributes().value("url").toString(); + } + } + else if(xml.name() == "link") { + d->link = xml.readElementText(); + if(d->guid.isEmpty()) + d->guid = d->link; + } + else if(xml.name() == "description") { + d->description = xml.readElementText(); + } + else if(xml.name() == "pubDate") { + d->date = parseDate(xml.readElementText()); + } + else if(xml.name() == "author") { + d->author = xml.readElementText(); + } + else if(xml.name() == "guid") { + d->guid = xml.readElementText(); + } + } + } +} + +RssArticle::RssArticle(RssFeed* parent, const QString &guid) { + d = new RssArticleData; + d->parent = parent; + d->guid = guid; +} + +RssArticle::~RssArticle() {} + +RssArticle::RssArticle(const RssArticle& other): d(other.d) { +} + +RssArticle & RssArticle::operator =(const RssArticle &other) +{ + d = other.d; + return *this; +} + +bool RssArticle::hasAttachment() const { + return !d->torrentUrl.isEmpty(); +} + +QVariantHash RssArticle::toHash() const { + QVariantHash item; + item["title"] = d->title; + item["id"] = d->guid; + item["torrent_url"] = d->torrentUrl; + item["news_link"] = d->link; + item["description"] = d->description; + item["date"] = d->date; + item["author"] = d->author; + item["read"] = d->read; + return item; +} + +RssArticle hashToRssArticle(RssFeed* parent, const QVariantHash &h) { + const QString guid = h.value("id").toString(); + if(guid.isEmpty()) return RssArticle(); + RssArticle art(parent, guid); + art.d->title = h.value("title", "").toString(); + art.d->torrentUrl = h.value("torrent_url", "").toString(); + art.d->link = h.value("news_link", "").toString(); + art.d->description = h.value("description").toString(); + art.d->date = h.value("date").toDateTime(); + art.d->author = h.value("author").toString(); + art.d->read = h.value("read").toBool(); + + Q_ASSERT(art.isValid()); + return art; +} + +RssFeed* RssArticle::parent() const { + return d->parent; +} + +bool RssArticle::isValid() const { + return !d->guid.isEmpty(); +} + +QString RssArticle::author() const { + return d->author; +} + +QString RssArticle::torrentUrl() const{ + return d->torrentUrl; +} + +QString RssArticle::link() const { + return d->link; +} + +QString RssArticle::description() const{ + if(d->description.isNull()) + return ""; + return d->description; +} + +QDateTime RssArticle::date() const { + return d->date; +} + +bool RssArticle::isRead() const{ + return d->read; +} + +void RssArticle::markAsRead(){ + d->read = true; +} + +QString RssArticle::guid() const +{ + return d->guid; +} + +QString RssArticle::title() const +{ + return d->title; +} diff --git a/src/rss/rssarticle.h b/src/rss/rssarticle.h new file mode 100644 index 000000000..172bb96bc --- /dev/null +++ b/src/rss/rssarticle.h @@ -0,0 +1,78 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#ifndef RSSARTICLE_H +#define RSSARTICLE_H + +#include +#include +#include +#include + +class RssFeed; +class RssArticleData; + +// Item of a rss stream, single information +class RssArticle { + +public: + RssArticle(RssFeed* parent, QXmlStreamReader& xml); + RssArticle(RssFeed* parent = 0, const QString &guid = QString()); + RssArticle(const RssArticle& other); // Copy constructor + RssArticle& operator=(const RssArticle& other); + ~RssArticle(); + // Accessors + bool isValid() const; + bool hasAttachment() const; + QString guid() const; + RssFeed* parent() const; + QString title() const; + QString author() const; + QString torrentUrl() const; + QString link() const; + QString description() const; + QDateTime date() const; + bool isRead() const; + // Setters + void markAsRead(); + // Serialization + QVariantHash toHash() const; + friend RssArticle hashToRssArticle(RssFeed* parent, const QVariantHash &hash); + +private: + static QDateTime parseDate(const QString &string); + +private: + QExplicitlySharedDataPointer d; +}; + +RssArticle hashToRssArticle(RssFeed* parent, const QVariantHash &hash); + +#endif // RSSARTICLE_H diff --git a/src/rss/rssarticle_p.h b/src/rss/rssarticle_p.h new file mode 100644 index 000000000..20cfdc8e1 --- /dev/null +++ b/src/rss/rssarticle_p.h @@ -0,0 +1,61 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#ifndef RSSARTICLE_P_H +#define RSSARTICLE_P_H + +#include +#include +#include + +class RssFeed; + +class RssArticleData: public QSharedData { +public: + RssArticleData(): QSharedData(), read(false) {} + ~RssArticleData() {} + RssArticleData(const RssArticleData& other): + QSharedData(other), parent(other.parent), + guid(other.guid), title(other.title), torrentUrl(other.torrentUrl), + link(other.link), description(other.description), date(other.date), + author(other.author), read(other.read) {} + + RssFeed* parent; + QString guid; + QString title; + QString torrentUrl; + QString link; + QString description; + QDateTime date; + QString author; + bool read; +}; + +#endif // RSSARTICLE_P_H diff --git a/src/rss/rssdownloadrule.cpp b/src/rss/rssdownloadrule.cpp new file mode 100644 index 000000000..78843b7f9 --- /dev/null +++ b/src/rss/rssdownloadrule.cpp @@ -0,0 +1,148 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include + +#include "rssdownloadrule.h" +#include "preferences.h" +#include "qinisettings.h" +#include "rssfeed.h" +#include "rssarticle.h" + +RssDownloadRule::RssDownloadRule(): m_enabled(false), m_useRegex(false) +{ +} + +bool RssDownloadRule::matches(const QString &article_title) const +{ + foreach(const QString& token, m_mustContain) { + if(token.isEmpty() || token == "") + continue; + QRegExp reg(token, Qt::CaseInsensitive, m_useRegex ? QRegExp::RegExp : QRegExp::Wildcard); + //reg.setMinimal(false); + if(reg.indexIn(article_title) < 0) return false; + } + qDebug("Checking not matching tokens"); + // Checking not matching + foreach(const QString& token, m_mustNotContain) { + if(token.isEmpty()) continue; + QRegExp reg(token, Qt::CaseInsensitive, m_useRegex ? QRegExp::RegExp : QRegExp::Wildcard); + if(reg.indexIn(article_title) > -1) return false; + } + return true; +} + +void RssDownloadRule::setMustContain(const QString &tokens) +{ + if(m_useRegex) + m_mustContain = QStringList() << tokens; + else + m_mustContain = tokens.split(" "); +} + +void RssDownloadRule::setMustNotContain(const QString &tokens) +{ + if(m_useRegex) + m_mustNotContain = QStringList() << tokens; + else + m_mustNotContain = tokens.split(QRegExp("[\\s|]")); +} + +RssDownloadRule RssDownloadRule::fromOldFormat(const QVariantHash &rule_hash, const QString &feed_url, const QString &rule_name) +{ + qDebug() << Q_FUNC_INFO << feed_url << rule_name; + RssDownloadRule rule; + rule.setName(rule_name); + rule.setMustContain(rule_hash.value("matches", "").toString()); + rule.setMustNotContain(rule_hash.value("not", "").toString()); + if(!feed_url.isEmpty()) + rule.setRssFeeds(QStringList() << feed_url); + rule.setSavePath(rule_hash.value("save_path", "").toString()); + // Is enabled? + QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss"); + const QHash feeds_w_downloader = qBTRSS.value("downloader_on").toHash(); + rule.setEnabled(feeds_w_downloader.value(feed_url, true).toBool()); + // label was unsupported < 2.5.0 + return rule; +} + +RssDownloadRule RssDownloadRule::fromNewFormat(const QVariantHash &rule_hash) +{ + RssDownloadRule rule; + rule.setName(rule_hash.value("name").toString()); + rule.setMustContain(rule_hash.value("must_contain").toString()); + rule.setMustNotContain(rule_hash.value("must_not_contain").toString()); + rule.setRssFeeds(rule_hash.value("affected_feeds").toStringList()); + rule.setEnabled(rule_hash.value("enabled", false).toBool()); + rule.setSavePath(rule_hash.value("save_path").toString()); + rule.setLabel(rule_hash.value("label_assigned").toString()); + rule.setUseRegex(rule_hash.value("use_regex", false).toBool()); + return rule; +} + +QVariantHash RssDownloadRule::toVariantHash() const +{ + QVariantHash hash; + hash["name"] = m_name; + hash["must_contain"] = m_mustContain.join(" "); + hash["must_not_contain"] = m_mustNotContain.join(" "); + hash["save_path"] = m_savePath; + hash["affected_feeds"] = m_rssFeeds; + hash["enabled"] = m_enabled; + hash["label_assigned"] = m_label; + hash["use_regex"] = m_useRegex; + return hash; +} + +bool RssDownloadRule::operator==(const RssDownloadRule &other) { + return m_name == other.name(); +} + +void RssDownloadRule::setSavePath(const QString &save_path) +{ + if(!save_path.isEmpty() && QDir(save_path) != QDir(Preferences().getSavePath())) + m_savePath = save_path; + else + m_savePath = QString(); +} + +QStringList RssDownloadRule::findMatchingArticles(const RssFeed *feed) const +{ + QStringList ret; + const QHash& feed_articles = feed->articleListNoCopy(); + QHash::const_iterator artIt; + for(artIt = feed_articles.begin(); artIt != feed_articles.end(); artIt++) { + const QString title = artIt.value().title(); + if(matches(title)) + ret << title; + } + return ret; +} diff --git a/src/rss/rssdownloadrule.h b/src/rss/rssdownloadrule.h new file mode 100644 index 000000000..b90f4dfaa --- /dev/null +++ b/src/rss/rssdownloadrule.h @@ -0,0 +1,80 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef RSSDOWNLOADRULE_H +#define RSSDOWNLOADRULE_H + +#include +#include + +class RssFeed; + +class RssDownloadRule +{ + +public: + explicit RssDownloadRule(); + static RssDownloadRule fromOldFormat(const QVariantHash& rule_hash, const QString &feed_url, const QString &rule_name); // Before v2.5.0 + static RssDownloadRule fromNewFormat(const QVariantHash &rule_hash); + QVariantHash toVariantHash() const; + bool matches(const QString &article_title) const; + void setMustContain(const QString &tokens); + void setMustNotContain(const QString &tokens); + inline QStringList rssFeeds() const { return m_rssFeeds; } + inline void setRssFeeds(const QStringList& rss_feeds) { m_rssFeeds = rss_feeds; } + inline QString name() const { return m_name; } + inline void setName(const QString &name) { m_name = name; } + inline QString savePath() const { return m_savePath; } + void setSavePath(const QString &save_path); + inline QString label() const { return m_label; } + inline void setLabel(const QString &_label) { m_label = _label; } + inline bool isEnabled() const { return m_enabled; } + inline void setEnabled(bool enable) { m_enabled = enable; } + inline bool isValid() const { return !m_name.isEmpty(); } + inline QString mustContain() const { return m_mustContain.join(" "); } + inline QString mustNotContain() const { return m_mustNotContain.join(" "); } + inline bool useRegex() const { return m_useRegex; } + inline void setUseRegex(bool enabled) { m_useRegex = enabled; } + QStringList findMatchingArticles(const RssFeed* feed) const; + // Operators + bool operator==(const RssDownloadRule &other); + +private: + QString m_name; + QStringList m_mustContain; + QStringList m_mustNotContain; + QString m_savePath; + QString m_label; + bool m_enabled; + QStringList m_rssFeeds; + bool m_useRegex; +}; + +#endif // RSSDOWNLOADRULE_H diff --git a/src/rss/rssdownloadrulelist.cpp b/src/rss/rssdownloadrulelist.cpp new file mode 100644 index 000000000..542f09acd --- /dev/null +++ b/src/rss/rssdownloadrulelist.cpp @@ -0,0 +1,225 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include + +#include "rssdownloadrulelist.h" +#include "rsssettings.h" +#include "qinisettings.h" + +RssDownloadRuleList* RssDownloadRuleList::m_instance = 0; + +RssDownloadRuleList::RssDownloadRuleList(){ + loadRulesFromStorage(); +} + +RssDownloadRuleList* RssDownloadRuleList::instance() +{ + if(!m_instance) + m_instance = new RssDownloadRuleList; + return m_instance; +} + +void RssDownloadRuleList::drop() +{ + if(m_instance) + delete m_instance; +} + +RssDownloadRule RssDownloadRuleList::findMatchingRule(const QString &feed_url, const QString &article_title) const +{ + Q_ASSERT(RssSettings().isRssDownloadingEnabled()); + const QStringList rule_names = m_feedRules.value(feed_url); + foreach(const QString &rule_name, rule_names) { + const RssDownloadRule &rule = m_rules[rule_name]; + if(rule.isEnabled() && rule.matches(article_title)) return rule; + } + return RssDownloadRule(); +} + +void RssDownloadRuleList::saveRulesToStorage() +{ + QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss"); + qBTRSS.setValue("download_rules", toVariantHash()); +} + +void RssDownloadRuleList::loadRulesFromStorage() +{ + QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss"); + if(qBTRSS.contains("feed_filters")) { + importFeedsInOldFormat(qBTRSS.value("feed_filters").toHash()); + // Remove outdated rules + qBTRSS.remove("feed_filters"); + // Save to new format + saveRulesToStorage(); + return; + } + // Load from new format + loadRulesFromVariantHash(qBTRSS.value("download_rules").toHash()); +} + +void RssDownloadRuleList::importFeedsInOldFormat(const QHash &rules) +{ + foreach(const QString &feed_url, rules.keys()) { + importFeedRulesInOldFormat(feed_url, rules.value(feed_url).toHash()); + } +} + +void RssDownloadRuleList::importFeedRulesInOldFormat(const QString &feed_url, const QHash &rules) +{ + foreach(const QString &rule_name, rules.keys()) { + RssDownloadRule rule = RssDownloadRule::fromOldFormat(rules.value(rule_name).toHash(), feed_url, rule_name); + if(!rule.isValid()) continue; + // Check for rule name clash + while(m_rules.contains(rule.name())) { + rule.setName(rule.name()+"_"); + } + // Add the rule to the list + saveRule(rule); + } +} + +QVariantHash RssDownloadRuleList::toVariantHash() const +{ + QVariantHash ret; + foreach(const RssDownloadRule &rule, m_rules.values()) { + ret.insert(rule.name(), rule.toVariantHash()); + } + return ret; +} + +void RssDownloadRuleList::loadRulesFromVariantHash(const QVariantHash &h) +{ + foreach(const QVariant& v, h.values()) { + RssDownloadRule rule = RssDownloadRule::fromNewFormat(v.toHash()); + if(!rule.name().isEmpty()) { + saveRule(rule); + } + } +} + +void RssDownloadRuleList::saveRule(const RssDownloadRule &rule) +{ + qDebug() << Q_FUNC_INFO << rule.name(); + Q_ASSERT(rule.isValid()); + if(m_rules.contains(rule.name())) { + qDebug("This is an update, removing old rule first"); + removeRule(rule.name()); + } + m_rules.insert(rule.name(), rule); + // Update feedRules hashtable + foreach(const QString &feed_url, rule.rssFeeds()) { + m_feedRules[feed_url].append(rule.name()); + } + // Save rules + saveRulesToStorage(); + qDebug() << Q_FUNC_INFO << "EXIT"; +} + +void RssDownloadRuleList::removeRule(const QString &name) +{ + qDebug() << Q_FUNC_INFO << name; + if(!m_rules.contains(name)) return; + const RssDownloadRule rule = m_rules.take(name); + // Update feedRules hashtable + foreach(const QString &feed_url, rule.rssFeeds()) { + m_feedRules[feed_url].removeOne(rule.name()); + } + // Save rules + saveRulesToStorage(); +} + +void RssDownloadRuleList::renameRule(const QString &old_name, const QString &new_name) +{ + if(!m_rules.contains(old_name)) return; + RssDownloadRule rule = m_rules.take(old_name); + rule.setName(new_name); + m_rules.insert(new_name, rule); + // Update feedRules hashtable + foreach(const QString &feed_url, rule.rssFeeds()) { + m_feedRules[feed_url].replace(m_feedRules[feed_url].indexOf(old_name), new_name); + } + // Save rules + saveRulesToStorage(); +} + +const RssDownloadRule RssDownloadRuleList::getRule(const QString &name) const +{ + return m_rules.value(name); +} + +bool RssDownloadRuleList::serialize(const QString& path) +{ + QFile f(path); + if(f.open(QIODevice::WriteOnly)) { + QDataStream out(&f); + out.setVersion(QDataStream::Qt_4_5); + out << toVariantHash(); + f.close(); + return true; + } else { + return false; + } +} + +bool RssDownloadRuleList::unserialize(const QString &path) +{ + QFile f(path); + if(f.open(QIODevice::ReadOnly)) { + QDataStream in(&f); + if(path.endsWith(".filters", Qt::CaseInsensitive)) { + // Old format (< 2.5.0) + qDebug("Old serialization format detected, processing..."); + in.setVersion(QDataStream::Qt_4_3); + QVariantHash tmp; + in >> tmp; + f.close(); + if(tmp.isEmpty()) return false; + qDebug("Processing was successful!"); + // Unfortunately the feed_url is lost + importFeedRulesInOldFormat("", tmp); + } else { + qDebug("New serialization format detected, processing..."); + in.setVersion(QDataStream::Qt_4_5); + QVariantHash tmp; + in >> tmp; + f.close(); + if(tmp.isEmpty()) return false; + qDebug("Processing was successful!"); + loadRulesFromVariantHash(tmp); + } + return true; + } + qDebug("Error: could not open file at %s", qPrintable(path)); + return false; +} + diff --git a/src/rss/rssdownloadrulelist.h b/src/rss/rssdownloadrulelist.h new file mode 100644 index 000000000..1be5f5265 --- /dev/null +++ b/src/rss/rssdownloadrulelist.h @@ -0,0 +1,77 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef RSSDOWNLOADRULELIST_H +#define RSSDOWNLOADRULELIST_H + +#include +#include +#include + +#include "rssdownloadrule.h" + +// This class is not thread-safe (not required) +class RssDownloadRuleList +{ + Q_DISABLE_COPY(RssDownloadRuleList) + +private: + explicit RssDownloadRuleList(); + static RssDownloadRuleList* m_instance; + +public: + static RssDownloadRuleList* instance(); + static void drop(); + RssDownloadRule findMatchingRule(const QString &feed_url, const QString &article_title) const; + // Operators + void saveRule(const RssDownloadRule &rule); + void removeRule(const QString &name); + void renameRule(const QString &old_name, const QString &new_name); + const RssDownloadRule getRule(const QString &name) const; + inline QStringList ruleNames() const { return m_rules.keys(); } + inline bool isEmpty() const { return m_rules.isEmpty(); } + bool serialize(const QString& path); + bool unserialize(const QString& path); + +private: + void loadRulesFromStorage(); + void importFeedsInOldFormat(const QHash &feedrules); // Before v2.5.0 + void importFeedRulesInOldFormat(const QString &feed_url, const QHash &rules); // Before v2.5.0 + void loadRulesFromVariantHash(const QVariantHash& l); + QVariantHash toVariantHash() const; + void saveRulesToStorage(); + +private: + QHash m_rules; + QHash m_feedRules; + +}; + +#endif // RSSDOWNLOADFILTERLIST_H diff --git a/src/rss/rssfeed.cpp b/src/rss/rssfeed.cpp new file mode 100644 index 000000000..05b5cd35a --- /dev/null +++ b/src/rss/rssfeed.cpp @@ -0,0 +1,356 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#include +#include "rssfeed.h" +#include "rssmanager.h" +#include "qbtsession.h" +#include "rssfolder.h" +#include "rsssettings.h" +#include "rssarticle.h" +#include "misc.h" +#include "rssdownloadrulelist.h" +#include "downloadthread.h" + +RssFeed::RssFeed(RssFolder* parent, const QString &url): m_parent(parent), m_icon(":/Icons/oxygen/application-rss+xml.png"), + m_refreshed(false), m_downloadFailure(false), m_loading(false) { + qDebug() << Q_FUNC_INFO << url; + m_url = QUrl::fromEncoded(url.toUtf8()).toString(); + QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss"); + QHash all_old_items = qBTRSS.value("old_items", QHash()).toHash(); + const QVariantList old_items = all_old_items.value(m_url, QVariantList()).toList(); + qDebug("Loading %d old items for feed %s", old_items.size(), displayName().toLocal8Bit().data()); + foreach(const QVariant &var_it, old_items) { + QHash item = var_it.toHash(); + const RssArticle rss_item = hashToRssArticle(this, item); + if(rss_item.isValid()) { + m_articles.insert(rss_item.guid(), rss_item); + } + } + // Listen for new RSS downloads + connect(RssManager::instance()->rssDownloader(), SIGNAL(downloadFinished(QString,QString)), SLOT(handleFinishedDownload(QString,QString))); + connect(RssManager::instance()->rssDownloader(), SIGNAL(downloadFailure(QString,QString)), SLOT(handleDownloadFailure(QString,QString))); + // Download the RSS Feed icon + m_iconUrl = iconUrl(); + RssManager::instance()->rssDownloader()->downloadUrl(m_iconUrl); +} + +RssFeed::~RssFeed(){ + // Saving current articles to hard disk + if(m_refreshed) { + QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss"); + QVariantList old_items; + foreach(const RssArticle &item, m_articles.values()) { + old_items << item.toHash(); + } + qDebug("Saving %d old items for feed %s", old_items.size(), displayName().toLocal8Bit().data()); + QHash all_old_items = qBTRSS.value("old_items", QHash()).toHash(); + all_old_items[m_url] = old_items; + qBTRSS.setValue("old_items", all_old_items); + } + if(!m_icon.startsWith(":/") && QFile::exists(m_icon)) + misc::safeRemove(m_icon); +} + +IRssFile::FileType RssFeed::type() const { + return IRssFile::FEED; +} + +void RssFeed::refresh() { + if(m_loading) return; + m_loading = true; + // Download the RSS again + RssManager::instance()->rssDownloader()->downloadUrl(m_url); +} + +void RssFeed::removeAllSettings() { + QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss"); + QHash feeds_w_downloader = qBTRSS.value("downloader_on", QHash()).toHash(); + if(feeds_w_downloader.contains(m_url)) { + feeds_w_downloader.remove(m_url); + qBTRSS.setValue("downloader_on", feeds_w_downloader); + } + QHash all_feeds_filters = qBTRSS.value("feed_filters", QHash()).toHash(); + if(all_feeds_filters.contains(m_url)) { + all_feeds_filters.remove(m_url); + qBTRSS.setValue("feed_filters", all_feeds_filters); + } +} + +bool RssFeed::itemAlreadyExists(const QString &hash) const { + return m_articles.contains(hash); +} + +void RssFeed::setLoading(bool val) { + m_loading = val; +} + +bool RssFeed::isLoading() const { + return m_loading; +} + +QString RssFeed::title() const{ + return m_title; +} + +void RssFeed::rename(const QString &new_name){ + qDebug() << "Renaming stream to" << new_name; + m_alias = new_name; +} + +// Return the alias if the stream has one, the url if it has no alias +QString RssFeed::displayName() const { + if(!m_alias.isEmpty()) { + //qDebug("getName() returned alias: %s", (const char*)alias.toLocal8Bit()); + return m_alias; + } + if(!m_title.isEmpty()) { + //qDebug("getName() returned title: %s", (const char*)title.toLocal8Bit()); + return m_title; + } + //qDebug("getName() returned url: %s", (const char*)url.toLocal8Bit()); + return m_url; +} + +QString RssFeed::url() const{ + return m_url; +} + +QString RssFeed::icon() const{ + if(m_downloadFailure) + return ":/Icons/oxygen/unavailable.png"; + return m_icon; +} + +bool RssFeed::hasCustomIcon() const{ + return !m_icon.startsWith(":/"); +} + +void RssFeed::setIconPath(const QString &path) { + if(path.isEmpty() || !QFile::exists(path)) return; + m_icon = path; +} + +RssArticle& RssFeed::getItem(const QString &id) { + return m_articles[id]; +} + +uint RssFeed::count() const{ + return m_articles.size(); +} + +void RssFeed::markAsRead() { + QHash::iterator it; + for(it = m_articles.begin(); it != m_articles.end(); it++) { + it.value().markAsRead(); + } + RssManager::instance()->forwardFeedInfosChanged(m_url, displayName(), 0); +} + +uint RssFeed::unreadCount() const{ + uint nbUnread=0; + foreach(const RssArticle &item, m_articles.values()) { + if(!item.isRead()) + ++nbUnread; + } + return nbUnread; +} + +const QList RssFeed::articleList() const{ + return m_articles.values(); +} + +const QList RssFeed::unreadArticleList() const { + QList unread_news; + foreach(const RssArticle &item, m_articles.values()) { + if(!item.isRead()) + unread_news << item; + } + return unread_news; +} + +// download the icon from the adress +QString RssFeed::iconUrl() const { + const QUrl siteUrl(m_url); + // XXX: This works for most sites but it is not perfect + return QString("http://")+siteUrl.host()+QString("/favicon.ico"); +} + +// read and create items from a rss document +bool RssFeed::parseRSS(QIODevice* device) { + qDebug("Parsing RSS file..."); + QXmlStreamReader xml(device); + // is it a rss file ? + if (xml.atEnd()) { + qDebug("ERROR: Could not parse RSS file"); + return false; + } + while (!xml.atEnd()) { + xml.readNext(); + if(xml.isStartElement()) { + if(xml.name() != "rss") { + qDebug("ERROR: this is not a rss file, root tag is <%s>", qPrintable(xml.name().toString())); + return false; + } else { + break; + } + } + } + // Read channels + while(!xml.atEnd()) { + xml.readNext(); + + if(!xml.isStartElement()) + continue; + + if(xml.name() != "channel") + continue; + + // Parse channel content + while(!xml.atEnd()) { + xml.readNext(); + + if(xml.isEndElement() && xml.name() == "channel") + break; // End of this channel, parse the next one + + if(!xml.isStartElement()) + continue; + + if(xml.name() == "title") { + m_title = xml.readElementText(); + if(m_alias == url()) + rename(m_title); + } + else if(xml.name() == "image") { + QString icon_path = xml.attributes().value("url").toString(); + if(!icon_path.isEmpty()) { + m_iconUrl = icon_path; + RssManager::instance()->rssDownloader()->downloadUrl(m_iconUrl); + } + } + else if(xml.name() == "item") { + RssArticle item(this, xml); + if(item.isValid() && !itemAlreadyExists(item.guid())) { + m_articles.insert(item.guid(), item); + } + } + } + } + + // RSS Feed Downloader + if(RssSettings().isRssDownloadingEnabled()) + downloadMatchingArticleTorrents(); + + // Make sure we limit the number of articles + resizeList(); + + return true; +} + +void RssFeed::downloadMatchingArticleTorrents() { + Q_ASSERT(RssSettings().isRssDownloadingEnabled()); + QHash::iterator it; + for(it = m_articles.begin(); it != m_articles.end(); it++) { + RssArticle &item = it.value(); + if(item.isRead()) continue; + QString torrent_url; + if(item.hasAttachment()) + torrent_url = item.torrentUrl(); + else + torrent_url = item.link(); + // Check if the item should be automatically downloaded + const RssDownloadRule matching_rule = RssDownloadRuleList::instance()->findMatchingRule(m_url, item.title()); + if(matching_rule.isValid()) { + // Download the torrent + QBtSession::instance()->addConsoleMessage(tr("Automatically downloading %1 torrent from %2 RSS feed...").arg(item.title()).arg(displayName())); + QBtSession::instance()->downloadUrlAndSkipDialog(torrent_url, matching_rule.savePath(), matching_rule.label()); + // Item was downloaded, consider it as Read + item.markAsRead(); + } + } +} + +void RssFeed::resizeList() { + const uint max_articles = RssSettings().getRSSMaxArticlesPerFeed(); + const uint nb_articles = m_articles.size(); + if(nb_articles > max_articles) { + const QList listItem = RssManager::sortNewsList(m_articles.values()); + const int excess = nb_articles - max_articles; + for(uint i=nb_articles-excess; iforwardFeedInfosChanged(m_url, displayName(), unreadCount()); // XXX: Ugly + } + } + else if(url == m_iconUrl) { + m_icon = file_path; + qDebug() << "icon path:" << m_icon; + RssManager::instance()->forwardFeedIconChanged(m_url, m_icon); // XXX: Ugly + } +} + +void RssFeed::handleDownloadFailure(const QString &url, const QString& error) { + Q_UNUSED(error); + if(url != m_url) return; + m_downloadFailure = true; + m_loading = false; + RssManager::instance()->forwardFeedInfosChanged(m_url, displayName(), unreadCount()); // XXX: Ugly +} diff --git a/src/rss/rssfeed.h b/src/rss/rssfeed.h new file mode 100644 index 000000000..00a03af23 --- /dev/null +++ b/src/rss/rssfeed.h @@ -0,0 +1,97 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#ifndef RSSFEED_H +#define RSSFEED_H + +#include + +#include "rssfile.h" + +class RssManager; + +class RssFeed: public QObject, public IRssFile { + Q_OBJECT + +public: + RssFeed(RssFolder* m_parent, const QString &url); + ~RssFeed(); + inline RssFolder* parent() const { return m_parent; } + void setParent(RssFolder* parent) { m_parent = parent; } + FileType type() const; + void refresh(); + QString id() const { return m_url; } + void removeAllSettings(); + bool itemAlreadyExists(const QString &hash) const; + void setLoading(bool val); + bool isLoading() const; + QString title() const; + void rename(const QString &alias); + QString displayName() const; + QString url() const; + QString icon() const; + bool hasCustomIcon() const; + void setIconPath(const QString &pathHierarchy); + RssArticle& getItem(const QString &name); + uint count() const; + void markAsRead(); + uint unreadCount() const; + const QList articleList() const; + const QHash& articleListNoCopy() const { return m_articles; } + const QList unreadArticleList() const; + +private slots: + void handleFinishedDownload(const QString& url, const QString &file_path); + void handleDownloadFailure(const QString &url, const QString& error); + +private: + bool parseRSS(QIODevice* device); + void resizeList(); + bool parseXmlFile(const QString &file_path); + void downloadMatchingArticleTorrents(); + QString iconUrl() const; + +private: + QHash m_articles; + RssFolder *m_parent; + QString m_title; + QString m_url; + QString m_alias; + QString m_icon; + QString m_iconUrl; + bool m_read; + bool m_refreshed; + bool m_downloadFailure; + bool m_loading; + +}; + + +#endif // RSSFEED_H diff --git a/src/rss/rssfile.cpp b/src/rss/rssfile.cpp new file mode 100644 index 000000000..e773263b9 --- /dev/null +++ b/src/rss/rssfile.cpp @@ -0,0 +1,40 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#include "rssfile.h" +#include "rssfolder.h" + +QStringList IRssFile::pathHierarchy() const { + QStringList path; + if(parent()) + path << parent()->pathHierarchy(); + path << id(); + return path; +} diff --git a/src/rss/rssfile.h b/src/rss/rssfile.h new file mode 100644 index 000000000..e9da8b047 --- /dev/null +++ b/src/rss/rssfile.h @@ -0,0 +1,62 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#ifndef RSSFILE_H +#define RSSFILE_H + +#include +#include + +class RssArticle; +class RssFolder; + +class IRssFile { + +public: + enum FileType {FEED, FOLDER}; + + virtual ~IRssFile() {} + + virtual uint unreadCount() const = 0; + virtual FileType type() const = 0; + virtual QString displayName() const = 0; + virtual QString id() const = 0; + virtual void rename(const QString &new_name) = 0; + virtual void markAsRead() = 0; + virtual RssFolder* parent() const = 0; + virtual void setParent(RssFolder* parent) = 0; + virtual void refresh() = 0; + virtual void removeAllSettings() = 0; + virtual const QList articleList() const = 0; + virtual const QList unreadArticleList() const = 0; + QStringList pathHierarchy() const; +}; + +#endif // RSSFILE_H diff --git a/src/rss/rssfolder.cpp b/src/rss/rssfolder.cpp new file mode 100644 index 000000000..e45c6ab2d --- /dev/null +++ b/src/rss/rssfolder.cpp @@ -0,0 +1,217 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#include + +#include "rssfolder.h" +#include "rssarticle.h" +#include "qbtsession.h" +#include "rssmanager.h" +#include "rssfeed.h" + +RssFolder::RssFolder(RssFolder *parent, const QString &name): m_parent(parent), m_name(name) { +} + +RssFolder::~RssFolder() { + qDebug("Deleting a RSS folder, removing elements"); + qDeleteAll(m_children.values()); +} + +unsigned int RssFolder::unreadCount() const { + unsigned int nb_unread = 0; + foreach(const IRssFile *file, m_children.values()) { + nb_unread += file->unreadCount(); + } + return nb_unread; +} + +IRssFile::FileType RssFolder::type() const { + return IRssFile::FOLDER; +} + +void RssFolder::removeChild(const QString &childId) { + if(m_children.contains(childId)) { + IRssFile* child = m_children.take(childId); + child->removeAllSettings(); + delete child; + } +} + +RssFolder* RssFolder::addFolder(const QString &name) { + RssFolder *subfolder; + if(!m_children.contains(name)) { + subfolder = new RssFolder(this, name); + m_children[name] = subfolder; + } else { + subfolder = dynamic_cast(m_children.value(name)); + } + return subfolder; +} + +RssFeed* RssFolder::addStream(const QString &url) { + RssFeed* stream = new RssFeed(this, url); + Q_ASSERT(!m_children.contains(stream->url())); + m_children[stream->url()] = stream; + stream->refresh(); + return stream; +} + +// Refresh All Children +void RssFolder::refresh() { + foreach(IRssFile *child, m_children.values()) { + child->refresh(); + } +} + +const QList RssFolder::articleList() const { + QList news; + foreach(const IRssFile *child, m_children.values()) { + news << child->articleList(); + } + return news; +} + +const QList RssFolder::unreadArticleList() const { + QList unread_news; + foreach(const IRssFile *child, m_children.values()) { + unread_news << child->unreadArticleList(); + } + return unread_news; +} + +QList RssFolder::getContent() const { + return m_children.values(); +} + +unsigned int RssFolder::getNbFeeds() const { + unsigned int nbFeeds = 0; + foreach(IRssFile* item, m_children.values()) { + if(item->type() == IRssFile::FOLDER) + nbFeeds += ((RssFolder*)item)->getNbFeeds(); + else + nbFeeds += 1; + } + return nbFeeds; +} + +QString RssFolder::displayName() const { + return m_name; +} + +void RssFolder::rename(const QString &new_name) { + if(m_name == new_name) return; + Q_ASSERT(!m_parent->hasChild(new_name)); + if(!m_parent->hasChild(new_name)) { + // Update parent + m_parent->renameChildFolder(m_name, new_name); + // Actually rename + m_name = new_name; + } +} + +void RssFolder::markAsRead() { + foreach(IRssFile *item, m_children.values()) { + item->markAsRead(); + } +} + +QList RssFolder::getAllFeeds() const { + QList streams; + foreach(IRssFile *item, m_children.values()) { + if(item->type() == IRssFile::FEED) { + streams << static_cast(item); + } else { + streams << static_cast(item)->getAllFeeds(); + } + } + return streams; +} + +QHash RssFolder::getAllFeedsAsHash() const { + QHash ret; + foreach(IRssFile *item, m_children.values()) { + if(item->type() == IRssFile::FEED) { + RssFeed* feed = dynamic_cast(item); + Q_ASSERT(feed); + qDebug() << Q_FUNC_INFO << feed->url(); + ret[feed->url()] = feed; + } else { + ret.unite(static_cast(item)->getAllFeedsAsHash()); + } + } + return ret; +} + +void RssFolder::addFile(IRssFile * item) { + if(item->type() == IRssFile::FEED) { + RssFeed* feedItem = dynamic_cast(item); + Q_ASSERT(!m_children.contains(feedItem->url())); + m_children[feedItem->url()] = item; + qDebug("Added feed %s to folder ./%s", qPrintable(feedItem->url()), qPrintable(m_name)); + } else { + RssFolder* folderItem = dynamic_cast(item); + Q_ASSERT(!m_children.contains(folderItem->displayName())); + m_children[folderItem->displayName()] = item; + qDebug("Added folder %s to folder ./%s", qPrintable(folderItem->displayName()), qPrintable(m_name)); + } + // Update parent + item->setParent(this); +} + +void RssFolder::removeAllItems() { + qDeleteAll(m_children.values()); + m_children.clear(); +} + +void RssFolder::removeAllSettings() { + foreach(IRssFile* child, m_children.values()) { + child->removeAllSettings(); + } +} + +QString RssFolder::id() const { + return m_name; +} + +bool RssFolder::hasChild(const QString &childId) { + return m_children.contains(childId); +} + +void RssFolder::renameChildFolder(const QString &old_name, const QString &new_name) +{ + Q_ASSERT(m_children.contains(old_name)); + IRssFile *folder = m_children.take(old_name); + m_children[new_name] = folder; +} + +IRssFile * RssFolder::takeChild(const QString &childId) +{ + return m_children.take(childId); +} diff --git a/src/rss/rssfolder.h b/src/rss/rssfolder.h new file mode 100644 index 000000000..9aebafc3d --- /dev/null +++ b/src/rss/rssfolder.h @@ -0,0 +1,80 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#ifndef RSSFOLDER_H +#define RSSFOLDER_H + +#include + +#include "rssfile.h" + +class RssArticle; +class RssFeed; + +class RssFolder: public QObject, public IRssFile { + Q_OBJECT + +public: + RssFolder(RssFolder *parent = 0, const QString &name = QString()); + virtual ~RssFolder(); + inline RssFolder* parent() const { return m_parent; } + void setParent(RssFolder* parent) { m_parent = parent; } + unsigned int unreadCount() const; + FileType type() const; + RssFeed* addStream(const QString &url); + RssFolder* addFolder(const QString &name); + unsigned int getNbFeeds() const; + QList getContent() const; + QList getAllFeeds() const; + QHash getAllFeedsAsHash() const; + QString displayName() const; + QString id() const; + bool hasChild(const QString &childId); + const QList articleList() const; + const QList unreadArticleList() const; + void removeAllSettings(); + void removeAllItems(); + void renameChildFolder(const QString &old_name, const QString &new_name); + IRssFile *takeChild(const QString &childId); + +public slots: + void refresh(); + void addFile(IRssFile * item); + void removeChild(const QString &childId); + void rename(const QString &new_name); + void markAsRead(); + +private: + RssFolder *m_parent; + QString m_name; + QHash m_children; +}; + +#endif // RSSFOLDER_H diff --git a/src/rss/rssmanager.cpp b/src/rss/rssmanager.cpp new file mode 100644 index 000000000..7095afc58 --- /dev/null +++ b/src/rss/rssmanager.cpp @@ -0,0 +1,165 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#include +#include "rssmanager.h" +#include "rsssettings.h" +#include "qbtsession.h" +#include "rssfeed.h" +#include "rssarticle.h" +#include "rssdownloadrulelist.h" +#include "downloadthread.h" + +RssManager* RssManager::m_instance = 0; + +RssManager::RssManager(): RssFolder() { + m_rssDownloader = new DownloadThread(this); + connect(&m_refreshTimer, SIGNAL(timeout()), this, SLOT(refresh())); + m_refreshInterval = RssSettings().getRSSRefreshInterval(); + m_refreshTimer.start(m_refreshInterval*60000); +} + +RssManager::~RssManager(){ + qDebug("Deleting RSSManager"); + delete m_rssDownloader; + RssDownloadRuleList::drop(); + saveStreamList(); + qDebug("RSSManager deleted"); +} + +void RssManager::updateRefreshInterval(uint val){ + if(m_refreshInterval != val) { + m_refreshInterval = val; + m_refreshTimer.start(m_refreshInterval*60000); + qDebug("New RSS refresh interval is now every %dmin", m_refreshInterval); + } +} + +void RssManager::loadStreamList() { + RssSettings settings; + const QStringList streamsUrl = settings.getRssFeedsUrls(); + const QStringList aliases = settings.getRssFeedsAliases(); + if(streamsUrl.size() != aliases.size()){ + std::cerr << "Corrupted Rss list, not loading it\n"; + return; + } + uint i = 0; + qDebug() << Q_FUNC_INFO << streamsUrl; + foreach(QString s, streamsUrl){ + QStringList path = s.split("\\", QString::SkipEmptyParts); + if(path.empty()) continue; + const QString feed_url = path.takeLast(); + qDebug() << "Feed URL:" << feed_url; + // Create feed path (if it does not exists) + RssFolder * feed_parent = this; + foreach(const QString &folder_name, path) { + qDebug() << "Adding parent folder:" << folder_name; + feed_parent = feed_parent->addFolder(folder_name); + } + // Create feed + qDebug() << "Adding feed to parent folder"; + RssFeed *stream = feed_parent->addStream(feed_url); + const QString alias = aliases.at(i); + if(!alias.isEmpty()) { + stream->rename(alias); + } + ++i; + } + qDebug("NB RSS streams loaded: %d", streamsUrl.size()); +} + +void RssManager::forwardFeedInfosChanged(const QString &url, const QString &display_name, uint nbUnread) { + emit feedInfosChanged(url, display_name, nbUnread); +} + +void RssManager::forwardFeedIconChanged(const QString &url, const QString &icon_path) { + emit feedIconChanged(url, icon_path); +} + +void RssManager::moveFile(IRssFile* file, RssFolder* dest_folder) { + RssFolder* src_folder = file->parent(); + if(dest_folder != src_folder) { + // Remove reference in old folder + src_folder->takeChild(file->id()); + // add to new Folder + dest_folder->addFile(file); + } else { + qDebug("Nothing to move, same destination folder"); + } +} + +void RssManager::saveStreamList() const { + QStringList streamsUrl; + QStringList aliases; + const QList streams = getAllFeeds(); + foreach(const RssFeed *stream, streams) { + QString stream_path = stream->pathHierarchy().join("\\"); + if(stream_path.isNull()) { + stream_path = ""; + } + qDebug("Saving stream path: %s", qPrintable(stream_path)); + streamsUrl << stream_path; + aliases << stream->displayName(); + } + RssSettings settings; + settings.setRssFeedsUrls(streamsUrl); + settings.setRssFeedsAliases(aliases); +} + +void RssManager::insertSortElem(QList &list, const RssArticle &item) { + int i = 0; + while(i < list.size() && item.date() < list.at(i).date()) { + ++i; + } + list.insert(i, item); +} + +QList RssManager::sortNewsList(const QList& news_list) { + QList new_list; + foreach(const RssArticle &item, news_list) { + insertSortElem(new_list, item); + } + return new_list; +} + +RssManager * RssManager::instance() +{ + if(!m_instance) + m_instance = new RssManager; + return m_instance; +} + +void RssManager::drop() +{ + if(m_instance) { + delete m_instance; + m_instance = 0; + } +} diff --git a/src/rss/rssmanager.h b/src/rss/rssmanager.h new file mode 100644 index 000000000..e4fd770ce --- /dev/null +++ b/src/rss/rssmanager.h @@ -0,0 +1,73 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez, Arnaud Demaiziere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact: chris@qbittorrent.org, arnaud@qbittorrent.org + */ + +#ifndef RSSMANAGER_H +#define RSSMANAGER_H + +#include + +#include "rssfolder.h" + +class DownloadThread; + +class RssManager: public RssFolder { + Q_OBJECT +private: + explicit RssManager(); + static RssManager* m_instance; + +public: + static RssManager* instance(); + static void drop(); + ~RssManager(); + inline DownloadThread* rssDownloader() const { return m_rssDownloader; } + static void insertSortElem(QList &list, const RssArticle &item); + static QList sortNewsList(const QList& news_list); + +public slots: + void loadStreamList(); + void saveStreamList() const; + void forwardFeedInfosChanged(const QString &url, const QString &aliasOrUrl, uint nbUnread); + void forwardFeedIconChanged(const QString &url, const QString &icon_path); + void moveFile(IRssFile* file, RssFolder* dest_folder); + void updateRefreshInterval(uint val); + +signals: + void feedInfosChanged(const QString &url, const QString &display_name, uint nbUnread); + void feedIconChanged(const QString &url, const QString &icon_path); + +private: + QTimer m_refreshTimer; + uint m_refreshInterval; + DownloadThread *m_rssDownloader; + +}; + +#endif // RSSMANAGER_H diff --git a/src/rss/rsssettings.h b/src/rss/rsssettings.h new file mode 100644 index 000000000..353e39418 --- /dev/null +++ b/src/rss/rsssettings.h @@ -0,0 +1,110 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef RSSSETTINGS_H +#define RSSSETTINGS_H + +#include +#include "qinisettings.h" + +class RssSettings: public QIniSettings{ + +public: + RssSettings() : QIniSettings("qBittorrent", "qBittorrent") {} + + bool isRSSEnabled() const { + return value(QString::fromUtf8("Preferences/RSS/RSSEnabled"), false).toBool(); + } + + void setRSSEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/RSS/RSSEnabled"), enabled); + } + + unsigned int getRSSRefreshInterval() const { + return value(QString::fromUtf8("Preferences/RSS/RSSRefresh"), 5).toUInt(); + } + + void setRSSRefreshInterval(uint interval) { + setValue(QString::fromUtf8("Preferences/RSS/RSSRefresh"), interval); + } + + int getRSSMaxArticlesPerFeed() const { + return value(QString::fromUtf8("Preferences/RSS/RSSMaxArticlesPerFeed"), 50).toInt(); + } + + void setRSSMaxArticlesPerFeed(int nb) { + setValue(QString::fromUtf8("Preferences/RSS/RSSMaxArticlesPerFeed"), nb); + } + + bool isRssDownloadingEnabled() const { + return value("Preferences/RSS/RssDownloading", true).toBool(); + } + + void setRssDownloadingEnabled(bool b) { + setValue("Preferences/RSS/RssDownloading", b); + } + + QStringList getRssFeedsUrls() const { + return value("Rss/streamList").toStringList(); + } + + void setRssFeedsUrls(const QStringList &rssFeeds) { + setValue("Rss/streamList", rssFeeds); + } + + QStringList getRssFeedsAliases() const { + return value("Rss/streamAlias").toStringList(); + } + + void setRssFeedsAliases(const QStringList &rssAliases) { + setValue("Rss/streamAlias", rssAliases); + } + + QList getHostNameCookies(const QString &host_name) const { + QMap hosts_table = value("Rss/hosts_cookies").toMap(); + if(!hosts_table.contains(host_name)) return QList(); + QByteArray raw_cookies = hosts_table.value(host_name).toByteArray(); + return raw_cookies.split(':'); + } + + void setHostNameCookies(const QString &host_name, const QList &cookies) { + QMap hosts_table = value("Rss/hosts_cookies").toMap(); + QByteArray raw_cookies = ""; + foreach(const QByteArray& cookie, cookies) { + raw_cookies += cookie + ":"; + } + if(raw_cookies.endsWith(":")) + raw_cookies.chop(1); + hosts_table.insert(host_name, raw_cookies); + setValue("Rss/hosts_cookies", hosts_table); + } +}; + +#endif // RSSSETTINGS_H diff --git a/src/rss/rsssettingsdlg.cpp b/src/rss/rsssettingsdlg.cpp new file mode 100644 index 000000000..524f5fbf6 --- /dev/null +++ b/src/rss/rsssettingsdlg.cpp @@ -0,0 +1,57 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include "rsssettingsdlg.h" +#include "ui_rsssettingsdlg.h" +#include "rsssettings.h" + +RssSettingsDlg::RssSettingsDlg(QWidget *parent) : + QDialog(parent), + ui(new Ui::RssSettingsDlg) +{ + ui->setupUi(this); + // Load settings + const RssSettings settings; + ui->spinRSSRefresh->setValue(settings.getRSSRefreshInterval()); + ui->spinRSSMaxArticlesPerFeed->setValue(settings.getRSSMaxArticlesPerFeed()); +} + +RssSettingsDlg::~RssSettingsDlg() +{ + qDebug("Deleting the RSS settings dialog"); + delete ui; +} + +void RssSettingsDlg::on_buttonBox_accepted() { + // Save settings + RssSettings settings; + settings.setRSSRefreshInterval(ui->spinRSSRefresh->value()); + settings.setRSSMaxArticlesPerFeed(ui->spinRSSMaxArticlesPerFeed->value()); +} diff --git a/src/rss/rsssettingsdlg.h b/src/rss/rsssettingsdlg.h new file mode 100644 index 000000000..a4d88d177 --- /dev/null +++ b/src/rss/rsssettingsdlg.h @@ -0,0 +1,58 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef RSSSETTINGSDLG_H +#define RSSSETTINGSDLG_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { + class RssSettingsDlg; +} +QT_END_NAMESPACE + +class RssSettingsDlg : public QDialog +{ + Q_OBJECT + +public: + explicit RssSettingsDlg(QWidget *parent = 0); + ~RssSettingsDlg(); + +protected slots: + void on_buttonBox_accepted(); + +private: + Ui::RssSettingsDlg *ui; + +}; + +#endif // RSSSETTINGS_H diff --git a/src/rss/rsssettingsdlg.ui b/src/rss/rsssettingsdlg.ui new file mode 100644 index 000000000..956685e39 --- /dev/null +++ b/src/rss/rsssettingsdlg.ui @@ -0,0 +1,158 @@ + + + RssSettingsDlg + + + + 0 + 0 + 502 + 137 + + + + RSS Reader Settings + + + + + + + + + 48 + 48 + + + + + 48 + 48 + + + + + + + :/Icons/oxygen/application-rss+xml.png + + + true + + + + + + + RSS feeds refresh interval: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 1 + + + 999999 + + + 5 + + + + + + + minutes + + + + + + + Maximum number of articles per feed: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 9999 + + + 100 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + RssSettingsDlg + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + RssSettingsDlg + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/scannedfoldersmodel.cpp b/src/scannedfoldersmodel.cpp new file mode 100644 index 000000000..52c3d4dc8 --- /dev/null +++ b/src/scannedfoldersmodel.cpp @@ -0,0 +1,204 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christian Kandeler, Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include "scannedfoldersmodel.h" +#include "preferences.h" +#include "filesystemwatcher.h" + +#include +#include +#include +#include +#include "qinisettings.h" +#include "misc.h" + +namespace { + const int PathColumn = 0; + const int DownloadAtTorrentColumn = 1; +} + +class ScanFoldersModel::PathData { +public: + PathData(const QString &path) : path(path), downloadAtPath(false) {} + PathData(const QString &path, bool download_at_path) : path(path), downloadAtPath(download_at_path) {} + const QString path; + bool downloadAtPath; +}; + +ScanFoldersModel *ScanFoldersModel::instance(QObject *parent) { + //Q_ASSERT(!parent != !m_instance); + if (!m_instance) + m_instance = new ScanFoldersModel(parent); + return m_instance; +} + +ScanFoldersModel::ScanFoldersModel(QObject *parent) : + QAbstractTableModel(parent), m_fsWatcher(0) +{ } + +ScanFoldersModel::~ScanFoldersModel() { + qDeleteAll(m_pathList); +} + +int ScanFoldersModel::rowCount(const QModelIndex &parent) const { + return parent.isValid() ? 0 : m_pathList.count(); +} + +int ScanFoldersModel::columnCount(const QModelIndex &parent) const { + Q_UNUSED(parent); + return 2; +} + +QVariant ScanFoldersModel::data(const QModelIndex &index, int role) const { + if (!index.isValid() || index.row() >= rowCount()) + return QVariant(); + + const PathData* pathData = m_pathList.at(index.row()); + if (index.column() == PathColumn && role == Qt::DisplayRole) { +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + QString ret = pathData->path; + ret = ret.replace("/", "\\"); + return ret; +#else + return pathData->path; +#endif + } + if (index.column() == DownloadAtTorrentColumn && role == Qt::CheckStateRole) + return pathData->downloadAtPath ? Qt::Checked : Qt::Unchecked; + return QVariant(); +} + +QVariant ScanFoldersModel::headerData(int section, Qt::Orientation orientation, int role) const { + if (orientation != Qt::Horizontal || role != Qt::DisplayRole || section < 0 || section >= columnCount()) + return QVariant(); + + if (section == PathColumn) + return tr("Watched Folder"); + return tr("Download here"); +} + +Qt::ItemFlags ScanFoldersModel::flags(const QModelIndex &index) const { + if (!index.isValid() || index.row() >= rowCount() || index.column() != DownloadAtTorrentColumn) + return QAbstractTableModel::flags(index); + return QAbstractTableModel::flags(index) | Qt::ItemIsUserCheckable; +} + +bool ScanFoldersModel::setData(const QModelIndex &index, const QVariant &value, int role) { + if (!index.isValid() || index.row() >= rowCount() || index.column() > DownloadAtTorrentColumn || role != Qt::CheckStateRole) + return false; + Q_ASSERT(index.column() == DownloadAtTorrentColumn); + m_pathList[index.row()]->downloadAtPath = (value.toInt() == Qt::Checked); + emit dataChanged(index, index); + return true; +} + +ScanFoldersModel::PathStatus ScanFoldersModel::addPath(const QString &path, bool download_at_path) { + QDir dir(path); + if (!dir.exists()) + return DoesNotExist; + if (!dir.isReadable()) + return CannotRead; + const QString &canonicalPath = dir.canonicalPath(); + if (findPathData(canonicalPath) != -1) + return AlreadyInList; + if (!m_fsWatcher) { + m_fsWatcher = new FileSystemWatcher(this); + connect(m_fsWatcher, SIGNAL(torrentsAdded(QStringList&)), this, SIGNAL(torrentsAdded(QStringList&))); + } + beginInsertRows(QModelIndex(), rowCount(), rowCount()); + m_pathList << new PathData(canonicalPath, download_at_path); + endInsertRows(); + // Start scanning + m_fsWatcher->addPath(canonicalPath); + return Ok; +} + +void ScanFoldersModel::removePath(int row) { + Q_ASSERT(row >= 0 && row < rowCount()); + beginRemoveRows(QModelIndex(), row, row); + m_fsWatcher->removePath(m_pathList.at(row)->path); + m_pathList.removeAt(row); + endRemoveRows(); +} + +bool ScanFoldersModel::removePath(const QString &path) { + const int row = findPathData(path); + if (row == -1) + return false; + removePath(row); + return true; +} + +ScanFoldersModel::PathStatus ScanFoldersModel::setDownloadAtPath(int row, bool downloadAtPath) { + Q_ASSERT(row >= 0 && row < rowCount()); + + bool &oldValue = m_pathList[row]->downloadAtPath; + if (oldValue != downloadAtPath) { + if (downloadAtPath) { + QTemporaryFile testFile(m_pathList[row]->path + "/tmpFile"); + if (!testFile.open()) + return CannotWrite; + } + oldValue = downloadAtPath; + const QModelIndex changedIndex = index(row, DownloadAtTorrentColumn); + emit dataChanged(changedIndex, changedIndex); + } + return Ok; +} + +bool ScanFoldersModel::downloadInTorrentFolder(const QString &filePath) const { + const int row = findPathData(QFileInfo(filePath).dir().path()); + Q_ASSERT(row != -1); + return m_pathList.at(row)->downloadAtPath; +} + +int ScanFoldersModel::findPathData(const QString &path) const { + for (int i = 0; i < m_pathList.count(); ++i) { + const PathData* pathData = m_pathList.at(i); + if (pathData->path == path) + return i; + } + + return -1; +} + +void ScanFoldersModel::makePersistent() { + Preferences pref; + QStringList paths; + QList downloadInFolderInfo; + foreach (const PathData* pathData, m_pathList) { + paths << pathData->path; + downloadInFolderInfo << pathData->downloadAtPath; + } + pref.setScanDirs(paths); + pref.setDownloadInScanDirs(downloadInFolderInfo); +} + +ScanFoldersModel *ScanFoldersModel::m_instance = 0; diff --git a/src/scannedfoldersmodel.h b/src/scannedfoldersmodel.h new file mode 100644 index 000000000..f0551d3e6 --- /dev/null +++ b/src/scannedfoldersmodel.h @@ -0,0 +1,81 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christian Kandeler, Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef SCANNEDFOLDERSMODEL_H +#define SCANNEDFOLDERSMODEL_H + +#include +#include +#include + +class FileSystemWatcher; +class QIniSettings; + +class ScanFoldersModel : public QAbstractTableModel { + Q_OBJECT + Q_DISABLE_COPY(ScanFoldersModel) + +public: + enum PathStatus { Ok, DoesNotExist, CannotRead, CannotWrite, AlreadyInList }; + static ScanFoldersModel *instance(QObject *parent = 0); + virtual ~ScanFoldersModel(); + + virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + // TODO: removePaths(); singular version becomes private helper functions; + // also: remove functions should take modelindexes + PathStatus addPath(const QString &path, bool download_at_path); + void removePath(int row); + bool removePath(const QString &path); + PathStatus setDownloadAtPath(int row, bool downloadAtPath); + + bool downloadInTorrentFolder(const QString &filePath) const; + void makePersistent(); + +signals: + // The absolute paths of new torrent files in the scanned directories. + void torrentsAdded(QStringList &pathList); + +private: + explicit ScanFoldersModel(QObject *parent); + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + static ScanFoldersModel *m_instance; + class PathData; + int findPathData(const QString &path) const; + + QList m_pathList; + FileSystemWatcher *m_fsWatcher; +}; + +#endif // SCANNEDFOLDERSMODEL_H diff --git a/src/searchengine/engineselect.ui b/src/searchengine/engineselect.ui new file mode 100644 index 000000000..da832485d --- /dev/null +++ b/src/searchengine/engineselect.ui @@ -0,0 +1,130 @@ + + + engineSelect + + + + 0 + 0 + 541 + 254 + + + + true + + + Search plugins + + + + + + + 75 + true + true + + + + Installed search engines: + + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::ExtendedSelection + + + true + + + false + + + + Name + + + + + Url + + + + + Enabled + + + + + + + + + + + + + + true + + + + You can get new search engine plugins here: <a href="http://plugins.qbittorrent.org">http://plugins.qbittorrent.org</a> + + + Qt::AutoText + + + true + + + + + + + + + Install a new one + + + + + + + Check for updates + + + + + + + Close + + + + + + + + + true + + + Enabled + + + + + Uninstall + + + + + + diff --git a/src/searchengine/engineselectdlg.cpp b/src/searchengine/engineselectdlg.cpp new file mode 100644 index 000000000..fe4142000 --- /dev/null +++ b/src/searchengine/engineselectdlg.cpp @@ -0,0 +1,456 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include "engineselectdlg.h" +#include "downloadthread.h" +#include "misc.h" +#include "ico.h" +#include "searchengine.h" +#include "pluginsource.h" +#include "iconprovider.h" +#include +#include +#include +#include +#include +#include +#include +#include + +enum EngineColumns {ENGINE_NAME, ENGINE_URL, ENGINE_STATE, ENGINE_ID}; +#define UPDATE_URL "http://qbittorrent.svn.sourceforge.net/viewvc/qbittorrent/trunk/src/searchengine/nova/engines/" + +engineSelectDlg::engineSelectDlg(QWidget *parent, SupportedEngines *supported_engines) : QDialog(parent), supported_engines(supported_engines) { + setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + pluginsTree->header()->resizeSection(0, 170); + pluginsTree->header()->resizeSection(1, 220); + pluginsTree->hideColumn(ENGINE_ID); + actionUninstall->setIcon(IconProvider::instance()->getIcon("list-remove")); + connect(actionEnable, SIGNAL(toggled(bool)), this, SLOT(enableSelection(bool))); + connect(pluginsTree, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayContextMenu(const QPoint&))); + downloader = new DownloadThread(this); + connect(downloader, SIGNAL(downloadFinished(QString, QString)), this, SLOT(processDownloadedFile(QString, QString))); + connect(downloader, SIGNAL(downloadFailure(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString))); + loadSupportedSearchEngines(); + connect(supported_engines, SIGNAL(newSupportedEngine(QString)), this, SLOT(addNewEngine(QString))); + connect(pluginsTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(toggleEngineState(QTreeWidgetItem*, int))); + show(); +} + +engineSelectDlg::~engineSelectDlg() { + qDebug("Destroying engineSelectDlg"); + emit enginesChanged(); + qDebug("Before deleting downloader"); + delete downloader; + qDebug("Engine plugins dialog destroyed"); +} + +void engineSelectDlg::dropEvent(QDropEvent *event) { + event->acceptProposedAction(); + QStringList files=event->mimeData()->text().split(QString::fromUtf8("\n")); + foreach(QString file, files) { + qDebug("dropped %s", qPrintable(file)); + if(misc::isUrl(file)) { + setCursor(QCursor(Qt::WaitCursor)); + downloader->downloadUrl(file); + continue; + } + if(file.endsWith(".py", Qt::CaseInsensitive)) { + if(file.startsWith("file:", Qt::CaseInsensitive)) + file = QUrl(file).toLocalFile(); + QString plugin_name = misc::fileName(file); + plugin_name.chop(3); // Remove extension + installPlugin(file, plugin_name); + } + } +} + +// Decode if we accept drag 'n drop or not +void engineSelectDlg::dragEnterEvent(QDragEnterEvent *event) { + QString mime; + foreach(mime, event->mimeData()->formats()){ + qDebug("mimeData: %s", qPrintable(mime)); + } + if (event->mimeData()->hasFormat(QString::fromUtf8("text/plain")) || event->mimeData()->hasFormat(QString::fromUtf8("text/uri-list"))) { + event->acceptProposedAction(); + } +} + +void engineSelectDlg::on_updateButton_clicked() { + // Download version file from update server on sourceforge + setCursor(QCursor(Qt::WaitCursor)); + downloader->downloadUrl(QString(UPDATE_URL)+"versions.txt"); +} + +void engineSelectDlg::toggleEngineState(QTreeWidgetItem *item, int) { + SupportedEngine *engine = supported_engines->value(item->text(ENGINE_ID)); + engine->setEnabled(!engine->isEnabled()); + if(engine->isEnabled()) { + item->setText(ENGINE_STATE, tr("Yes")); + setRowColor(pluginsTree->indexOfTopLevelItem(item), "green"); + } else { + item->setText(ENGINE_STATE, tr("No")); + setRowColor(pluginsTree->indexOfTopLevelItem(item), "red"); + } +} + +void engineSelectDlg::displayContextMenu(const QPoint&) { + QMenu myContextMenu(this); + // Enable/disable pause/start action given the DL state + QList items = pluginsTree->selectedItems(); + if(items.isEmpty()) return; + QString first_id = items.first()->text(ENGINE_ID); + actionEnable->setChecked(supported_engines->value(first_id)->isEnabled()); + myContextMenu.addAction(actionEnable); + myContextMenu.addSeparator(); + myContextMenu.addAction(actionUninstall); + myContextMenu.exec(QCursor::pos()); +} + +void engineSelectDlg::on_closeButton_clicked() { + close(); +} + +void engineSelectDlg::on_actionUninstall_triggered() { + QList items = pluginsTree->selectedItems(); + QTreeWidgetItem *item; + bool error = false; + foreach(item, items) { + int index = pluginsTree->indexOfTopLevelItem(item); + Q_ASSERT(index != -1); + QString id = item->text(ENGINE_ID); + if(QFile::exists(":/nova/engines/"+id+".py")) { + error = true; + // Disable it instead + supported_engines->value(id)->setEnabled(false); + item->setText(ENGINE_STATE, tr("No")); + setRowColor(index, "red"); + continue; + }else { + // Proceed with uninstall + // remove it from hard drive + QDir enginesFolder(misc::searchEngineLocation()+QDir::separator()+"engines"); + QStringList filters; + filters << id+".*"; + QStringList files = enginesFolder.entryList(filters, QDir::Files, QDir::Unsorted); + QString file; + foreach(file, files) { + enginesFolder.remove(file); + } + // Remove it from supported engines + delete supported_engines->take(id); + delete item; + } + } + if(error) + QMessageBox::warning(0, tr("Uninstall warning"), tr("Some plugins could not be uninstalled because they are included in qBittorrent.\n Only the ones you added yourself can be uninstalled.\nHowever, those plugins were disabled.")); + else + QMessageBox::information(0, tr("Uninstall success"), tr("All selected plugins were uninstalled successfully")); +} + +void engineSelectDlg::enableSelection(bool enable) { + QList items = pluginsTree->selectedItems(); + QTreeWidgetItem *item; + foreach(item, items) { + int index = pluginsTree->indexOfTopLevelItem(item); + Q_ASSERT(index != -1); + QString id = item->text(ENGINE_ID); + supported_engines->value(id)->setEnabled(enable); + if(enable) { + item->setText(ENGINE_STATE, tr("Yes")); + setRowColor(index, "green"); + } else { + item->setText(ENGINE_STATE, tr("No")); + setRowColor(index, "red"); + } + } +} + +// Set the color of a row in data model +void engineSelectDlg::setRowColor(int row, QString color){ + QTreeWidgetItem *item = pluginsTree->topLevelItem(row); + for(int i=0; icolumnCount(); ++i){ + item->setData(i, Qt::ForegroundRole, QVariant(QColor(color))); + } +} + +QList engineSelectDlg::findItemsWithUrl(QString url){ + QList res; + for(int i=0; itopLevelItemCount(); ++i) { + QTreeWidgetItem *item = pluginsTree->topLevelItem(i); + if(url.startsWith(item->text(ENGINE_URL), Qt::CaseInsensitive)) + res << item; + } + return res; +} + +QTreeWidgetItem* engineSelectDlg::findItemWithID(QString id){ + QList res; + for(int i=0; itopLevelItemCount(); ++i) { + QTreeWidgetItem *item = pluginsTree->topLevelItem(i); + if(id == item->text(ENGINE_ID)) + return item; + } + return 0; +} + +bool engineSelectDlg::isUpdateNeeded(QString plugin_name, qreal new_version) const { + qreal old_version = SearchEngine::getPluginVersion(misc::searchEngineLocation()+QDir::separator()+"engines"+QDir::separator()+plugin_name+".py"); + qDebug("IsUpdate needed? tobeinstalled: %.2f, alreadyinstalled: %.2f", new_version, old_version); + return (new_version > old_version); +} + +void engineSelectDlg::installPlugin(QString path, QString plugin_name) { + qDebug("Asked to install plugin at %s", qPrintable(path)); + qreal new_version = SearchEngine::getPluginVersion(path); + qDebug("Version to be installed: %.2f", new_version); + if(!isUpdateNeeded(plugin_name, new_version)) { + qDebug("Apparently update is not needed, we have a more recent version"); + QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("A more recent version of %1 search engine plugin is already installed.", "%1 is the name of the search engine").arg(plugin_name)); + return; + } + // Process with install + QString dest_path = misc::searchEngineLocation()+QDir::separator()+"engines"+QDir::separator()+plugin_name+".py"; + bool update = false; + if(QFile::exists(dest_path)) { + // Backup in case install fails + QFile::copy(dest_path, dest_path+".bak"); + misc::safeRemove(dest_path); + misc::safeRemove(dest_path+"c"); + update = true; + } + // Copy the plugin + QFile::copy(path, dest_path); + // Update supported plugins + supported_engines->update(); + // Check if this was correctly installed + if(!supported_engines->contains(plugin_name)) { + if(update) { + // Remove broken file + misc::safeRemove(dest_path); + // restore backup + QFile::copy(dest_path+".bak", dest_path); + misc::safeRemove(dest_path+".bak"); + QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be updated, keeping old version.", "%1 is the name of the search engine").arg(plugin_name)); + return; + } else { + // Remove broken file + misc::safeRemove(dest_path); + QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be installed.", "%1 is the name of the search engine").arg(plugin_name)); + return; + } + } + // Install was successful, remove backup + if(update) { + misc::safeRemove(dest_path+".bak"); + } + if(update) { + QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin was successfully updated.", "%1 is the name of the search engine").arg(plugin_name)); + return; + } else { + QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin was successfully installed.", "%1 is the name of the search engine").arg(plugin_name)); + return; + } +} + +void engineSelectDlg::loadSupportedSearchEngines() { + // Some clean up first + pluginsTree->clear(); + foreach(QString name, supported_engines->keys()) { + addNewEngine(name); + } +} + +void engineSelectDlg::addNewEngine(QString engine_name) { + QTreeWidgetItem *item = new QTreeWidgetItem(pluginsTree); + SupportedEngine *engine = supported_engines->value(engine_name); + item->setText(ENGINE_NAME, engine->getFullName()); + item->setText(ENGINE_URL, engine->getUrl()); + item->setText(ENGINE_ID, engine->getName()); + if(engine->isEnabled()) { + item->setText(ENGINE_STATE, tr("Yes")); + setRowColor(pluginsTree->indexOfTopLevelItem(item), "green"); + } else { + item->setText(ENGINE_STATE, tr("No")); + setRowColor(pluginsTree->indexOfTopLevelItem(item), "red"); + } + // Handle icon + QString iconPath = misc::searchEngineLocation()+QDir::separator()+"engines"+QDir::separator()+engine->getName()+".png"; + if(QFile::exists(iconPath)) { + // Good, we already have the icon + item->setData(ENGINE_NAME, Qt::DecorationRole, QVariant(QIcon(iconPath))); + } else { + iconPath = misc::searchEngineLocation()+QDir::separator()+"engines"+QDir::separator()+engine->getName()+".ico"; + if(QFile::exists(iconPath)) { // ICO support + item->setData(ENGINE_NAME, Qt::DecorationRole, QVariant(QIcon(iconPath))); + } else { + // Icon is missing, we must download it + downloader->downloadUrl(engine->getUrl()+"/favicon.ico"); + } + } +} + +void engineSelectDlg::on_installButton_clicked() { + pluginSourceDlg *dlg = new pluginSourceDlg(this); + connect(dlg, SIGNAL(askForLocalFile()), this, SLOT(askForLocalPlugin())); + connect(dlg, SIGNAL(askForUrl()), this, SLOT(askForPluginUrl())); +} + +void engineSelectDlg::askForPluginUrl() { + bool ok; + QString url = QInputDialog::getText(this, tr("New search engine plugin URL"), + tr("URL:"), QLineEdit::Normal, + "http://", &ok); + if (ok && !url.isEmpty()) { + setCursor(QCursor(Qt::WaitCursor)); + downloader->downloadUrl(url); + } +} + +void engineSelectDlg::askForLocalPlugin() { + QStringList pathsList = QFileDialog::getOpenFileNames(0, + tr("Select search plugins"), QDir::homePath(), + tr("qBittorrent search plugins")+QString::fromUtf8(" (*.py)")); + QString path; + foreach(path, pathsList) { + if(path.endsWith(".py", Qt::CaseInsensitive)) { + QString plugin_name = path.split(QDir::separator()).last(); + plugin_name.replace(".py", "", Qt::CaseInsensitive); + installPlugin(path, plugin_name); + } + } +} + +bool engineSelectDlg::parseVersionsFile(QString versions_file) { + qDebug("Checking if update is needed"); + bool file_correct = false; + QFile versions(versions_file); + if(!versions.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug("* Error: Could not read versions.txt file"); + return false; + } + bool updated = false; + while(!versions.atEnd()) { + QByteArray line = versions.readLine(); + line.replace("\n", ""); + line = line.trimmed(); + if(line.isEmpty()) continue; + if(line.startsWith("#")) continue; + QList list = line.split(' '); + if(list.size() != 2) continue; + QString plugin_name = QString(list.first()); + if(!plugin_name.endsWith(":")) continue; + plugin_name.chop(1); // remove trailing ':' + bool ok; + qreal version = list.last().toFloat(&ok); + qDebug("read line %s: %.2f", qPrintable(plugin_name), version); + if(!ok) continue; + file_correct = true; + if(isUpdateNeeded(plugin_name, version)) { + qDebug("Plugin: %s is outdated", qPrintable(plugin_name)); + // Downloading update + setCursor(QCursor(Qt::WaitCursor)); + downloader->downloadUrl(UPDATE_URL+plugin_name+".py"); + //downloader->downloadUrl(UPDATE_URL+plugin_name+".png"); + updated = true; + }else { + qDebug("Plugin: %s is up to date", qPrintable(plugin_name)); + } + } + // Close file + versions.close(); + // Clean up tmp file + misc::safeRemove(versions_file); + if(file_correct && !updated) { + QMessageBox::information(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("All your plugins are already up to date.")); + } + return file_correct; +} + +void engineSelectDlg::processDownloadedFile(QString url, QString filePath) { + setCursor(QCursor(Qt::ArrowCursor)); + qDebug("engineSelectDlg received %s", qPrintable(url)); + if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){ + // Icon downloaded + QImage fileIcon; + if(fileIcon.load(filePath)) { + QList items = findItemsWithUrl(url); + QTreeWidgetItem *item; + foreach(item, items){ + QString id = item->text(ENGINE_ID); + QString iconPath; + QFile icon(filePath); + icon.open(QIODevice::ReadOnly); + if(ICOHandler::canRead(&icon)) + iconPath = misc::searchEngineLocation()+QDir::separator()+"engines"+QDir::separator()+id+".ico"; + else + iconPath = misc::searchEngineLocation()+QDir::separator()+"engines"+QDir::separator()+id+".png"; + QFile::copy(filePath, iconPath); + item->setData(ENGINE_NAME, Qt::DecorationRole, QVariant(QIcon(iconPath))); + } + } + // Delete tmp file + misc::safeRemove(filePath); + return; + } + if(url.endsWith("versions.txt")) { + if(!parseVersionsFile(filePath)) { + QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, update server is temporarily unavailable.")); + } + misc::safeRemove(filePath); + return; + } + if(url.endsWith(".py", Qt::CaseInsensitive)) { + QString plugin_name = misc::fileName(url); + plugin_name.chop(3); // Remove extension + installPlugin(filePath, plugin_name); + misc::safeRemove(filePath); + return; + } +} + +void engineSelectDlg::handleDownloadFailure(QString url, QString reason) { + setCursor(QCursor(Qt::ArrowCursor)); + if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){ + qDebug("Could not download favicon: %s, reason: %s", qPrintable(url), qPrintable(reason)); + return; + } + if(url.endsWith("versions.txt")) { + QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, update server is temporarily unavailable.")); + return; + } + if(url.endsWith(".py", Qt::CaseInsensitive)) { + // a plugin update download has been failed + QString plugin_name = url.split('/').last(); + plugin_name.replace(".py", "", Qt::CaseInsensitive); + QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, %1 search plugin install failed.", "%1 is the name of the search engine").arg(plugin_name)); + } +} diff --git a/src/searchengine/engineselectdlg.h b/src/searchengine/engineselectdlg.h new file mode 100644 index 000000000..31acdcd47 --- /dev/null +++ b/src/searchengine/engineselectdlg.h @@ -0,0 +1,83 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef ENGINE_SELECT_DLG_H +#define ENGINE_SELECT_DLG_H + +#include "ui_engineselect.h" +#include "supportedengines.h" + +class DownloadThread; + +QT_BEGIN_NAMESPACE +class QDropEvent; +QT_END_NAMESPACE + +class engineSelectDlg : public QDialog, public Ui::engineSelect{ + Q_OBJECT + + private: + DownloadThread *downloader; + SupportedEngines *supported_engines; + + public: + engineSelectDlg(QWidget *parent, SupportedEngines *supported_engines); + ~engineSelectDlg(); + QList findItemsWithUrl(QString url); + QTreeWidgetItem* findItemWithID(QString id); + + protected: + bool parseVersionsFile(QString versions_file); + bool isUpdateNeeded(QString plugin_name, qreal new_version) const; + + signals: + void enginesChanged(); + + protected slots: + void on_closeButton_clicked(); + void loadSupportedSearchEngines(); + void addNewEngine(QString engine_name); + void toggleEngineState(QTreeWidgetItem*, int); + void setRowColor(int row, QString color); + void processDownloadedFile(QString url, QString filePath); + void handleDownloadFailure(QString url, QString reason); + void displayContextMenu(const QPoint& pos); + void enableSelection(bool enable); + void on_actionUninstall_triggered(); + void on_updateButton_clicked(); + void on_installButton_clicked(); + void dropEvent(QDropEvent *event); + void dragEnterEvent(QDragEnterEvent *event); + void installPlugin(QString plugin_path, QString plugin_name); + void askForLocalPlugin(); + void askForPluginUrl(); +}; + +#endif diff --git a/src/searchengine/nova/__init__.py b/src/searchengine/nova/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/searchengine/nova/engines/__init__.py b/src/searchengine/nova/engines/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/searchengine/nova/engines/btdigg.png b/src/searchengine/nova/engines/btdigg.png new file mode 100644 index 0000000000000000000000000000000000000000..2823b9ae1ad69834125d46848676bff6e6ebf75b GIT binary patch literal 692 zcmV;l0!#ggP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipV+ z2qQ99eRr_{00J~gL_t(I%Z-vxXp(Ul$G`9E+}?}EDhOGyV{{2Zs6j+sVj(pI!9yUl z%OF^h$I&5Jbr>WJy420ZTXd>mMX*4Y1g7mYA(UJp%r*5z(fM!l_deea#$aT#&*cX{ zcs|dU=Xt_XHx(XYt_a1f0Ka;>+hXKm!IQ*r~NZM;(#-9@Mvh$1nEq=wTR_ zPbDyNa&B+}*AXX%oyX8%NQJ>j-UIdUhdgD$@QV5D_jcEHIzXGndP8Wo3n?X)>8i zG8pjfXX*z?G8T)mTCFml&oh(BaAszPu~>}3U~s>*-QMjh&;g)Qsi4#8Kt!;-yo~AT zX_%%7zu%8<>sg2>IGv8ZThdag6un+A3WWkh1dT=m>2w<7~y>Iy#C%p@4F^3|-d|3WfgJ^?;z&YSAzZlu9LNng+Mq4Z|?- azx)O#+0=-^3MYa90000 +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +import urllib +import urllib2 +import sys + +from novaprinter import prettyPrinter + +class btdigg(object): + url = 'http://btdigg.org' + name = 'BTDigg' + + supported_categories = {'all': ''} + + def __init__(self): + pass + + def search(self, what, cat='all'): + req = what.replace('+', ' ') + u = urllib2.urlopen('http://api.btdigg.org/api/public-8e9a50f8335b964f/s01?%s' % (urllib.urlencode(dict(q = req)),)) + + try: + for line in u: + if line.startswith('#'): + continue + + info_hash, name, files, size, dl, seen = line.strip().split('\t')[:6] + + res = dict(link = 'magnet:?xt=urn:btih:%s' % (info_hash,), + name = name.translate(None, '|'), + size = size, + seeds = int(dl), + leech = int(dl), + engine_url = self.url, + desc_link = 'http://btdigg.org/search?%s' % (urllib.urlencode(dict(info_hash = info_hash, q = req)),)) + + prettyPrinter(res) + finally: + u.close() + + + + +if __name__ == "__main__": + s = btdigg() + s.search(sys.argv[1]) diff --git a/src/searchengine/nova/engines/btjunkie.png b/src/searchengine/nova/engines/btjunkie.png new file mode 100644 index 0000000000000000000000000000000000000000..a3161758079ca0ccee7452294e9945d17c22949c GIT binary patch literal 622 zcmV-!0+IcRP)FyLY`R z6Qf`U*`ahZ)7%6vL3RqlgH}X(C=j|-l2N3W2s*S&6c~{aK^LJ2PpNcmRHrT@rUP+X zlbFgJ8#8rfxZnG9kiE{5-t1JcVG zN|>CQ0-#td{?R&`UHFBH;DI8e%B zwXlK1S+!-M{p@|Y^JqduM7nzV1WmV7_BA!xatDL2#DD6poF9I^Gek=F0468KsdD=< z_EZB9kHu(g^Z}rhs<5F07>3SNC_>{Qf z-r5@44|@nSd-zsZV}E-;rfZ))I6V_(E|~%CHwu&`bar?dyLXY-qXYDxIf|t=IdtL% z{wN@O3a~;b424$SY)w&?)5m30=D^L(03v6T5rt;^(6Zzm6L^&uiymc`@I zCoH9NtgL+}mQ3$Z@y9n+mSy)=SuY~e-QBbO$|AyU5Dtg=2^-y+reRWb_y7O^07*qo IM6N<$g2v?%s{jB1 literal 0 HcmV?d00001 diff --git a/src/searchengine/nova/engines/btjunkie.py b/src/searchengine/nova/engines/btjunkie.py new file mode 100644 index 000000000..d5165bb36 --- /dev/null +++ b/src/searchengine/nova/engines/btjunkie.py @@ -0,0 +1,122 @@ +#VERSION: 2.31 +#AUTHORS: Christophe Dumez (chris@qbittorrent.org) + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + + +from novaprinter import prettyPrinter +from helpers import retrieve_url, download_file +import sgmllib +import re + +class btjunkie(object): + url = 'http://btjunkie.org' + name = 'btjunkie' + supported_categories = {'all': '0', 'movies': '6', 'tv': '4', 'music': '1', 'games': '2', 'anime': '7', 'software': '3'} + + def __init__(self): + self.results = [] + self.parser = self.SimpleSGMLParser(self.results, self.url) + + def download_torrent(self, info): + print download_file(info) + + class SimpleSGMLParser(sgmllib.SGMLParser): + def __init__(self, results, url, *args): + sgmllib.SGMLParser.__init__(self) + self.url = url + self.th_counter = None + self.current_item = None + self.results = results + + def start_a(self, attr): + params = dict(attr) + #print params + if params.has_key('href'): + if params['href'].startswith("http://dl.btjunkie.org/torrent"): + self.current_item = {} + self.th_counter = 0 + self.current_item['link']=params['href'].strip() + elif self.th_counter == 0 and params['href'].startswith("/torrent/") and params['href'].find('/files/') == -1: + self.current_item['desc_link'] = 'http://btjunkie.org'+params['href'].strip() + + def handle_data(self, data): + if self.th_counter == 0: + if not self.current_item.has_key('name'): + self.current_item['name'] = '' + self.current_item['name']+= data.strip() + elif self.th_counter == 3: + if not self.current_item.has_key('size'): + self.current_item['size'] = '' + self.current_item['size']+= data.strip() + elif self.th_counter == 5: + if not self.current_item.has_key('seeds'): + self.current_item['seeds'] = '' + self.current_item['seeds']+= data.strip() + elif self.th_counter == 6: + if not self.current_item.has_key('leech'): + self.current_item['leech'] = '' + self.current_item['leech']+= data.strip() + + def start_th(self,attr): + if isinstance(self.th_counter,int): + self.th_counter += 1 + if self.th_counter > 6: + self.th_counter = None + # Display item + if self.current_item: + self.current_item['engine_url'] = self.url + if not self.current_item['seeds'].isdigit(): + self.current_item['seeds'] = 0 + if not self.current_item['leech'].isdigit(): + self.current_item['leech'] = 0 + prettyPrinter(self.current_item) + self.results.append('a') + + def search(self, what, cat='all'): + # Remove {} since btjunkie does not seem + # to handle those very well + what = what.replace('{', '').replace('}', '') + ret = [] + i = 1 + while True and i<11: + results = [] + parser = self.SimpleSGMLParser(results, self.url) + dat = retrieve_url(self.url+'/search?q=%s&c=%s&o=52&p=%d'%(what, self.supported_categories[cat], i)) + # Remove tags from page + p = re.compile( '<[/]?font.*?>') + dat = p.sub('', dat) + #print dat + #return + results_re = re.compile('(?s)class="tab_results">.*') + for match in results_re.finditer(dat): + res_tab = match.group(0) + parser.feed(res_tab) + parser.close() + break + if len(results) <= 0: + break + i += 1 + diff --git a/src/searchengine/nova/engines/extratorrent.png b/src/searchengine/nova/engines/extratorrent.png new file mode 100644 index 0000000000000000000000000000000000000000..e5e84571881547a82934e344287255c6e94adc06 GIT binary patch literal 605 zcmV-j0;2tiP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igo8 z3MmdNO!z4P00G@eL_t(I%bk-wXjDNIg}*!V^5Vu71!E(TR2sDii4dckuqhNlD|@?u zsD%=26txy@G{z#@2tq)ER#q0-hze^2MFsH(Nns&m-9X%EcKylDwV3yw`}_gf3j;HA zFXx^)=Z;JlW>nPyf{5@xp{jr)VhB_no40h*OuTvho&W@63;_2Z7J2&QG1eHIDpmwU zqK-a#dixm4=c1Dk#2Zkazk18zqa*+9c;)gakBSc%$`1e@GypJGA`l_7W-S2Ymo8HI zv_RMrA`y#)&sDm&b~V(;0Adm%9~Y|tJbUqy)5njbgxk2OD{h=b0AP&;pv5TjUmO6# zBPW=+aqU-O7?SHRkslnOH4M`L#(Dr}pZ z4VD+@nVo%yK~TV{BfDxf8#+2ta}hm3VyUV9@X0;L&T(~Ol%-lVDb8ftIIw>&{e9bh zbHVy~GS>37wv;5ZyAP6WpkJIEXY$r{?0!EA=%f`hy+$O00000NkvXXu0mjfksts* literal 0 HcmV?d00001 diff --git a/src/searchengine/nova/engines/extratorrent.py b/src/searchengine/nova/engines/extratorrent.py new file mode 100755 index 000000000..b57558915 --- /dev/null +++ b/src/searchengine/nova/engines/extratorrent.py @@ -0,0 +1,116 @@ +#VERSION: 1.1 +#AUTHORS: Christophe Dumez (chris@qbittorrent.org) + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + + +from novaprinter import prettyPrinter +from helpers import retrieve_url, download_file +import sgmllib +import re + +class extratorrent(object): + url = 'http://extratorrent.com' + name = 'extratorrent' + supported_categories = {'all': '', 'movies': '4', 'tv': '8', 'music': '5', 'games': '3', 'anime': '1', 'software': '7', 'books': '2', 'pictures': '6'} + + def __init__(self): + self.results = [] + self.parser = self.SimpleSGMLParser(self.results, self.url) + + def download_torrent(self, info): + print download_file(info) + + class SimpleSGMLParser(sgmllib.SGMLParser): + def __init__(self, results, url, *args): + sgmllib.SGMLParser.__init__(self) + self.url = url + self.td_counter = None + self.current_item = None + self.start_name = False + self.results = results + + def start_a(self, attr): + params = dict(attr) + #print params + if params.has_key('href') and params['href'].startswith("/torrent_download/"): + self.current_item = {} + self.td_counter = 0 + self.start_name = False + torrent_id = '/'.join(params['href'].split('/')[2:]) + self.current_item['link']=self.url+'/download/'+torrent_id + elif params.has_key('href') and params['href'].startswith("/torrent/") and params['href'].endswith(".html"): + self.current_item['desc_link'] = self.url + params['href'].strip() + self.start_name = True + + def handle_data(self, data): + if self.td_counter == 2: + if not self.current_item.has_key('name') and self.start_name: + self.current_item['name'] = data.strip() + elif self.td_counter == 3: + if not self.current_item.has_key('size'): + self.current_item['size'] = '' + self.current_item['size']+= data.replace(" ", " ").strip() + elif self.td_counter == 4: + if not self.current_item.has_key('seeds'): + self.current_item['seeds'] = '' + self.current_item['seeds']+= data.strip() + elif self.td_counter == 5: + if not self.current_item.has_key('leech'): + self.current_item['leech'] = '' + self.current_item['leech']+= data.strip() + + def start_td(self,attr): + if isinstance(self.td_counter,int): + self.td_counter += 1 + if self.td_counter > 5: + self.td_counter = None + # Display item + if self.current_item: + self.current_item['engine_url'] = self.url + if not self.current_item['seeds'].isdigit(): + self.current_item['seeds'] = 0 + if not self.current_item['leech'].isdigit(): + self.current_item['leech'] = 0 + prettyPrinter(self.current_item) + self.results.append('a') + + def search(self, what, cat='all'): + ret = [] + i = 1 + while True and i<11: + results = [] + parser = self.SimpleSGMLParser(results, self.url) + dat = retrieve_url(self.url+'/advanced_search/?with=%s&s_cat=%s&page=%d'%(what, self.supported_categories[cat], i)) + results_re = re.compile('(?s).*') + for match in results_re.finditer(dat): + res_tab = match.group(0) + parser.feed(res_tab) + parser.close() + break + if len(results) <= 0: + break + i += 1 + diff --git a/src/searchengine/nova/engines/isohunt.png b/src/searchengine/nova/engines/isohunt.png new file mode 100644 index 0000000000000000000000000000000000000000..e71fb1ca23ff886c2bd8e656d31034943c8ec568 GIT binary patch literal 633 zcmV-<0*3vGP)K z^Us`Ho5TIH?PpHs)1`i}qMAL&FVE-2=izxC_>UD$tjf@GLIRX-H~ea3Lb}gf$6IG3 zwVIL2c7bp@gQl%>w97?BxkczeG@h3CpS+Q8$EM}qfWe`6>@bvZps5i69e6P^PXB{v ze3%OSG5mQUB7@NcjSbb<$_<6U=wt|!s?zFp;9pvihcDcg=LR0hrC3sL6iuXvrLr9H zI_W*uA#`9R{Z-B_gfN@RXmjmh+8IWO0OlfLa`{cXP8(LUN+uZx zz-%@G0ubc4B-yofdOF<5Eead>7goq>IS%dj5QrpLjHGFD*%`Wb1#d&O02m(g$%{80 zqpAw6UWa}xDad)|s3Q z;IvyYs0OBH!^DyqTn>A|#>?kVh?ftqiSAC9C;+M|EaKMHK2G;^;;P*(KKX(GR9a0% zz06X8zT@q>8q+iY_BpGI0)G1oD$vzjkH=k86d-;bWVJP!+mNWn63hmJ_!saU_r<`@ T=4)dh00000NkvXXu0mjfO$8z7 literal 0 HcmV?d00001 diff --git a/src/searchengine/nova/engines/isohunt.py b/src/searchengine/nova/engines/isohunt.py new file mode 100644 index 000000000..c37315c09 --- /dev/null +++ b/src/searchengine/nova/engines/isohunt.py @@ -0,0 +1,69 @@ +#VERSION: 1.4 +#AUTHORS: Christophe Dumez (chris@qbittorrent.org) + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from novaprinter import prettyPrinter +import re +from helpers import retrieve_url, download_file + +class isohunt(object): + url = 'http://isohunt.com' + name = 'isoHunt' + supported_categories = {'all': '', 'movies': '1', 'tv': '3', 'music': '2', 'games': '4', 'anime': '7', 'software': '5', 'pictures': '6', 'books': '9'} + + def download_torrent(self, info): + print download_file(info) + + def search(self, what, cat='all'): + # Remove {} since isohunt does not seem + # to handle those very well + what = what.replace('{', '').replace('}', '') + i = 1 + while True and i<11: + res = 0 + dat = retrieve_url(self.url+'/torrents.php?ihq=%s&iht=%s&ihp=%s&ihs1=2&iho1=d'%(what, self.supported_categories[cat],i)) + # I know it's not very readable, but the SGML parser feels in pain + section_re = re.compile('(?s)id=link.*?.*?[^/]+).*?' + '>(?P.*?).*?' + '>(?P[\d,\.]+\s+MB).*?' + '>(?P\d+).*?' + '>(?P\d+)') + for match in section_re.finditer(dat): + txt = match.group(0) + m = torrent_re.search(txt) + if m: + torrent_infos = m.groupdict() + torrent_infos['name'] = re.sub('<.*?>', '', torrent_infos['name']) + torrent_infos['engine_url'] = self.url + torrent_code = torrent_infos['link'] + torrent_infos['link'] = 'http://isohunt.com/download/'+torrent_code + torrent_infos['desc_link'] = 'http://isohunt.com/torrent_details/'+torrent_code+'/dvdrip?tab=summary' + prettyPrinter(torrent_infos) + res = res + 1 + if res == 0: + break + i = i + 1 diff --git a/src/searchengine/nova/engines/kickasstorrents.png b/src/searchengine/nova/engines/kickasstorrents.png new file mode 100644 index 0000000000000000000000000000000000000000..7ddc99353881dbc741e1dad0acce65517089f9ec GIT binary patch literal 787 zcmV+u1MK{XP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXf7 z7cwRU6Xi*|XNi}Jiql1rh9B0&dIOkrcgqVI8e>?AWu(Q|0*e8$F^1E|XuVER{uuza7oQ+~>u$VmCta;KR&iT1tSOacg$auR zW<#mEWR@hE_{1%!Y8YEu0RW@UkEmK{IeOmIGcoE|7CQU7@JtTknHWUVDMGNYpvp49 zTp%J`_L*fyJ7!iXRx78gFj@;gJEF+xuLpwwV6B zOl!6_VcI=RVsa+g`TNPp+Jy)Qc~V!k`~ugA_W^*U0mGx-N`EjE5sE-4g7>c*5aA#? zokY;@rKRy28u#1fnQnaUxV~zY0V?cS^*ak}r?lQ;O~YbM#WnB=RbBjtxqw*c>HSmE z(&6k}7XVOkIJ0S6uC+|kt)rOr3-$AN_tBP)p(YK}uN8gk_cR&}`eBn%f6y2$$&pBe zNF>5fr|*|zV0uSer>lGIM*g?#CF$p5&9dF&4WE7aZlrf3&0omuEd`|WoEQKA002ov RPDHLkV1f!D2_PT|APPpGRqFr% literal 0 HcmV?d00001 diff --git a/src/searchengine/nova/engines/kickasstorrents.py b/src/searchengine/nova/engines/kickasstorrents.py new file mode 100755 index 000000000..634113cb4 --- /dev/null +++ b/src/searchengine/nova/engines/kickasstorrents.py @@ -0,0 +1,71 @@ +#VERSION: 1.2 +#AUTHORS: Christophe Dumez (chris@qbittorrent.org) + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + + +from novaprinter import prettyPrinter +from helpers import retrieve_url, download_file +import json + +class kickasstorrents(object): + url = 'http://www.kickasstorrents.com' + name = 'kickasstorrents' + supported_categories = {'all': 'all', 'movies': 'movies', 'tv': 'tv', 'music': 'music', 'games': 'games', 'software': 'applications'} + + def __init__(self): + self.results = [] + + def download_torrent(self, info): + print download_file(info) + + def search(self, what, cat='all'): + ret = [] + i = 1 + while True and i<11: + results = [] + json_data = retrieve_url(self.url+'/search/%s/%d/?categories[]=%s&field=seeders&sorder=desc&json=1'%(what, i, self.supported_categories[cat])) + try: + json_dict = json.loads(json_data) + except: + i += 1 + continue + if json_dict['total_results'] <= 0: return + results = json_dict['list'] + for r in results: + try: + res_dict = dict() + res_dict['name'] = r['title'] + res_dict['size'] = str(r['size']) + res_dict['seeds'] = r['seeds'] + res_dict['leech'] = r['leechs'] + res_dict['link'] = r['torrentLink'] + res_dict['desc_link'] = r['link'] + res_dict['engine_url'] = self.url + prettyPrinter(res_dict) + except: + pass + i += 1 + diff --git a/src/searchengine/nova/engines/mininova.png b/src/searchengine/nova/engines/mininova.png new file mode 100644 index 0000000000000000000000000000000000000000..1513376b66dd7e8e99e33b045c9932e0bd827679 GIT binary patch literal 365 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP`hdjHqtjR3vpFp8so-U3d7N?I+-s^QZL8NW|v*Xhy zxas(o(i_PTskNYV#cU??zny85}S Ib4q9e09Q_ud;kCd literal 0 HcmV?d00001 diff --git a/src/searchengine/nova/engines/mininova.py b/src/searchengine/nova/engines/mininova.py new file mode 100644 index 000000000..5bfd81f42 --- /dev/null +++ b/src/searchengine/nova/engines/mininova.py @@ -0,0 +1,114 @@ +#VERSION: 1.50 +#AUTHORS: Christophe Dumez (chris@qbittorrent.org) + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from novaprinter import prettyPrinter +from helpers import retrieve_url, download_file +import sgmllib +import re + +class mininova(object): + # Mandatory properties + url = 'http://www.mininova.org' + name = 'Mininova' + supported_categories = {'all': '0', 'movies': '4', 'tv': '8', 'music': '5', 'games': '3', 'anime': '1', 'software': '7', 'pictures': '6', 'books': '2'} + + def __init__(self): + self.results = [] + self.parser = self.SimpleSGMLParser(self.results, self.url) + + def download_torrent(self, info): + print download_file(info) + + class SimpleSGMLParser(sgmllib.SGMLParser): + def __init__(self, results, url, *args): + sgmllib.SGMLParser.__init__(self) + self.url = url + self.td_counter = None + self.current_item = None + self.results = results + + def start_a(self, attr): + params = dict(attr) + #print params + if params.has_key('href'): + if params['href'].startswith("/get/"): + self.current_item = {} + self.td_counter = 0 + self.current_item['link']=self.url+params['href'].strip() + elif params['href'].startswith("/tor/"): + self.current_item['desc_link']=self.url+params['href'].strip() + + def handle_data(self, data): + if self.td_counter == 0: + if not self.current_item.has_key('name'): + self.current_item['name'] = '' + self.current_item['name']+= data + elif self.td_counter == 1: + if not self.current_item.has_key('size'): + self.current_item['size'] = '' + self.current_item['size']+= data.strip() + elif self.td_counter == 2: + if not self.current_item.has_key('seeds'): + self.current_item['seeds'] = '' + self.current_item['seeds']+= data.strip() + elif self.td_counter == 3: + if not self.current_item.has_key('leech'): + self.current_item['leech'] = '' + self.current_item['leech']+= data.strip() + + def start_td(self,attr): + if isinstance(self.td_counter,int): + self.td_counter += 1 + if self.td_counter > 4: + self.td_counter = None + # Display item + if self.current_item: + self.current_item['engine_url'] = self.url + if not self.current_item['seeds'].isdigit(): + self.current_item['seeds'] = 0 + if not self.current_item['leech'].isdigit(): + self.current_item['leech'] = 0 + prettyPrinter(self.current_item) + self.results.append('a') + + def search(self, what, cat='all'): + ret = [] + i = 1 + while True and i<11: + results = [] + parser = self.SimpleSGMLParser(results, self.url) + dat = retrieve_url(self.url+'/search/%s/%s/seeds/%d'%(what, self.supported_categories[cat], i)) + results_re = re.compile('(?s)

Search results for.*') + for match in results_re.finditer(dat): + res_tab = match.group(0) + parser.feed(res_tab) + parser.close() + break + if len(results) <= 0: + break + i += 1 + diff --git a/src/searchengine/nova/engines/piratebay.png b/src/searchengine/nova/engines/piratebay.png new file mode 100644 index 0000000000000000000000000000000000000000..3ab97883d3571e609a5278ff37c56d3c040d78d6 GIT binary patch literal 609 zcmV-n0-pVeP)4;^@v00062NklX{L z>+380ih8{sDmM-+yCIQCgb>2>JR!t!8~_M{01@~0_Cmpr0EI%~{r&y!?(XH~Wj>!j zJUqO;y*)lYZjZ-q2jw_U5CqTj+U<5U8ufj@)oN*)7W({~2@#*3p29MbNNjt?Vljqc z0H9i}dY*@fyF0OMJDbh!@9zVED2lG@5<&pr`}=z{!(y>e6vg-bu#+syk|ZUQNdUOG zxR7O;=Xn4)K0anymJmXX$K$K3t4^nLaBz@Lr+J=VtyaG8hfz6>qiLF^=}M*2@As$E zDU-=$CX-3{cgy9HVHio0E-x=jrBbn2JUKa8uh)iQsH)oSb~%othQr}tFwiuu*=&A% zd^|rtTb6Zrc$m-UP1AH;_w4NK^z`)W>&rAvLI{P3rfHs^pC^;aTrPKXbQF)rMNtfb zU_PJgx-JMpxm@n`de_(2_xJaJh>qi=QYl4IY}>}4ux(pa)!W-!0GQ2YhzN-2`~GM& vvMdY#1H&+Cwc6+BCn8e6ob=Akh8O+^O42Py1rH4t00000NkvXXu0mjf8w?xe literal 0 HcmV?d00001 diff --git a/src/searchengine/nova/engines/piratebay.py b/src/searchengine/nova/engines/piratebay.py new file mode 100644 index 000000000..32a57f52c --- /dev/null +++ b/src/searchengine/nova/engines/piratebay.py @@ -0,0 +1,114 @@ +#VERSION: 1.40 +#AUTHORS: Fabien Devaux (fab@gnux.info) +#CONTRIBUTORS: Christophe Dumez (chris@qbittorrent.org) + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from novaprinter import prettyPrinter +import sgmllib +from helpers import retrieve_url, download_file + +class piratebay(object): + url = 'http://thepiratebay.org' + name = 'The Pirate Bay' + supported_categories = {'all': '0', 'movies': '200', 'music': '100', 'games': '400', 'software': '300'} + + def __init__(self): + self.results = [] + self.parser = self.SimpleSGMLParser(self.results, self.url) + + def download_torrent(self, info): + print download_file(info) + + class SimpleSGMLParser(sgmllib.SGMLParser): + def __init__(self, results, url, *args): + sgmllib.SGMLParser.__init__(self) + self.td_counter = None + self.current_item = None + self.results = results + self.url = url + self.code = 0 + self.in_name = None + + def start_a(self, attr): + params = dict(attr) + if params['href'].startswith('/torrent/'): + self.current_item = {} + self.td_counter = 0 + self.code = params['href'].split('/')[2] + self.current_item['desc_link'] = 'http://thepiratebay.org'+params['href'].strip() + self.in_name = True + elif params['href'].startswith('http://torrents.thepiratebay.org/%s'%self.code): + self.current_item['link']=params['href'].strip() + self.in_name = False + + def handle_data(self, data): + if self.td_counter == 0: + if self.in_name: + if not self.current_item.has_key('name'): + self.current_item['name'] = '' + self.current_item['name']+= data.strip() + else: + #Parse size + if 'Size' in data: + self.current_item['size'] = data[data.index("Size")+5:] + self.current_item['size'] = self.current_item['size'][:self.current_item['size'].index(',')] + elif self.td_counter == 1: + if not self.current_item.has_key('seeds'): + self.current_item['seeds'] = '' + self.current_item['seeds']+= data.strip() + elif self.td_counter == 2: + if not self.current_item.has_key('leech'): + self.current_item['leech'] = '' + self.current_item['leech']+= data.strip() + + def start_td(self,attr): + if isinstance(self.td_counter,int): + self.td_counter += 1 + if self.td_counter > 3: + self.td_counter = None + # Display item + if self.current_item: + self.current_item['engine_url'] = self.url + if not self.current_item['seeds'].isdigit(): + self.current_item['seeds'] = 0 + if not self.current_item['leech'].isdigit(): + self.current_item['leech'] = 0 + prettyPrinter(self.current_item) + self.results.append('a') + def search(self, what, cat='all'): + ret = [] + i = 0 + order = 'se' + while True and i<11: + results = [] + parser = self.SimpleSGMLParser(results, self.url) + dat = retrieve_url(self.url+'/search/%s/%u/7/%s' % (what, i, self.supported_categories[cat])) + print self.url+'/search/%s/%u/7/%s' % (what, i, self.supported_categories[cat]) + parser.feed(dat) + parser.close() + if len(results) <= 0: + break + i += 1 diff --git a/src/searchengine/nova/engines/torrentdownloads.png b/src/searchengine/nova/engines/torrentdownloads.png new file mode 100644 index 0000000000000000000000000000000000000000..ce14cea487d289ace537cb4139b8f5080e39ee47 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgga9zJ1R#dR;W-U3Zg_jGX#u{gbS zvcDIzp~TVosbcdEuVw$hbdL428MU*)fpNNzF=Wk_0z3E{OFv^)dlAm8J^`- z)K&OAE92wWdh2>oSx_X$v;5pa%l0N-7daQX+tt4nK2_}6yShe2NchP@OGmjiq0>2y z^qXulm=qSZ24;5$$ug!kEwxT~mht4)I`3W6625Z$-Mm`sRsO7y@P-9lO}FclXQq`I zvN7cJ>S@;pxE|Z}tLN*s%9?pSujBd{vj1w-Uu%k5bFBaS_H(RXnO{}0yj{NJwJ|Uh O89ZJ6T-G@yGywp^OsDMt literal 0 HcmV?d00001 diff --git a/src/searchengine/nova/engines/torrentdownloads.py b/src/searchengine/nova/engines/torrentdownloads.py new file mode 100644 index 000000000..0d0b79591 --- /dev/null +++ b/src/searchengine/nova/engines/torrentdownloads.py @@ -0,0 +1,141 @@ +#VERSION: 1.1 +#AUTHORS: Christophe Dumez (chris@qbittorrent.org) + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + + +from novaprinter import prettyPrinter +from helpers import retrieve_url +import StringIO, gzip, urllib2, tempfile +import sgmllib +import re +import os + +class torrentdownloads(object): + url = 'http://www.torrentdownloads.net' + name = 'TorrentDownloads' + supported_categories = {'all': '0', 'movies': '4', 'tv': '8', 'music': '5', 'games': '3', 'anime': '1', 'software': '7', 'books': '2'} + + def __init__(self): + self.results = [] + #self.parser = self.SimpleSGMLParser(self.results, self.url) + + def download_torrent(self, url): + """ Download file at url and write it to a file, return the path to the file and the url """ + file, path = tempfile.mkstemp() + file = os.fdopen(file, "w") + # Download url + req = urllib2.Request(url) + response = urllib2.urlopen(req) + dat = response.read() + # Check if it is gzipped + if dat[:2] == '\037\213': + # Data is gzip encoded, decode it + compressedstream = StringIO.StringIO(dat) + gzipper = gzip.GzipFile(fileobj=compressedstream) + extracted_data = gzipper.read() + dat = extracted_data + + # Write it to a file + file.write(dat.strip()) + file.close() + # return file path + print path+" "+url + + class SimpleSGMLParser(sgmllib.SGMLParser): + def __init__(self, results, url, what, *args): + sgmllib.SGMLParser.__init__(self) + self.url = url + self.li_counter = None + self.current_item = None + self.results = results + self.what = what.upper().split('+') + if len(self.what) == 0: + self.what = None + + def start_a(self, attr): + params = dict(attr) + #print params + if params.has_key('href') and params['href'].startswith("http://www.torrentdownloads.net/torrent/"): + self.current_item = {} + self.li_counter = 0 + self.current_item['desc_link'] = params['href'].strip() + self.current_item['link']=params['href'].strip().replace('/torrent', '/download', 1) + + def handle_data(self, data): + if self.li_counter == 0: + if not self.current_item.has_key('name'): + self.current_item['name'] = '' + self.current_item['name']+= data + elif self.li_counter == 1: + if not self.current_item.has_key('size'): + self.current_item['size'] = '' + self.current_item['size']+= data.strip().replace(" ", " ") + elif self.li_counter == 2: + if not self.current_item.has_key('seeds'): + self.current_item['seeds'] = '' + self.current_item['seeds']+= data.strip() + elif self.li_counter == 3: + if not self.current_item.has_key('leech'): + self.current_item['leech'] = '' + self.current_item['leech']+= data.strip() + + def start_li(self,attr): + if isinstance(self.li_counter,int): + self.li_counter += 1 + if self.li_counter > 3: + self.li_counter = None + # Display item + if self.current_item: + self.current_item['engine_url'] = self.url + if not self.current_item['seeds'].isdigit(): + self.current_item['seeds'] = 0 + if not self.current_item['leech'].isdigit(): + self.current_item['leech'] = 0 + # Search should use AND operator as a default + tmp = self.current_item['name'].upper(); + if self.what is not None: + for w in self.what: + if tmp.find(w) < 0: return + prettyPrinter(self.current_item) + self.results.append('a') + + def search(self, what, cat='all'): + ret = [] + i = 1 + while i<11: + results = [] + parser = self.SimpleSGMLParser(results, self.url, what) + dat = retrieve_url(self.url+'/search/?page=%d&search=%s&s_cat=%s&srt=seeds&pp=50&order=desc'%(i, what, self.supported_categories[cat])) + results_re = re.compile('(?s)
.*') + for match in results_re.finditer(dat): + res_tab = match.group(0) + parser.feed(res_tab) + parser.close() + break + if len(results) <= 0: + break + i += 1 + diff --git a/src/searchengine/nova/engines/torrentreactor.png b/src/searchengine/nova/engines/torrentreactor.png new file mode 100644 index 0000000000000000000000000000000000000000..480c0b32e309093c46a31f61d36771d84dd3987a GIT binary patch literal 529 zcmV+s0`C2ZP)yvXtq_B{tDFBnn1fa}qnW57$ zesqjIep;xSjtQe7HDL4dEi4ubcXu~4?{qre@Auu^J?ZP50mdHHP6c7NCO z`F!pg#}S*&HOu94S7v_0&E~q&+E$I36*Eu`#PNP(9vu`7z-ImjfcV#U!f1#e9g`$U ziC4yf7aNe@KY4WVVh3A4e+3$dR72$*s0KuJuf96#VNae>PZHb=-5yE^QPm}tYg?W5 z3JX`4)RP3ubKD&j5kzF~!bAk_l<9O#t 3: + self.td_counter = None + # add item to results + if self.current_item: + self.current_item['engine_url'] = self.url + if not self.current_item['seeds'].isdigit(): + self.current_item['seeds'] = 0 + if not self.current_item['leech'].isdigit(): + self.current_item['leech'] = 0 + prettyPrinter(self.current_item) + self.has_results = True + self.results.append('a') + + def __init__(self): + self.results = [] + self.parser = self.SimpleSGMLParser(self.results, self.url) + + def search(self, what, cat='all'): + i = 0 + while True and i<11: + results = [] + parser = self.SimpleSGMLParser(results, self.url) + dat = retrieve_url(self.url+'/search.php?search=&words=%s&cid=%s&sid=&type=1&orderby=a.seeds&asc=0&skip=%s'%(what, self.supported_categories[cat], (i*35))) + parser.feed(dat) + parser.close() + if len(results) <= 0: + break + i += 1 diff --git a/src/searchengine/nova/engines/versions.txt b/src/searchengine/nova/engines/versions.txt new file mode 100644 index 000000000..08d74f646 --- /dev/null +++ b/src/searchengine/nova/engines/versions.txt @@ -0,0 +1,10 @@ +isohunt: 1.4 +torrentreactor: 1.31 +btjunkie: 2.31 +mininova: 1.50 +piratebay: 1.40 +vertor: 1.3 +torrentdownloads: 1.1 +extratorrent: 1.1 +kickasstorrents: 1.2 +btdigg: 1.1 diff --git a/src/searchengine/nova/engines/vertor.png b/src/searchengine/nova/engines/vertor.png new file mode 100644 index 0000000000000000000000000000000000000000..f9975f508bb42ca0e328fe3175c20491c43e998c GIT binary patch literal 643 zcmV-}0(||6P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXf7 z6Brt3GXU z0I$HC@ETmZaN)|tt*sxix{-oJt3_yvEm#K2R2V*_z__3p90#4%n=|kE<(zk(5gu(l z(2~JB1YHpTN@{`iy(f%&!tOZN=57J-qy3%d-yUN<>Qvb%KjUunJ^=M@ji>pCV}YCD zdphv(@GaF=2@zmZexWyo+%e{-mQ0(iqQuJV4FEJWveh>LL!hJLk@e)(0Tw zUuIJB7=SA?NxjZgU+J|D_>;`Ay2Kf5(PoW%FPK&RK#V=5qE5r>D|R#LQks`(!QSPkAbEVhqT`dS~$$!7$p dwo9fyfZx~Nxu{`V$ZP-r002ovPDHLkV1gdb5O@Fp literal 0 HcmV?d00001 diff --git a/src/searchengine/nova/engines/vertor.py b/src/searchengine/nova/engines/vertor.py new file mode 100755 index 000000000..bca604416 --- /dev/null +++ b/src/searchengine/nova/engines/vertor.py @@ -0,0 +1,129 @@ +#VERSION: 1.3 +#AUTHORS: Christophe Dumez (chris@qbittorrent.org) + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + + +from novaprinter import prettyPrinter +from helpers import retrieve_url, download_file +import sgmllib +import re + +class vertor(object): + url = 'http://www.vertor.com' + name = 'vertor' + supported_categories = {'all': '0', 'movies': '5', 'tv': '8', 'music': '6', 'games': '3', 'anime': '1', 'software': '2'} + + def __init__(self): + self.results = [] + self.parser = self.SimpleSGMLParser(self.results, self.url) + + def download_torrent(self, info): + print download_file(info) + + class SimpleSGMLParser(sgmllib.SGMLParser): + def __init__(self, results, url, *args): + sgmllib.SGMLParser.__init__(self) + self.url = url + self.td_counter = None + self.current_item = None + self.results = results + self.in_name = False + self.outside_td = True; + + def start_tr(self, attr): + self.td_counter = -1 + self.current_item = {} + + def end_tr(self): + if self.td_counter == 5: + self.td_counter = None + # Display item + if self.current_item and self.current_item.has_key('link'): + self.current_item['engine_url'] = self.url + if not self.current_item['seeds'].isdigit(): + self.current_item['seeds'] = 0 + if not self.current_item['leech'].isdigit(): + self.current_item['leech'] = 0 + prettyPrinter(self.current_item) + self.results.append('a') + + def start_a(self, attr): + #if self.td_counter is None or self.td_counter < 0: return + params = dict(attr) + if params.has_key('href') and params['href'].startswith("http://www.vertor.com/index.php?mod=download"): + self.current_item['link']=params['href'].strip() + elif self.td_counter == 0 and params.has_key('href') and params['href'].startswith("/torrents/") \ + and not self.current_item.has_key('name'): + self.current_item['desc_link']='http://www.vertor.com'+params['href'].strip() + self.in_name = True + + def end_a(self): + if self.in_name: + self.in_name = False + + def handle_data(self, data): + if self.in_name: + if not self.current_item.has_key('name'): + self.current_item['name'] = '' + self.current_item['name']+= data.strip() + elif self.td_counter == 2 and not self.outside_td: + if not self.current_item.has_key('size'): + self.current_item['size'] = '' + self.current_item['size']+= data.strip() + elif self.td_counter == 4 and not self.outside_td: + if not self.current_item.has_key('seeds'): + self.current_item['seeds'] = '' + self.current_item['seeds']+= data.strip() + elif self.td_counter == 5 and not self.outside_td: + if not self.current_item.has_key('leech'): + self.current_item['leech'] = '' + self.current_item['leech']+= data.strip() + + def end_td(self): + self.outside_td = True + + def start_td(self,attr): + if isinstance(self.td_counter,int): + self.outside_td = False + self.td_counter += 1 + + def search(self, what, cat='all'): + ret = [] + i = 0 + while True and i<11: + results = [] + parser = self.SimpleSGMLParser(results, self.url) + dat = retrieve_url(self.url+'/index.php?mod=search&words=%s&cid=%s&orderby=a.seeds&asc=0&search=&exclude=&p=%d'%(what, self.supported_categories[cat], i)) + results_re = re.compile('(?s)

.*') + for match in results_re.finditer(dat): + res_tab = match.group(0) + parser.feed(res_tab) + parser.close() + break + if len(results) <= 0: + break + i += 1 + diff --git a/src/searchengine/nova/helpers.py b/src/searchengine/nova/helpers.py new file mode 100644 index 000000000..97a30974c --- /dev/null +++ b/src/searchengine/nova/helpers.py @@ -0,0 +1,99 @@ +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +#VERSION: 1.31 + +# Author: +# Christophe DUMEZ (chris@qbittorrent.org) + +import re, htmlentitydefs +import tempfile +import os +import StringIO, gzip, urllib2 +import socket +import socks +import re + +# SOCKS5 Proxy support +if os.environ.has_key("sock_proxy") and len(os.environ["sock_proxy"].strip()) > 0: + proxy_str = os.environ["sock_proxy"].strip() + m=re.match(r"^(?:(?P[^:]+):(?P[^@]+)@)?(?P[^:]+):(?P\w+)$", proxy_str) + if m is not None: + socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, m.group('host'), int(m.group('port')), True, m.group('username'), m.group('password')) + socket.socket = socks.socksocket + +def htmlentitydecode(s): + # First convert alpha entities (such as é) + # (Inspired from http://mail.python.org/pipermail/python-list/2007-June/443813.html) + def entity2char(m): + entity = m.group(1) + if entity in htmlentitydefs.name2codepoint: + return unichr(htmlentitydefs.name2codepoint[entity]) + return u" " # Unknown entity: We replace with a space. + t = re.sub(u'&(%s);' % u'|'.join(htmlentitydefs.name2codepoint), entity2char, s) + + # Then convert numerical entities (such as é) + t = re.sub(u'&#(\d+);', lambda x: unichr(int(x.group(1))), t) + + # Then convert hexa entities (such as é) + return re.sub(u'&#x(\w+);', lambda x: unichr(int(x.group(1),16)), t) + +def retrieve_url(url): + """ Return the content of the url page as a string """ + req = urllib2.Request(url) + response = urllib2.urlopen(req) + dat = response.read() + info = response.info() + charset = 'utf-8' + try: + ignore, charset = info['Content-Type'].split('charset=') + except: + pass + dat = dat.decode(charset, 'replace') + dat = htmlentitydecode(dat) + return dat.encode('utf-8', 'replace') + +def download_file(url, referer=None): + """ Download file at url and write it to a file, return the path to the file and the url """ + file, path = tempfile.mkstemp() + file = os.fdopen(file, "w") + # Download url + req = urllib2.Request(url) + if referer is not None: + req.add_header('referer', referer) + response = urllib2.urlopen(req) + dat = response.read() + # Check if it is gzipped + if dat[:2] == '\037\213': + # Data is gzip encoded, decode it + compressedstream = StringIO.StringIO(dat) + gzipper = gzip.GzipFile(fileobj=compressedstream) + extracted_data = gzipper.read() + dat = extracted_data + + # Write it to a file + file.write(dat) + file.close() + # return file path + return path+" "+url diff --git a/src/searchengine/nova/nova2.py b/src/searchengine/nova/nova2.py new file mode 100755 index 000000000..5d75642bb --- /dev/null +++ b/src/searchengine/nova/nova2.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + + +#VERSION: 1.23 + +# Author: +# Fabien Devaux +# Contributors: +# Christophe Dumez (qbittorrent integration) +# Thanks to gab #gcu @ irc.freenode.net (multipage support on PirateBay) +# Thanks to Elias (torrentreactor and isohunt search engines) +# +# Licence: BSD + +import sys +import threading +import os +import glob + +THREADED = True +CATEGORIES = ('all', 'movies', 'tv', 'music', 'games', 'anime', 'software', 'pictures', 'books') + +################################################################################ +# Every engine should have a "search" method taking +# a space-free string as parameter (ex. "family+guy") +# it should call prettyPrinter() with a dict as parameter. +# The keys in the dict must be: link,name,size,seeds,leech,engine_url +# As a convention, try to list results by decrasing number of seeds or similar +################################################################################ + +supported_engines = [] + +engines = glob.glob(os.path.join(os.path.dirname(__file__), 'engines','*.py')) +for engine in engines: + e = engine.split(os.sep)[-1][:-3] + if len(e.strip()) == 0: continue + if e.startswith('_'): continue + try: + exec "from engines.%s import %s"%(e,e) + supported_engines.append(e) + except: + pass + +def engineToXml(short_name): + xml = "<%s>\n"%short_name + exec "engine = %s()"%short_name + xml += "%s\n"%engine.name + xml += "%s\n"%engine.url + xml += "" + if hasattr(engine, 'supported_categories'): + supported_categories = engine.supported_categories.keys() + supported_categories.remove('all') + xml += " ".join(supported_categories) + xml += "\n" + xml += "\n"%short_name + return xml + +def displayCapabilities(): + """ + Display capabilities in XML format + + + long name + http://example.com + movies music games + + + """ + xml = "" + for short_name in supported_engines: + xml += engineToXml(short_name) + xml += "" + print xml + +class EngineLauncher(threading.Thread): + def __init__(self, engine, what, cat='all'): + threading.Thread.__init__(self) + self.engine = engine + self.what = what + self.cat = cat + def run(self): + if hasattr(self.engine, 'supported_categories'): + if self.cat == 'all' or self.cat in self.engine.supported_categories.keys(): + self.engine.search(self.what, self.cat) + elif self.cat == 'all': + self.engine.search(self.what) + +if __name__ == '__main__': + if len(sys.argv) < 2: + raise SystemExit('./nova2.py [all|engine1[,engine2]*] \navailable engines: %s'% + (','.join(supported_engines))) + + if len(sys.argv) == 2: + if sys.argv[1] == "--capabilities": + displayCapabilities() + sys.exit(0) + else: + raise SystemExit('./nova.py [all|engine1[,engine2]*] \navailable engines: %s'% + (','.join(supported_engines))) + + engines_list = [e.lower() for e in sys.argv[1].strip().split(',')] + + if 'all' in engines_list: + engines_list = supported_engines + + cat = sys.argv[2].lower() + + if cat not in CATEGORIES: + raise SystemExit('Invalid category!') + + what = '+'.join(sys.argv[3:]) + + threads = [] + for engine in engines_list: + try: + if THREADED: + exec "l = EngineLauncher(%s(), what, cat)"%engine + threads.append(l) + l.start() + else: + exec "e = %s()"%engine + if hasattr(engine, 'supported_categories'): + if cat == 'all' or cat in e.supported_categories.keys(): + e.search(what, cat) + elif self.cat == 'all': + e.search(what) + engine().search(what, cat) + except: + pass + if THREADED: + for t in threads: + t.join() diff --git a/src/searchengine/nova/nova2dl.py b/src/searchengine/nova/nova2dl.py new file mode 100755 index 000000000..e0c2c2cd6 --- /dev/null +++ b/src/searchengine/nova/nova2dl.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +#VERSION: 1.10 + +# Author: +# Christophe DUMEZ (chris@qbittorrent.org) + +import sys +import os +import glob +from helpers import download_file + +supported_engines = dict() + +engines = glob.glob(os.path.join(os.path.dirname(__file__), 'engines','*.py')) +for engine in engines: + e = engine.split(os.sep)[-1][:-3] + if len(e.strip()) == 0: continue + if e.startswith('_'): continue + try: + exec "from engines.%s import %s"%(e,e) + exec "engine_url = %s.url"%e + supported_engines[engine_url] = e + except: + pass + +if __name__ == '__main__': + if len(sys.argv) < 3: + raise SystemExit('./nova2dl.py engine_url download_parameter') + engine_url = sys.argv[1].strip() + download_param = sys.argv[2].strip() + if engine_url not in supported_engines.keys(): + raise SystemExit('./nova2dl.py: this engine_url was not recognized') + exec "engine = %s()"%supported_engines[engine_url] + if hasattr(engine, 'download_torrent'): + engine.download_torrent(download_param) + else: + print download_file(download_param) + sys.exit(0) \ No newline at end of file diff --git a/src/searchengine/nova/novaprinter.py b/src/searchengine/nova/novaprinter.py new file mode 100644 index 000000000..848f932fa --- /dev/null +++ b/src/searchengine/nova/novaprinter.py @@ -0,0 +1,69 @@ +#VERSION: 1.43 + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import sys, codecs + +# Force UTF-8 printing +sys.stdout = codecs.getwriter('utf-8')(sys.stdout) + +def prettyPrinter(dictionary): + # Convert everything to unicode for safe printing + for key,value in dictionary.items(): + if isinstance(dictionary[key], str): + dictionary[key] = unicode(dictionary[key], 'utf-8') + dictionary['size'] = anySizeToBytes(dictionary['size']) + if dictionary.has_key('desc_link'): + print u"%s|%s|%s|%s|%s|%s|%s"%(dictionary['link'],dictionary['name'].replace('|',' '),dictionary['size'],dictionary['seeds'],dictionary['leech'],dictionary['engine_url'],dictionary['desc_link']) + else: + print u"%s|%s|%s|%s|%s|%s"%(dictionary['link'],dictionary['name'].replace('|',' '),dictionary['size'],dictionary['seeds'],dictionary['leech'],dictionary['engine_url']) + +def anySizeToBytes(size_string): + """ + Convert a string like '1 KB' to '1024' (bytes) + """ + # separate integer from unit + try: + size, unit = size_string.split() + except: + try: + size = size_string.strip() + unit = ''.join([c for c in size if c.isalpha()]) + if len(unit) > 0: + size = size[:-len(unit)] + except: + return -1 + if len(size) == 0: + return -1 + size = float(size) + if len(unit) == 0: + return int(size) + short_unit = unit.upper()[0] + + # convert + units_dict = { 'T': 40, 'G': 30, 'M': 20, 'K': 10 } + if units_dict.has_key( short_unit ): + size = size * 2**units_dict[short_unit] + return int(size) diff --git a/src/searchengine/nova/socks.py b/src/searchengine/nova/socks.py new file mode 100644 index 000000000..c4fe83f40 --- /dev/null +++ b/src/searchengine/nova/socks.py @@ -0,0 +1,391 @@ +"""SocksiPy - Python SOCKS module. +Version 1.01 + +Copyright 2006 Dan-Haim. All rights reserved. +Various fixes by Christophe DUMEZ - 2010 + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +3. Neither the name of Dan Haim nor the names of his contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY DAN HAIM "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL DAN HAIM OR HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMANGE. + + +This module provides a standard socket-like interface for Python +for tunneling connections through SOCKS proxies. + +""" + +import socket +import struct + +PROXY_TYPE_SOCKS4 = 1 +PROXY_TYPE_SOCKS5 = 2 +PROXY_TYPE_HTTP = 3 + +_defaultproxy = None +_orgsocket = socket.socket + +class ProxyError(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + +class GeneralProxyError(ProxyError): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + +class Socks5AuthError(ProxyError): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + +class Socks5Error(ProxyError): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + +class Socks4Error(ProxyError): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + +class HTTPError(ProxyError): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + +_generalerrors = ("success", + "invalid data", + "not connected", + "not available", + "bad proxy type", + "bad input") + +_socks5errors = ("succeeded", + "general SOCKS server failure", + "connection not allowed by ruleset", + "Network unreachable", + "Host unreachable", + "Connection refused", + "TTL expired", + "Command not supported", + "Address type not supported", + "Unknown error") + +_socks5autherrors = ("succeeded", + "authentication is required", + "all offered authentication methods were rejected", + "unknown username or invalid password", + "unknown error") + +_socks4errors = ("request granted", + "request rejected or failed", + "request rejected because SOCKS server cannot connect to identd on the client", + "request rejected because the client program and identd report different user-ids", + "unknown error") + +def setdefaultproxy(proxytype=None,addr=None,port=None,rdns=True,username=None,password=None): + """setdefaultproxy(proxytype, addr[, port[, rdns[, username[, password]]]]) + Sets a default proxy which all further socksocket objects will use, + unless explicitly changed. + """ + global _defaultproxy + _defaultproxy = (proxytype,addr,port,rdns,username,password) + +class socksocket(socket.socket): + """socksocket([family[, type[, proto]]]) -> socket object + + Open a SOCKS enabled socket. The parameters are the same as + those of the standard socket init. In order for SOCKS to work, + you must specify family=AF_INET, type=SOCK_STREAM and proto=0. + """ + + def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None): + _orgsocket.__init__(self,family,type,proto,_sock) + if _defaultproxy != None: + self.__proxy = _defaultproxy + else: + self.__proxy = (None, None, None, None, None, None) + self.__proxysockname = None + self.__proxypeername = None + + def __recvall(self, bytes): + """__recvall(bytes) -> data + Receive EXACTLY the number of bytes requested from the socket. + Blocks until the required number of bytes have been received. + """ + data = "" + while len(data) < bytes: + d = self.recv(bytes-len(data)) + if not d: + raise GeneralProxyError("connection closed unexpectedly") + data = data + d + return data + + def setproxy(self,proxytype=None,addr=None,port=None,rdns=True,username=None,password=None): + """setproxy(proxytype, addr[, port[, rdns[, username[, password]]]]) + Sets the proxy to be used. + proxytype - The type of the proxy to be used. Three types + are supported: PROXY_TYPE_SOCKS4 (including socks4a), + PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP + addr - The address of the server (IP or DNS). + port - The port of the server. Defaults to 1080 for SOCKS + servers and 8080 for HTTP proxy servers. + rdns - Should DNS queries be preformed on the remote side + (rather than the local side). The default is True. + Note: This has no effect with SOCKS4 servers. + username - Username to authenticate with to the server. + The default is no authentication. + password - Password to authenticate with to the server. + Only relevant when username is also provided. + """ + self.__proxy = (proxytype,addr,port,rdns,username,password) + + def __negotiatesocks5(self,destaddr,destport): + """__negotiatesocks5(self,destaddr,destport) + Negotiates a connection through a SOCKS5 server. + """ + # First we'll send the authentication packages we support. + if (self.__proxy[4]!=None) and (self.__proxy[5]!=None): + # The username/password details were supplied to the + # setproxy method so we support the USERNAME/PASSWORD + # authentication (in addition to the standard none). + self.sendall("\x05\x02\x00\x02") + else: + # No username/password were entered, therefore we + # only support connections with no authentication. + self.sendall("\x05\x01\x00") + # We'll receive the server's response to determine which + # method was selected + chosenauth = self.__recvall(2) + if chosenauth[0] != "\x05": + self.close() + raise GeneralProxyError((1,_generalerrors[1])) + # Check the chosen authentication method + if chosenauth[1] == "\x00": + # No authentication is required + pass + elif chosenauth[1] == "\x02": + # Okay, we need to perform a basic username/password + # authentication. + self.sendall("\x01" + chr(len(self.__proxy[4])) + self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5]) + authstat = self.__recvall(2) + if authstat[0] != "\x01": + # Bad response + self.close() + raise GeneralProxyError((1,_generalerrors[1])) + if authstat[1] != "\x00": + # Authentication failed + self.close() + raise Socks5AuthError,((3,_socks5autherrors[3])) + # Authentication succeeded + else: + # Reaching here is always bad + self.close() + if chosenauth[1] == "\xFF": + raise Socks5AuthError((2,_socks5autherrors[2])) + else: + raise GeneralProxyError((1,_generalerrors[1])) + # Now we can request the actual connection + req = "\x05\x01\x00" + # If the given destination address is an IP address, we'll + # use the IPv4 address request even if remote resolving was specified. + try: + ipaddr = socket.inet_aton(destaddr) + req = req + "\x01" + ipaddr + except socket.error: + # Well it's not an IP number, so it's probably a DNS name. + if self.__proxy[3]==True: + # Resolve remotely + ipaddr = None + req = req + "\x03" + chr(len(destaddr)) + destaddr + else: + # Resolve locally + ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) + req = req + "\x01" + ipaddr + req = req + struct.pack(">H",destport) + self.sendall(req) + # Get the response + resp = self.__recvall(4) + if resp[0] != "\x05": + self.close() + raise GeneralProxyError((1,_generalerrors[1])) + elif resp[1] != "\x00": + # Connection failed + self.close() + if ord(resp[1])<=8: + raise Socks5Error((ord(resp[1]),_generalerrors[ord(resp[1])])) + else: + raise Socks5Error((9,_generalerrors[9])) + # Get the bound address/port + elif resp[3] == "\x01": + boundaddr = self.__recvall(4) + elif resp[3] == "\x03": + resp = resp + self.recv(1) + boundaddr = self.__recvall(ord(resp[4])) + else: + self.close() + raise GeneralProxyError((1,_generalerrors[1])) + boundport = struct.unpack(">H",self.__recvall(2))[0] + self.__proxysockname = (boundaddr,boundport) + if ipaddr != None: + self.__proxypeername = (socket.inet_ntoa(ipaddr),destport) + else: + self.__proxypeername = (destaddr,destport) + + def getproxysockname(self): + """getsockname() -> address info + Returns the bound IP address and port number at the proxy. + """ + return self.__proxysockname + + def getproxypeername(self): + """getproxypeername() -> address info + Returns the IP and port number of the proxy. + """ + return _orgsocket.getpeername(self) + + def getpeername(self): + """getpeername() -> address info + Returns the IP address and port number of the destination + machine (note: getproxypeername returns the proxy) + """ + return self.__proxypeername + + def __negotiatesocks4(self,destaddr,destport): + """__negotiatesocks4(self,destaddr,destport) + Negotiates a connection through a SOCKS4 server. + """ + # Check if the destination address provided is an IP address + rmtrslv = False + try: + ipaddr = socket.inet_aton(destaddr) + except socket.error: + # It's a DNS name. Check where it should be resolved. + if self.__proxy[3]==True: + ipaddr = "\x00\x00\x00\x01" + rmtrslv = True + else: + ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) + # Construct the request packet + req = "\x04\x01" + struct.pack(">H",destport) + ipaddr + # The username parameter is considered userid for SOCKS4 + if self.__proxy[4] != None: + req = req + self.__proxy[4] + req = req + "\x00" + # DNS name if remote resolving is required + # NOTE: This is actually an extension to the SOCKS4 protocol + # called SOCKS4A and may not be supported in all cases. + if rmtrslv==True: + req = req + destaddr + "\x00" + self.sendall(req) + # Get the response from the server + resp = self.__recvall(8) + if resp[0] != "\x00": + # Bad data + self.close() + raise GeneralProxyError((1,_generalerrors[1])) + if resp[1] != "\x5A": + # Server returned an error + self.close() + if ord(resp[1]) in (91,92,93): + self.close() + raise Socks4Error((ord(resp[1]),_socks4errors[ord(resp[1])-90])) + else: + raise Socks4Error((94,_socks4errors[4])) + # Get the bound address/port + self.__proxysockname = (socket.inet_ntoa(resp[4:]),struct.unpack(">H",resp[2:4])[0]) + if rmtrslv != None: + self.__proxypeername = (socket.inet_ntoa(ipaddr),destport) + else: + self.__proxypeername = (destaddr,destport) + + def __negotiatehttp(self,destaddr,destport): + """__negotiatehttp(self,destaddr,destport) + Negotiates a connection through an HTTP server. + """ + # If we need to resolve locally, we do this now + if self.__proxy[3] == False: + addr = socket.gethostbyname(destaddr) + else: + addr = destaddr + self.sendall("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n") + # We read the response until we get the string "\r\n\r\n" + resp = self.recv(1) + while resp.find("\r\n\r\n")==-1: + resp = resp + self.recv(1) + # We just need the first line to check if the connection + # was successful + statusline = resp.splitlines()[0].split(" ",2) + if statusline[0] not in ("HTTP/1.0","HTTP/1.1"): + self.close() + raise GeneralProxyError((1,_generalerrors[1])) + try: + statuscode = int(statusline[1]) + except ValueError: + self.close() + raise GeneralProxyError((1,_generalerrors[1])) + if statuscode != 200: + self.close() + raise HTTPError((statuscode,statusline[2])) + self.__proxysockname = ("0.0.0.0",0) + self.__proxypeername = (addr,destport) + + def connect(self,destpair): + """connect(self,despair) + Connects to the specified destination through a proxy. + destpar - A tuple of the IP/DNS address and the port number. + (identical to socket's connect). + To select the proxy server use setproxy(). + """ + # Do a minimal input check first + if (type(destpair) in (list,tuple)==False) or (len(destpair)<2) or (type(destpair[0])!=str) or (type(destpair[1])!=int): + raise GeneralProxyError((5,_generalerrors[5])) + if self.__proxy[0] == PROXY_TYPE_SOCKS5: + if self.__proxy[2] != None: + portnum = self.__proxy[2] + else: + portnum = 1080 + _orgsocket.connect(self,(self.__proxy[1],portnum)) + self.__negotiatesocks5(destpair[0],destpair[1]) + elif self.__proxy[0] == PROXY_TYPE_SOCKS4: + if self.__proxy[2] != None: + portnum = self.__proxy[2] + else: + portnum = 1080 + _orgsocket.connect(self,(self.__proxy[1],portnum)) + self.__negotiatesocks4(destpair[0],destpair[1]) + elif self.__proxy[0] == PROXY_TYPE_HTTP: + if self.__proxy[2] != None: + portnum = self.__proxy[2] + else: + portnum = 8080 + _orgsocket.connect(self,(self.__proxy[1],portnum)) + self.__negotiatehttp(destpair[0],destpair[1]) + elif self.__proxy[0] == None: + _orgsocket.connect(self,(destpair[0],destpair[1])) + else: + raise GeneralProxyError((4,_generalerrors[4])) diff --git a/src/searchengine/pluginsource.h b/src/searchengine/pluginsource.h new file mode 100644 index 000000000..514a3ea71 --- /dev/null +++ b/src/searchengine/pluginsource.h @@ -0,0 +1,65 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PLUGIN_SOURCE_H +#define PLUGIN_SOURCE_H + +#include +#include "ui_pluginsource.h" + +class pluginSourceDlg: public QDialog, private Ui::pluginSourceDlg { + Q_OBJECT + + signals: + void askForUrl(); + void askForLocalFile(); + + protected slots: + void on_localButton_clicked() { + emit askForLocalFile(); + close(); + } + + void on_urlButton_clicked() { + emit askForUrl(); + close(); + } + + public: + pluginSourceDlg(QWidget* parent): QDialog(parent){ + setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + show(); + } + + ~pluginSourceDlg(){} +}; + +#endif diff --git a/src/searchengine/pluginsource.ui b/src/searchengine/pluginsource.ui new file mode 100644 index 000000000..ecfcbc49c --- /dev/null +++ b/src/searchengine/pluginsource.ui @@ -0,0 +1,52 @@ + + pluginSourceDlg + + + + 0 + 0 + 207 + 76 + + + + Plugin source + + + + + + + 75 + true + true + + + + Search plugin source: + + + + + + + + + Local file + + + + + + + Web link + + + + + + + + + + diff --git a/src/searchengine/search.qrc b/src/searchengine/search.qrc new file mode 100644 index 000000000..03f94024e --- /dev/null +++ b/src/searchengine/search.qrc @@ -0,0 +1,29 @@ + + + nova/nova2.py + nova/novaprinter.py + nova/socks.py + nova/nova2dl.py + nova/helpers.py + nova/engines/vertor.png + nova/engines/kickasstorrents.png + nova/engines/mininova.png + nova/engines/mininova.py + nova/engines/torrentdownloads.png + nova/engines/isohunt.png + nova/engines/torrentreactor.py + nova/engines/btjunkie.png + nova/engines/extratorrent.py + nova/engines/piratebay.py + nova/engines/torrentdownloads.py + nova/engines/torrentreactor.png + nova/engines/isohunt.py + nova/engines/btdigg.py + nova/engines/btjunkie.py + nova/engines/kickasstorrents.py + nova/engines/extratorrent.png + nova/engines/piratebay.png + nova/engines/vertor.py + nova/engines/btdigg.png + + \ No newline at end of file diff --git a/src/searchengine/search.ui b/src/searchengine/search.ui new file mode 100644 index 000000000..c5de22c97 --- /dev/null +++ b/src/searchengine/search.ui @@ -0,0 +1,194 @@ + + + search_engine + + + + 0 + 0 + 820 + 453 + + + + Search + + + + + + + + + 16777215 + 22 + + + + Qt::CustomContextMenu + + + + + + + + + + + 16777215 + 29 + + + + Search + + + + + + + + + + + + 16777215 + 35 + + + + + 75 + true + + + + Status: + + + + + + + + 200 + 0 + + + + + 16777215 + 35 + + + + + true + + + + Stopped + + + + + + + Qt::Horizontal + + + + 188 + 21 + + + + + + + + + + + + + 6 + + + 0 + + + + + 6 + + + 0 + + + + + false + + + Download + + + + + + + false + + + Go to description page + + + + + + + Qt::Horizontal + + + + 601 + 20 + + + + + + + + Search engines... + + + + + + + + + + + + + search_pattern + returnPressed() + search_button + click() + + + 421 + 37 + + + 685 + 45 + + + + + diff --git a/src/searchengine/searchengine.cpp b/src/searchengine/searchengine.cpp new file mode 100644 index 000000000..913131348 --- /dev/null +++ b/src/searchengine/searchengine.cpp @@ -0,0 +1,735 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_WS_WIN +#include +#endif + +#include "searchengine.h" +#include "qbtsession.h" +#include "downloadthread.h" +#include "misc.h" +#include "preferences.h" +#include "searchlistdelegate.h" +#include "qinisettings.h" +#include "mainwindow.h" +#include "iconprovider.h" + +#define SEARCHHISTORY_MAXSIZE 50 + +/*SEARCH ENGINE START*/ +SearchEngine::SearchEngine(MainWindow *parent) : QWidget(parent), mp_mainWindow(parent) { + setupUi(this); + // Icons + search_button->setIcon(IconProvider::instance()->getIcon("edit-find")); + download_button->setIcon(IconProvider::instance()->getIcon("download")); + goToDescBtn->setIcon(IconProvider::instance()->getIcon("application-x-mswinurl")); + enginesButton->setIcon(IconProvider::instance()->getIcon("preferences-system-network")); + // new qCompleter to the search pattern + startSearchHistory(); + createCompleter(); +#if (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) + tabWidget->setTabsClosable(true); + connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); +#else + // Add close tab button + closeTab_button = new QPushButton(); + closeTab_button->setIcon(IconProvider::instance()->getIcon("tab-close")); + closeTab_button->setFlat(true); + tabWidget->setCornerWidget(closeTab_button); + connect(closeTab_button, SIGNAL(clicked()), this, SLOT(closeTab_button_clicked())); +#endif + // Boolean initialization + search_stopped = false; + // Creating Search Process +#ifdef Q_WS_WIN + has_python = addPythonPathToEnv(); +#endif + searchProcess = new QProcess(this); + searchProcess->setEnvironment(QProcess::systemEnvironment()); + connect(searchProcess, SIGNAL(started()), this, SLOT(searchStarted())); + connect(searchProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readSearchOutput())); + connect(searchProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(searchFinished(int,QProcess::ExitStatus))); + connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tab_changed(int))); + searchTimeout = new QTimer(this); + searchTimeout->setSingleShot(true); + connect(searchTimeout, SIGNAL(timeout()), this, SLOT(on_search_button_clicked())); + // Update nova.py search plugin if necessary + updateNova(); + supported_engines = new SupportedEngines( + #ifdef Q_WS_WIN + has_python + #endif + ); + // Fill in category combobox + fillCatCombobox(); + connect(search_pattern, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(displayPatternContextMenu(QPoint))); + connect(search_pattern, SIGNAL(textEdited(QString)), this, SLOT(searchTextEdited(QString))); +} + +void SearchEngine::fillCatCombobox() { + comboCategory->clear(); + comboCategory->addItem(full_cat_names["all"], QVariant("all")); + QStringList supported_cat = supported_engines->supportedCategories(); + foreach(QString cat, supported_cat) { + qDebug("Supported category: %s", qPrintable(cat)); + comboCategory->addItem(full_cat_names[cat], QVariant(cat)); + } +} + +#ifdef Q_WS_WIN +bool SearchEngine::addPythonPathToEnv() { + QString python_path = Preferences::getPythonPath(); + if(!python_path.isEmpty()) { + // Add it to PATH envvar + QString path_envar = QString::fromLocal8Bit(getenv("PATH")); + if(path_envar.isNull()) { + path_envar = ""; + } + path_envar = python_path+";"+path_envar; + qDebug("New PATH envvar is: %s", qPrintable(path_envar)); + QString envar = "PATH="+path_envar; + putenv(envar.toLocal8Bit().data()); + return true; + } + return false; +} + +void SearchEngine::installPython() { + setCursor(QCursor(Qt::WaitCursor)); + // Download python + DownloadThread *pydownloader = new DownloadThread(this); + connect(pydownloader, SIGNAL(downloadFinished(QString,QString)), this, SLOT(pythonDownloadSuccess(QString,QString))); + connect(pydownloader, SIGNAL(downloadFailure(QString,QString)), this, SLOT(pythonDownloadFailure(QString,QString))); + pydownloader->downloadUrl("http://python.org/ftp/python/2.7.1/python-2.7.1.msi"); +} + +void SearchEngine::pythonDownloadSuccess(QString url, QString file_path) { + setCursor(QCursor(Qt::ArrowCursor)); + Q_UNUSED(url); + QFile::rename(file_path, file_path+".msi"); + QProcess installer; + qDebug("Launching Python installer in passive mode..."); + + installer.start("msiexec.exe /passive /i "+file_path.replace("/", "\\")+".msi"); + // Wait for setup to complete + installer.waitForFinished(); + + qDebug("Installer stdout: %s", installer.readAllStandardOutput().data()); + qDebug("Installer stderr: %s", installer.readAllStandardError().data()); + qDebug("Setup should be complete!"); + // Reload search engine + has_python = addPythonPathToEnv(); + if(has_python) { + supported_engines->update(); + // Launch the search again + on_search_button_clicked(); + } + // Delete temp file + misc::safeRemove(file_path+".msi"); +} + +void SearchEngine::pythonDownloadFailure(QString url, QString error) { + Q_UNUSED(url); + setCursor(QCursor(Qt::ArrowCursor)); + QMessageBox::warning(this, tr("Download error"), tr("Python setup could not be downloaded, reason: %1.\nPlease install it manually.").arg(error)); +} + +#endif + +QString SearchEngine::selectedCategory() const { + return comboCategory->itemData(comboCategory->currentIndex()).toString(); +} + +SearchEngine::~SearchEngine(){ + qDebug("Search destruction"); + // save the searchHistory for later uses + saveSearchHistory(); + searchProcess->kill(); + searchProcess->waitForFinished(); + foreach(QProcess *downloader, downloaders) { + // Make sure we disconnect the SIGNAL/SLOT first + // To avoid qreal free + downloader->disconnect(); + downloader->kill(); + downloader->waitForFinished(); + delete downloader; + } +#if QT_VERSION < 0x040500 + delete closeTab_button; +#endif + delete searchTimeout; + delete searchProcess; + delete supported_engines; + if(searchCompleter) + delete searchCompleter; +} + +void SearchEngine::displayPatternContextMenu(QPoint) { + QMenu myMenu(this); + QAction cutAct(IconProvider::instance()->getIcon("edit-cut"), tr("Cut"), &myMenu); + QAction copyAct(IconProvider::instance()->getIcon("edit-copy"), tr("Copy"), &myMenu); + QAction pasteAct(IconProvider::instance()->getIcon("edit-paste"), tr("Paste"), &myMenu); + QAction clearAct(IconProvider::instance()->getIcon("edit-clear"), tr("Clear field"), &myMenu); + QAction clearHistoryAct(IconProvider::instance()->getIcon("edit-clear-history"), tr("Clear completion history"), &myMenu); + bool hasCopyAct = false; + if(search_pattern->hasSelectedText()) { + myMenu.addAction(&cutAct); + myMenu.addAction(©Act); + hasCopyAct = true; + } + if(qApp->clipboard()->mimeData()->hasText()) { + myMenu.addAction(&pasteAct); + hasCopyAct = true; + } + if(hasCopyAct) + myMenu.addSeparator(); + myMenu.addAction(&clearHistoryAct); + myMenu.addAction(&clearAct); + QAction *act = myMenu.exec(QCursor::pos()); + if(act != 0) { + if(act == &clearHistoryAct) { + // Ask for confirmation + if(QMessageBox::question(this, tr("Confirmation"), tr("Are you sure you want to clear the history?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) { + // Clear history + searchHistory.setStringList(QStringList()); + } + } + else if (act == &pasteAct) { + search_pattern->paste(); + } + else if (act == &cutAct) { + search_pattern->cut(); + } + else if (act == ©Act) { + search_pattern->copy(); + } + else if (act == &clearAct) { + search_pattern->clear(); + } + } +} + +void SearchEngine::tab_changed(int t) +{//when we switch from a tab that is not empty to another that is empty the download button + //doesn't have to be available + if(t>-1) + {//-1 = no more tab + if(all_tab.at(tabWidget->currentIndex())->getCurrentSearchListModel()->rowCount()) { + download_button->setEnabled(true); + goToDescBtn->setEnabled(true); + } else { + download_button->setEnabled(false); + goToDescBtn->setEnabled(false); + } + } +} + +void SearchEngine::on_enginesButton_clicked() { + engineSelectDlg *dlg = new engineSelectDlg(this, supported_engines); + connect(dlg, SIGNAL(enginesChanged()), this, SLOT(fillCatCombobox())); +} + +// get the last searchs from a QIniSettings to a QStringList +void SearchEngine::startSearchHistory(){ + QIniSettings settings("qBittorrent", "qBittorrent"); + searchHistory.setStringList(settings.value("Search/searchHistory",QStringList()).toStringList()); +} + +// Save the history list into the QIniSettings for the next session +void SearchEngine::saveSearchHistory() { + QIniSettings settings("qBittorrent", "qBittorrent"); + settings.setValue("Search/searchHistory",searchHistory.stringList()); +} + +void SearchEngine::searchTextEdited(QString) { + // Enable search button + search_button->setText(tr("Search")); +} + +void SearchEngine::giveFocusToSearchInput() { + search_pattern->setFocus(); +} + +// Function called when we click on search button +void SearchEngine::on_search_button_clicked(){ +#ifdef Q_WS_WIN + if(!has_python) { + if(QMessageBox::question(this, tr("Missing Python Interpreter"), + tr("Python 2.x is required to use the search engine but it does not seem to be installed.\nDo you want to install it now?"), + QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) { + // Download and Install Python + installPython(); + } + return; + } +#endif + if(searchProcess->state() != QProcess::NotRunning){ +#ifdef Q_WS_WIN + searchProcess->kill(); +#else + searchProcess->terminate(); +#endif + search_stopped = true; + if(searchTimeout->isActive()) { + searchTimeout->stop(); + } + if(search_button->text() != tr("Search")) { + search_button->setText(tr("Search")); + return; + } + } + searchProcess->waitForFinished(); + // Reload environment variables (proxy) + searchProcess->setEnvironment(QProcess::systemEnvironment()); + + const QString pattern = search_pattern->text().trimmed(); + // No search pattern entered + if(pattern.isEmpty()){ + QMessageBox::critical(0, tr("Empty search pattern"), tr("Please type a search pattern first")); + return; + } + // Tab Addition + currentSearchTab=new SearchTab(this); + connect(currentSearchTab->header(), SIGNAL(sectionResized(int, int, int)), this, SLOT(propagateSectionResized(int,int,int))); + all_tab.append(currentSearchTab); + QString tabName = pattern; + tabName.replace(QRegExp("&{1}"), "&&"); + tabWidget->addTab(currentSearchTab, tabName); + tabWidget->setCurrentWidget(currentSearchTab); +#if QT_VERSION < 0x040500 + closeTab_button->setEnabled(true); +#endif + // if the pattern is not in the pattern + QStringList wordList = searchHistory.stringList(); + if(wordList.indexOf(pattern) == -1){ + //update the searchHistory list + wordList.append(pattern); + // verify the max size of the history + if(wordList.size() > SEARCHHISTORY_MAXSIZE) + wordList = wordList.mid(wordList.size()/2); + searchHistory.setStringList(wordList); + } + + // Getting checked search engines + QStringList params; + search_stopped = false; + params << misc::searchEngineLocation()+QDir::separator()+"nova2.py"; + params << supported_engines->enginesEnabled().join(","); + qDebug("Search with category: %s", qPrintable(selectedCategory())); + params << selectedCategory(); + params << pattern.split(" "); + // Update SearchEngine widgets + no_search_results = true; + nb_search_results = 0; + search_result_line_truncated.clear(); + //on change le texte du label courrant + currentSearchTab->getCurrentLabel()->setText(tr("Results")+" (0):"); + // Launch search + searchProcess->start("python", params, QIODevice::ReadOnly); + searchTimeout->start(180000); // 3min +} + +void SearchEngine::createCompleter() { + if(searchCompleter) + delete searchCompleter; + searchCompleter = new QCompleter(&searchHistory); + searchCompleter->setCaseSensitivity(Qt::CaseInsensitive); + search_pattern->setCompleter(searchCompleter); +} + +void SearchEngine::propagateSectionResized(int index, int , int newsize) { + foreach(SearchTab * tab, all_tab) { + tab->getCurrentTreeView()->setColumnWidth(index, newsize); + } + saveResultsColumnsWidth(); +} + +void SearchEngine::saveResultsColumnsWidth() { + if(all_tab.size() > 0) { + QTreeView* treeview = all_tab.first()->getCurrentTreeView(); + QIniSettings settings("qBittorrent", "qBittorrent"); + QStringList width_list; + QStringList new_width_list; + short nbColumns = all_tab.first()->getCurrentSearchListModel()->columnCount(); + + QString line = settings.value("SearchResultsColsWidth", QString()).toString(); + if(!line.isEmpty()) { + width_list = line.split(' '); + } + for(short i=0; icolumnWidth(i)<1 && width_list.size() == nbColumns && width_list.at(i).toInt()>=1) { + // load the former width + new_width_list << width_list.at(i); + } else if(treeview->columnWidth(i)>=1) { + // usual case, save the current width + new_width_list << QString::number(treeview->columnWidth(i)); + } else { + // default width + treeview->resizeColumnToContents(i); + new_width_list << QString::number(treeview->columnWidth(i)); + } + } + settings.setValue("SearchResultsColsWidth", new_width_list.join(" ")); + } +} + +void SearchEngine::downloadTorrent(QString engine_url, QString torrent_url) { + if(torrent_url.startsWith("bc://bt/", Qt::CaseInsensitive)) { + qDebug("Converting bc link to magnet link"); + torrent_url = misc::bcLinkToMagnet(torrent_url); + } + if(torrent_url.startsWith("magnet:")) { + QStringList urls; + urls << torrent_url; + mp_mainWindow->downloadFromURLList(urls); + } else { + QProcess *downloadProcess = new QProcess(this); + downloadProcess->setEnvironment(QProcess::systemEnvironment()); + connect(downloadProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(downloadFinished(int,QProcess::ExitStatus))); + downloaders << downloadProcess; + QStringList params; + params << misc::searchEngineLocation()+QDir::separator()+"nova2dl.py"; + params << engine_url; + params << torrent_url; + // Launch search + downloadProcess->start("python", params, QIODevice::ReadOnly); + } +} + +void SearchEngine::searchStarted(){ + // Update SearchEngine widgets + search_status->setText(tr("Searching...")); + search_status->repaint(); + search_button->setText("Stop"); +} + +// search Qprocess return output as soon as it gets new +// stuff to read. We split it into lines and add each +// line to search results calling appendSearchResult(). +void SearchEngine::readSearchOutput(){ + QByteArray output = searchProcess->readAllStandardOutput(); + output.replace("\r", ""); + QList lines_list = output.split('\n'); + if(!search_result_line_truncated.isEmpty()){ + QByteArray end_of_line = lines_list.takeFirst(); + lines_list.prepend(search_result_line_truncated+end_of_line); + } + search_result_line_truncated = lines_list.takeLast().trimmed(); + foreach(const QByteArray &line, lines_list){ + appendSearchResult(QString::fromUtf8(line)); + } + if(currentSearchTab) + currentSearchTab->getCurrentLabel()->setText(tr("Results")+QString::fromUtf8(" (")+QString::number(nb_search_results)+QString::fromUtf8("):")); +} + +void SearchEngine::downloadFinished(int exitcode, QProcess::ExitStatus) { + QProcess *downloadProcess = (QProcess*)sender(); + if(exitcode == 0) { + QString line = QString::fromUtf8(downloadProcess->readAllStandardOutput()).trimmed(); + QStringList parts = line.split(' '); + if(parts.size() == 2) { + QString path = parts[0]; + QString url = parts[1]; + QBtSession::instance()->processDownloadedFile(url, path); + } + } + qDebug("Deleting downloadProcess"); + downloaders.removeOne(downloadProcess); + delete downloadProcess; +} + +// Update nova.py search plugin if necessary +void SearchEngine::updateNova() { + qDebug("Updating nova"); + // create nova directory if necessary + QDir search_dir(misc::searchEngineLocation()); + QFile package_file(search_dir.absoluteFilePath("__init__.py")); + package_file.open(QIODevice::WriteOnly | QIODevice::Text); + package_file.close(); + if(!search_dir.exists("engines")){ + search_dir.mkdir("engines"); + } + QFile package_file2(search_dir.absolutePath().replace("\\", "/")+"/engines/__init__.py"); + package_file2.open(QIODevice::WriteOnly | QIODevice::Text); + package_file2.close(); + // Copy search plugin files (if necessary) + QString filePath = search_dir.absoluteFilePath("nova2.py"); + if(getPluginVersion(":/nova/nova2.py") > getPluginVersion(filePath)) { + if(QFile::exists(filePath)) { + misc::safeRemove(filePath); + misc::safeRemove(filePath+"c"); + } + QFile::copy(":/nova/nova2.py", filePath); + } + + filePath = search_dir.absoluteFilePath("nova2dl.py"); + if(getPluginVersion(":/nova/nova2dl.py") > getPluginVersion(filePath)) { + if(QFile::exists(filePath)){ + misc::safeRemove(filePath); + misc::safeRemove(filePath+"c"); + } + QFile::copy(":/nova/nova2dl.py", filePath); + } + + filePath = search_dir.absoluteFilePath("novaprinter.py"); + if(getPluginVersion(":/nova/novaprinter.py") > getPluginVersion(filePath)) { + if(QFile::exists(filePath)){ + misc::safeRemove(filePath); + misc::safeRemove(filePath+"c"); + } + QFile::copy(":/nova/novaprinter.py", filePath); + } + + filePath = search_dir.absoluteFilePath("helpers.py"); + if(getPluginVersion(":/nova/helpers.py") > getPluginVersion(filePath)) { + if(QFile::exists(filePath)){ + misc::safeRemove(filePath); + misc::safeRemove(filePath+"c"); + } + QFile::copy(":/nova/helpers.py", filePath); + } + + filePath = search_dir.absoluteFilePath("socks.py"); + if(QFile::exists(filePath)){ + misc::safeRemove(filePath); + misc::safeRemove(filePath+"c"); + } + QFile::copy(":/nova/socks.py", filePath); + QDir destDir(QDir(misc::searchEngineLocation()).absoluteFilePath("engines")); + QDir shipped_subDir(":/nova/engines/"); + QStringList files = shipped_subDir.entryList(); + foreach(const QString &file, files){ + QString shipped_file = shipped_subDir.absoluteFilePath(file); + // Copy python classes + if(file.endsWith(".py")) { + const QString dest_file = destDir.absoluteFilePath(file); + if(getPluginVersion(shipped_file) > getPluginVersion(dest_file) ) { + qDebug("shipped %s is more recent then local plugin, updating...", qPrintable(file)); + if(QFile::exists(dest_file)) { + qDebug("Removing old %s", qPrintable(dest_file)); + misc::safeRemove(dest_file); + misc::safeRemove(dest_file+"c"); + } + qDebug("%s copied to %s", qPrintable(shipped_file), qPrintable(dest_file)); + QFile::copy(shipped_file, dest_file); + } + } else { + // Copy icons + if(file.endsWith(".png")) { + if(!QFile::exists(destDir.absoluteFilePath(file))) { + QFile::copy(shipped_file, destDir.absoluteFilePath(file)); + } + } + } + } +#ifndef Q_WS_WIN + // Fix permissions + misc::chmod644(QDir(misc::searchEngineLocation())); +#endif +} + +// Slot called when search is Finished +// Search can be finished for 3 reasons : +// Error | Stopped by user | Finished normally +void SearchEngine::searchFinished(int exitcode,QProcess::ExitStatus){ + if(searchTimeout->isActive()) { + searchTimeout->stop(); + } + QIniSettings settings("qBittorrent", "qBittorrent"); + bool useNotificationBalloons = settings.value("Preferences/General/NotificationBaloons", true).toBool(); + if(useNotificationBalloons && mp_mainWindow->getCurrentTabWidget() != this) { + mp_mainWindow->showNotificationBaloon(tr("Search Engine"), tr("Search has finished")); + } + if(exitcode){ +#ifdef Q_WS_WIN + search_status->setText(tr("Search aborted")); +#else + search_status->setText(tr("An error occured during search...")); +#endif + }else{ + if(search_stopped){ + search_status->setText(tr("Search aborted")); + }else{ + if(no_search_results){ + search_status->setText(tr("Search returned no results")); + }else{ + search_status->setText(tr("Search has finished")); + } + } + } + if(currentSearchTab) + currentSearchTab->getCurrentLabel()->setText(tr("Results", "i.e: Search results")+QString::fromUtf8(" (")+QString::number(nb_search_results)+QString::fromUtf8("):")); + search_button->setText("Search"); +} + +// SLOT to append one line to search results list +// Line is in the following form : +// file url | file name | file size | nb seeds | nb leechers | Search engine url +void SearchEngine::appendSearchResult(const QString &line){ + if(!currentSearchTab) { + if(searchProcess->state() != QProcess::NotRunning){ + searchProcess->terminate(); + } + if(searchTimeout->isActive()) { + searchTimeout->stop(); + } + search_stopped = true; + return; + } + const QStringList parts = line.split("|"); + const int nb_fields = parts.size(); + if(nb_fields < NB_PLUGIN_COLUMNS-1){ //-1 because desc_link is optional + return; + } + Q_ASSERT(currentSearchTab); + // Add item to search result list + QStandardItemModel* cur_model = currentSearchTab->getCurrentSearchListModel(); + Q_ASSERT(cur_model); + int row = cur_model->rowCount(); + cur_model->insertRow(row); + + cur_model->setData(cur_model->index(row, DL_LINK), parts.at(PL_DL_LINK).trimmed()); // download URL + cur_model->setData(cur_model->index(row, NAME), parts.at(PL_NAME).trimmed()); // Name + cur_model->setData(cur_model->index(row, SIZE), parts.at(PL_SIZE).trimmed().toLongLong()); // Size + bool ok = false; + qlonglong nb_seeders = parts.at(PL_SEEDS).trimmed().toLongLong(&ok); + if(!ok || nb_seeders < 0) { + cur_model->setData(cur_model->index(row, SEEDS), tr("Unknown")); // Seeders + } else { + cur_model->setData(cur_model->index(row, SEEDS), nb_seeders); // Seeders + } + qlonglong nb_leechers = parts.at(PL_LEECHS).trimmed().toLongLong(&ok); + if(!ok || nb_leechers < 0) { + cur_model->setData(cur_model->index(row, LEECHS), tr("Unknown")); // Leechers + } else { + cur_model->setData(cur_model->index(row, LEECHS), nb_leechers); // Leechers + } + cur_model->setData(cur_model->index(row, ENGINE_URL), parts.at(PL_ENGINE_URL).trimmed()); // Engine URL + // Description Link + if(nb_fields == NB_PLUGIN_COLUMNS) + cur_model->setData(cur_model->index(row, DESC_LINK), parts.at(PL_DESC_LINK).trimmed()); + + no_search_results = false; + ++nb_search_results; + // Enable clear & download buttons + download_button->setEnabled(true); + goToDescBtn->setEnabled(true); +} + +#if QT_VERSION >= 0x040500 +void SearchEngine::closeTab(int index) { + if(index == tabWidget->indexOf(currentSearchTab)) { + qDebug("Deleted current search Tab"); + if(searchProcess->state() != QProcess::NotRunning){ + searchProcess->terminate(); + } + if(searchTimeout->isActive()) { + searchTimeout->stop(); + } + search_stopped = true; + currentSearchTab = 0; + } + delete all_tab.takeAt(index); + if(!all_tab.size()) { + download_button->setEnabled(false); + goToDescBtn->setEnabled(false); + } +} +#else +// Clear search results list +void SearchEngine::closeTab_button_clicked(){ + if(all_tab.size()) { + qDebug("currentTab rank: %d", tabWidget->currentIndex()); + qDebug("currentSearchTab rank: %d", tabWidget->indexOf(currentSearchTab)); + if(tabWidget->currentIndex() == tabWidget->indexOf(currentSearchTab)) { + qDebug("Deleted current search Tab"); + if(searchProcess->state() != QProcess::NotRunning){ + searchProcess->terminate(); + } + if(searchTimeout->isActive()) { + searchTimeout->stop(); + } + search_stopped = true; + currentSearchTab = 0; + } + delete all_tab.takeAt(tabWidget->currentIndex()); + if(!all_tab.size()) { + closeTab_button->setEnabled(false); + download_button->setEnabled(false); + } + } +} +#endif + +// Download selected items in search results list +void SearchEngine::on_download_button_clicked(){ + //QModelIndexList selectedIndexes = currentSearchTab->getCurrentTreeView()->selectionModel()->selectedIndexes(); + QModelIndexList selectedIndexes = all_tab.at(tabWidget->currentIndex())->getCurrentTreeView()->selectionModel()->selectedIndexes(); + foreach(const QModelIndex &index, selectedIndexes){ + if(index.column() == NAME){ + // Get Item url + QSortFilterProxyModel* model = all_tab.at(tabWidget->currentIndex())->getCurrentSearchListProxy(); + QString torrent_url = model->data(model->index(index.row(), URL_COLUMN)).toString(); + QString engine_url = model->data(model->index(index.row(), ENGINE_URL_COLUMN)).toString(); + downloadTorrent(engine_url, torrent_url); + all_tab.at(tabWidget->currentIndex())->setRowColor(index.row(), "red"); + } + } +} + +void SearchEngine::on_goToDescBtn_clicked() +{ + QModelIndexList selectedIndexes = all_tab.at(tabWidget->currentIndex())->getCurrentTreeView()->selectionModel()->selectedIndexes(); + foreach(const QModelIndex &index, selectedIndexes){ + if(index.column() == NAME) { + QSortFilterProxyModel* model = all_tab.at(tabWidget->currentIndex())->getCurrentSearchListProxy(); + const QString desc_url = model->data(model->index(index.row(), DESC_LINK)).toString(); + if(!desc_url.isEmpty()) + QDesktopServices::openUrl(QUrl::fromEncoded(desc_url.toUtf8())); + } + } +} diff --git a/src/searchengine/searchengine.h b/src/searchengine/searchengine.h new file mode 100644 index 000000000..3b9629e6c --- /dev/null +++ b/src/searchengine/searchengine.h @@ -0,0 +1,151 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef SEARCH_H +#define SEARCH_H + +#include +#include +#include +#include +#include +#include "ui_search.h" +#include "engineselectdlg.h" +#include "searchtab.h" +#include "supportedengines.h" + +class DownloadThread; +class SearchEngine; +class MainWindow; + +QT_BEGIN_NAMESPACE +class QTimer; +QT_END_NAMESPACE + +class SearchEngine : public QWidget, public Ui::search_engine{ + Q_OBJECT + Q_DISABLE_COPY(SearchEngine) + +public: + enum SearchColumn { NAME, SIZE, SEEDS, LEECHS, ENGINE_URL, DL_LINK, DESC_LINK, NB_SEARCH_COLUMNS }; +private: + enum PluginColumn { PL_DL_LINK, PL_NAME, PL_SIZE, PL_SEEDS, PL_LEECHS, PL_ENGINE_URL, PL_DESC_LINK, NB_PLUGIN_COLUMNS }; + +public: + SearchEngine(MainWindow *mp_mainWindow); + ~SearchEngine(); + QString selectedCategory() const; + + static qreal getPluginVersion(QString filePath) { + QFile plugin(filePath); + if(!plugin.exists()){ + qDebug("%s plugin does not exist, returning 0.0", qPrintable(filePath)); + return 0.0; + } + if(!plugin.open(QIODevice::ReadOnly | QIODevice::Text)){ + return 0.0; + } + qreal version = 0.0; + while (!plugin.atEnd()){ + QByteArray line = plugin.readLine(); + if(line.startsWith("#VERSION: ")){ + line = line.split(' ').last().trimmed(); + version = line.toFloat(); + qDebug("plugin %s version: %.2f", qPrintable(filePath), version); + break; + } + } + return version; + } + +public slots: + void on_download_button_clicked(); + void downloadTorrent(QString engine_url, QString torrent_url); + void giveFocusToSearchInput(); + +protected slots: + // Search slots + void tab_changed(int);//to prevent the use of the download button when the tab is empty + void on_search_button_clicked(); +#if QT_VERSION < 0x040500 + void closeTab_button_clicked(); +#else + void closeTab(int index); +#endif + void appendSearchResult(const QString &line); + void searchFinished(int exitcode,QProcess::ExitStatus); + void readSearchOutput(); + void searchStarted(); + void startSearchHistory(); + void updateNova(); + void saveSearchHistory(); + void on_enginesButton_clicked(); + void propagateSectionResized(int index, int oldsize , int newsize); + void saveResultsColumnsWidth(); + void downloadFinished(int exitcode, QProcess::ExitStatus); + void displayPatternContextMenu(QPoint); + void createCompleter(); + void fillCatCombobox(); + void searchTextEdited(QString); +#ifdef Q_WS_WIN + bool addPythonPathToEnv(); + void installPython(); + void pythonDownloadSuccess(QString url, QString file_path); + void pythonDownloadFailure(QString url, QString error); +#endif + +private slots: + void on_goToDescBtn_clicked(); + +private: + // Search related + QProcess *searchProcess; + QList downloaders; + bool search_stopped; + bool no_search_results; + QByteArray search_result_line_truncated; + unsigned long nb_search_results; + QPointer searchCompleter; + QStringListModel searchHistory; + SupportedEngines *supported_engines; + QTimer *searchTimeout; + QPointer currentSearchTab; +#if QT_VERSION < 0x040500 + QPushButton *closeTab_button; +#endif + QList > all_tab; // To store all tabs + const SearchCategories full_cat_names; + MainWindow *mp_mainWindow; +#ifdef Q_WS_WIN + bool has_python; +#endif +}; + +#endif diff --git a/src/searchengine/searchengine.pri b/src/searchengine/searchengine.pri new file mode 100644 index 000000000..8a4ac7c46 --- /dev/null +++ b/src/searchengine/searchengine.pri @@ -0,0 +1,18 @@ +INCLUDEPATH += $$PWD + +FORMS += $$PWD/search.ui \ + $$PWD/engineselect.ui \ + $$PWD/pluginsource.ui + +HEADERS += $$PWD/searchengine.h \ + $$PWD/searchtab.h \ + $$PWD/engineselectdlg.h \ + $$PWD/pluginsource.h \ + $$PWD/searchlistdelegate.h \ + $$PWD/supportedengines.h + +SOURCES += $$PWD/searchengine.cpp \ + $$PWD/searchtab.cpp \ + $$PWD/engineselectdlg.cpp + +RESOURCES += $$PWD/search.qrc diff --git a/src/searchengine/searchlistdelegate.h b/src/searchengine/searchlistdelegate.h new file mode 100644 index 000000000..3e3804cb8 --- /dev/null +++ b/src/searchengine/searchlistdelegate.h @@ -0,0 +1,71 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef SEARCHLISTDELEGATE_H +#define SEARCHLISTDELEGATE_H + +#include +#include +#include +#include +#include +#include +#include "misc.h" +#include "searchengine.h" + +class SearchListDelegate: public QItemDelegate { + Q_OBJECT + + public: + SearchListDelegate(QObject *parent=0) : QItemDelegate(parent){} + + ~SearchListDelegate(){} + + void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const{ + painter->save(); + QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option); + switch(index.column()){ + case SearchEngine::SIZE: + QItemDelegate::drawBackground(painter, opt, index); + QItemDelegate::drawDisplay(painter, opt, option.rect, misc::friendlyUnit(index.data().toLongLong())); + break; + default: + QItemDelegate::paint(painter, option, index); + } + painter->restore(); + } + + QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const { + // No editor here + return 0; + } +}; + +#endif diff --git a/src/searchengine/searchtab.cpp b/src/searchengine/searchtab.cpp new file mode 100644 index 000000000..ad056eaf7 --- /dev/null +++ b/src/searchengine/searchtab.cpp @@ -0,0 +1,152 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include +#include + +#include "searchtab.h" +#include "searchlistdelegate.h" +#include "misc.h" +#include "searchengine.h" +#include "qinisettings.h" + +SearchTab::SearchTab(SearchEngine *parent) : QWidget(), parent(parent) +{ + box=new QVBoxLayout(); + results_lbl=new QLabel(); + resultsBrowser = new QTreeView(); + resultsBrowser->setSelectionMode(QAbstractItemView::ExtendedSelection); + box->addWidget(results_lbl); + box->addWidget(resultsBrowser); + + setLayout(box); + // Set Search results list model + SearchListModel = new QStandardItemModel(0, SearchEngine::NB_SEARCH_COLUMNS); + SearchListModel->setHeaderData(SearchEngine::NAME, Qt::Horizontal, tr("Name", "i.e: file name")); + SearchListModel->setHeaderData(SearchEngine::SIZE, Qt::Horizontal, tr("Size", "i.e: file size")); + SearchListModel->setHeaderData(SearchEngine::SEEDS, Qt::Horizontal, tr("Seeders", "i.e: Number of full sources")); + SearchListModel->setHeaderData(SearchEngine::LEECHS, Qt::Horizontal, tr("Leechers", "i.e: Number of partial sources")); + SearchListModel->setHeaderData(SearchEngine::ENGINE_URL, Qt::Horizontal, tr("Search engine")); + + proxyModel = new QSortFilterProxyModel(); + proxyModel->setDynamicSortFilter(true); + proxyModel->setSourceModel(SearchListModel); + resultsBrowser->setModel(proxyModel); + + SearchDelegate = new SearchListDelegate(); + resultsBrowser->setItemDelegate(SearchDelegate); + + resultsBrowser->hideColumn(SearchEngine::DL_LINK); // Hide url column + resultsBrowser->hideColumn(SearchEngine::DESC_LINK); + + resultsBrowser->setRootIsDecorated(false); + resultsBrowser->setAllColumnsShowFocus(true); + resultsBrowser->setSortingEnabled(true); + + // Connect signals to slots (search part) + connect(resultsBrowser, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(downloadSelectedItem(const QModelIndex&))); + + // Load last columns width for search results list + if(!loadColWidthResultsList()){ + resultsBrowser->header()->resizeSection(0, 275); + } + + // Sort by Seeds + resultsBrowser->sortByColumn(SearchEngine::SEEDS, Qt::DescendingOrder); +} + +void SearchTab::downloadSelectedItem(const QModelIndex& index) { + QString engine_url = proxyModel->data(proxyModel->index(index.row(), SearchEngine::ENGINE_URL)).toString(); + QString torrent_url = proxyModel->data(proxyModel->index(index.row(), SearchEngine::DL_LINK)).toString(); + setRowColor(index.row(), "red"); + parent->downloadTorrent(engine_url, torrent_url); +} + +SearchTab::~SearchTab() { + delete box; + delete results_lbl; + delete resultsBrowser; + delete SearchListModel; + delete proxyModel; + delete SearchDelegate; +} + +QHeaderView* SearchTab::header() const { + return resultsBrowser->header(); +} + +bool SearchTab::loadColWidthResultsList() { + QIniSettings settings("qBittorrent", "qBittorrent"); + QString line = settings.value("SearchResultsColsWidth", QString()).toString(); + if(line.isEmpty()) + return false; + QStringList width_list = line.split(' '); + if(width_list.size() < SearchListModel->columnCount()) + return false; + unsigned int listSize = width_list.size(); + for(unsigned int i=0; iheader()->resizeSection(i, width_list.at(i).toInt()); + } + return true; +} + +QLabel* SearchTab::getCurrentLabel() +{ + return results_lbl; +} + +QTreeView* SearchTab::getCurrentTreeView() +{ + return resultsBrowser; +} + +QSortFilterProxyModel* SearchTab::getCurrentSearchListProxy() const +{ + return proxyModel; +} + +QStandardItemModel* SearchTab::getCurrentSearchListModel() const +{ + return SearchListModel; +} + +// Set the color of a row in data model +void SearchTab::setRowColor(int row, QString color){ + proxyModel->setDynamicSortFilter(false); + for(int i=0; icolumnCount(); ++i){ + proxyModel->setData(proxyModel->index(row, i), QVariant(QColor(color)), Qt::ForegroundRole); + } + proxyModel->setDynamicSortFilter(true); +} + + diff --git a/src/searchengine/searchtab.h b/src/searchengine/searchtab.h new file mode 100644 index 000000000..dfc77c2e2 --- /dev/null +++ b/src/searchengine/searchtab.h @@ -0,0 +1,79 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef SEARCH_TAB_H +#define SEARCH_TAB_H + +#include "ui_search.h" + +#define ENGINE_URL_COLUMN 4 +#define URL_COLUMN 5 + +class SearchListDelegate; +class SearchEngine; + +QT_BEGIN_NAMESPACE +class QTreeView; +class QHeaderView; +class QStandardItemModel; +class QSortFilterProxyModel; +QT_END_NAMESPACE + +class SearchTab: public QWidget, public Ui::search_engine { + Q_OBJECT + +private: + QVBoxLayout *box; + QLabel *results_lbl; + QTreeView *resultsBrowser; + QStandardItemModel *SearchListModel; + QSortFilterProxyModel *proxyModel; + SearchListDelegate *SearchDelegate; + SearchEngine *parent; + +protected slots: + void downloadSelectedItem(const QModelIndex& index); + +public: + SearchTab(SearchEngine *parent); + ~SearchTab(); + bool loadColWidthResultsList(); + QLabel * getCurrentLabel(); + QStandardItemModel* getCurrentSearchListModel() const; + QSortFilterProxyModel* getCurrentSearchListProxy() const; + QTreeView * getCurrentTreeView(); + void setRowColor(int row, QString color); + QHeaderView* header() const; + + +}; + +#endif + diff --git a/src/searchengine/supportedengines.h b/src/searchengine/supportedengines.h new file mode 100644 index 000000000..a01456290 --- /dev/null +++ b/src/searchengine/supportedengines.h @@ -0,0 +1,180 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef SEARCHENGINES_H +#define SEARCHENGINES_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "misc.h" +#include "qinisettings.h" + +class SearchCategories: public QObject, public QHash { + Q_OBJECT + +public: + SearchCategories() { + (*this)["all"] = tr("All categories"); + (*this)["movies"] = tr("Movies"); + (*this)["tv"] = tr("TV shows"); + (*this)["music"] = tr("Music"); + (*this)["games"] = tr("Games"); + (*this)["anime"] = tr("Anime"); + (*this)["software"] = tr("Software"); + (*this)["pictures"] = tr("Pictures"); + (*this)["books"] = tr("Books"); + } +}; + +class SupportedEngine { +private: + QString name; + QString full_name; + QString url; + QStringList supported_categories; + bool enabled; + +public: + SupportedEngine(QDomElement engine_elem) { + name = engine_elem.tagName(); + full_name = engine_elem.elementsByTagName("name").at(0).toElement().text(); + url = engine_elem.elementsByTagName("url").at(0).toElement().text(); + supported_categories = engine_elem.elementsByTagName("categories").at(0).toElement().text().split(" "); + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + QStringList disabled_engines = settings.value(QString::fromUtf8("SearchEngines/disabledEngines"), QStringList()).toStringList(); + enabled = !disabled_engines.contains(name); + } + + QString getName() const { return name; } + QString getUrl() const { return url; } + QString getFullName() const { return full_name; } + QStringList getSupportedCategories() const { return supported_categories; } + bool isEnabled() const { return enabled; } + void setEnabled(bool _enabled) { + enabled = _enabled; + // Save to Hard disk + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + QStringList disabled_engines = settings.value(QString::fromUtf8("SearchEngines/disabledEngines"), QStringList()).toStringList(); + if(enabled) { + disabled_engines.removeAll(name); + } else { + disabled_engines.append(name); + } + settings.setValue("SearchEngines/disabledEngines", disabled_engines); + } +}; + +class SupportedEngines: public QObject, public QHash { + Q_OBJECT + +signals: + void newSupportedEngine(QString name); + +public: + SupportedEngines(bool has_python = true) { + if(has_python) + update(); + } + + ~SupportedEngines() { + qDeleteAll(this->values()); + } + + QStringList enginesEnabled() const { + QStringList engines; + foreach(const SupportedEngine *engine, values()) { + if(engine->isEnabled()) + engines << engine->getName(); + } + return engines; + } + + QStringList supportedCategories() const { + QStringList supported_cat; + foreach(const SupportedEngine *engine, values()) { + if(engine->isEnabled()) { + const QStringList &s = engine->getSupportedCategories(); + foreach(QString cat, s) { + cat = cat.trimmed(); + if(!cat.isEmpty() && !supported_cat.contains(cat)) + supported_cat << cat; + } + } + } + return supported_cat; + } + +public slots: + void update() { + QProcess nova; + nova.setEnvironment(QProcess::systemEnvironment()); + QStringList params; + params << misc::searchEngineLocation()+QDir::separator()+"nova2.py"; + params << "--capabilities"; + nova.start("python", params, QIODevice::ReadOnly); + nova.waitForStarted(); + nova.waitForFinished(); + QString capabilities = QString(nova.readAll()); + QDomDocument xml_doc; + if(!xml_doc.setContent(capabilities)) { + std::cerr << "Could not parse Nova search engine capabilities, msg: " << capabilities.toLocal8Bit().data() << std::endl; + std::cerr << "Error: " << nova.readAllStandardError().constData() << std::endl; + return; + } + QDomElement root = xml_doc.documentElement(); + if(root.tagName() != "capabilities") { + std::cout << "Invalid XML file for Nova search engine capabilities, msg: " << capabilities.toLocal8Bit().data() << std::endl; + return; + } + for(QDomNode engine_node = root.firstChild(); !engine_node.isNull(); engine_node = engine_node.nextSibling()) { + QDomElement engine_elem = engine_node.toElement(); + if(!engine_elem.isNull()) { + SupportedEngine *s = new SupportedEngine(engine_elem); + if(this->contains(s->getName())) { + // Already in the list + delete s; + } else { + qDebug("Supported search engine: %s", s->getFullName().toLocal8Bit().data()); + (*this)[s->getName()] = s; + emit newSupportedEngine(s->getName()); + } + } + } + } +}; + +#endif // SEARCHENGINES_H diff --git a/src/sessionapplication.cpp b/src/sessionapplication.cpp new file mode 100644 index 000000000..4a8b264b6 --- /dev/null +++ b/src/sessionapplication.cpp @@ -0,0 +1,44 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include "sessionapplication.h" + +SessionApplication::SessionApplication(const QString &id, int &argc, char **argv) : +#ifdef Q_WS_MAC +QMacApplication(id, argc, argv) +#else +QtSingleApplication(id, argc, argv) +#endif +{} + +void SessionApplication::commitData(QSessionManager & manager) { + Q_UNUSED(manager); + emit sessionIsShuttingDown(); +} diff --git a/src/sessionapplication.h b/src/sessionapplication.h new file mode 100644 index 000000000..d3ce6866b --- /dev/null +++ b/src/sessionapplication.h @@ -0,0 +1,61 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef SESSIONAPPLICATION_H +#define SESSIONAPPLICATION_H + +#include + +#ifdef Q_WS_MAC +#include "qmacapplication.h" +#else +#include "qtsingleapplication.h" +#endif + +#include + +class SessionApplication : +#ifdef Q_WS_MAC + public QMacApplication +#else + public QtSingleApplication +#endif +{ + Q_OBJECT + +public: + SessionApplication(const QString &id, int &argc, char **argv); + void commitData(QSessionManager & manager); + + signals: + void sessionIsShuttingDown(); +}; + +#endif // SESSIONAPPLICATION_H diff --git a/src/smtp.cpp b/src/smtp.cpp new file mode 100644 index 000000000..616b87458 --- /dev/null +++ b/src/smtp.cpp @@ -0,0 +1,458 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +/* + * This code is based on QxtSmtp from libqxt (http://libqxt.org) + */ + +#include "smtp.h" +#include "preferences.h" +#include "qbtsession.h" + +#include +#ifndef QT_NO_OPENSSL +#include +#else +#include +#endif +#include +#include +#include +#include +#include + +const short DEFAULT_PORT = 25; +const short DEFAULT_PORT_SSL = 465; + +QByteArray hmacMD5(QByteArray key, const QByteArray &msg) +{ + const int blockSize = 64; // HMAC-MD5 block size + if (key.length() > blockSize) { // if key is longer than block size (64), reduce key length with MD5 compression + key = QCryptographicHash::hash(key, QCryptographicHash::Md5); + } + + QByteArray innerPadding(blockSize, char(0x36)); // initialize inner padding with char "6" + QByteArray outerPadding(blockSize, char(0x5c)); // initialize outer padding with char "\" + // ascii characters 0x36 ("6") and 0x5c ("\") are selected because they have large + // Hamming distance (http://en.wikipedia.org/wiki/Hamming_distance) + + for (int i = 0; i < key.length(); i++) { + innerPadding[i] = innerPadding[i] ^ key.at(i); // XOR operation between every byte in key and innerpadding, of key length + outerPadding[i] = outerPadding[i] ^ key.at(i); // XOR operation between every byte in key and outerpadding, of key length + } + + // result = hash ( outerPadding CONCAT hash ( innerPadding CONCAT baseString ) ).toBase64 + QByteArray total = outerPadding; + QByteArray part = innerPadding; + part.append(msg); + total.append(QCryptographicHash::hash(part, QCryptographicHash::Md5)); + return QCryptographicHash::hash(total, QCryptographicHash::Md5); +} + +Smtp::Smtp(QObject *parent): QObject(parent), + state(Init), use_ssl(false) { +#ifndef QT_NO_OPENSSL + socket = new QSslSocket(this); +#else + socket = new QTcpSocket(this); +#endif + + connect(socket, SIGNAL(readyRead()), SLOT(readyRead())); + connect(socket, SIGNAL(disconnected()), SLOT(deleteLater())); + + // Test hmacMD5 function (http://www.faqs.org/rfcs/rfc2202.html) + Q_ASSERT(hmacMD5("Jefe", "what do ya want for nothing?").toHex() + == "750c783e6ab0b503eaa86e310a5db738"); + Q_ASSERT(hmacMD5(QByteArray::fromHex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"), + "Hi There").toHex() + == "9294727a3638bb1c13f48ef8158bfc9d"); +} + +Smtp::~Smtp() { + qDebug() << Q_FUNC_INFO; +} + +void Smtp::sendMail(const QString &from, const QString &to, const QString &subject, const QString &body) { + Preferences pref; + QTextCodec* latin1 = QTextCodec::codecForName("latin1"); + message = ""; + message += encode_mime_header("Date", QDateTime::currentDateTime().toUTC().toString("ddd, d MMM yyyy hh:mm:ss UT"), latin1); + message += encode_mime_header("From", from, latin1); + message += encode_mime_header("Subject", subject, latin1); + message += encode_mime_header("To", to, latin1); + message += "MIME-Version: 1.0\r\n"; + message += "Content-Type: text/plain; charset=UTF-8\r\n"; + message += "Content-Transfer-Encoding: base64\r\n"; + message += "\r\n"; + // Encode the body in base64 + QString crlf_body = body; + QByteArray b = crlf_body.replace("\n","\r\n").toUtf8().toBase64(); + int ct = b.length(); + for (int i = 0; i < ct; i += 78) + { + message += b.mid(i, 78); + } + this->from = from; + rcpt = to; + // Authentication + if(pref.getMailNotificationSMTPAuth()) { + username = pref.getMailNotificationSMTPUsername(); + password = pref.getMailNotificationSMTPPassword(); + } + + // Connect to SMTP server +#ifndef QT_NO_OPENSSL + if(pref.getMailNotificationSMTPSSL()) { + socket->connectToHostEncrypted(pref.getMailNotificationSMTP(), DEFAULT_PORT_SSL); + use_ssl = true; + } else { +#endif + socket->connectToHost(pref.getMailNotificationSMTP(), DEFAULT_PORT); + use_ssl = false; +#ifndef QT_NO_OPENSSL + } +#endif +} + +void Smtp::readyRead() +{ + qDebug() << Q_FUNC_INFO; + // SMTP is line-oriented + buffer += socket->readAll(); + while (true) + { + int pos = buffer.indexOf("\r\n"); + if (pos < 0) return; // Loop exit condition + QByteArray line = buffer.left(pos); + buffer = buffer.mid(pos + 2); + qDebug() << "Response line:" << line; + // Extract reponse code + QByteArray code = line.left(3); + + switch(state) { + case Init: { + if(code[0] == '2') { + // Connection was successful + ehlo(); + } else { + logError("Connection failed, unrecognized reply: "+line); + state = Close; + } + break; + } + case EhloSent: + case HeloSent: + case EhloGreetReceived: + parseEhloResponse(code, line[3] != ' ', line.mid(4)); + break; +#ifndef QT_NO_OPENSSL + case StartTLSSent: + if (code == "220") { + socket->startClientEncryption(); + ehlo(); + } else { + authenticate(); + } + break; +#endif + case AuthRequestSent: + case AuthUsernameSent: + if (authType == AuthPlain) authPlain(); + else if (authType == AuthLogin) authLogin(); + else authCramMD5(line.mid(4)); + break; + case AuthSent: + case Authenticated: + if (code[0] == '2') { + qDebug() << "Sending ..."; + socket->write("mail from:<" + from.toAscii() + ">\r\n"); + socket->flush(); + state = Rcpt; + } else { + // Authentication failed! + logError("Authentication failed, msg: "+line); + state = Close; + } + break; + case Rcpt: + if (code[0] == '2') { + socket->write("rcpt to:<" + rcpt.toAscii() + ">\r\n"); + socket->flush(); + state = Data; + } else { + logError(" was rejected by server, msg: "+line); + state = Close; + } + break; + case Data: + if (code[0] == '2') { + socket->write("data\r\n"); + socket->flush(); + state = Body; + } else { + logError(" was rejected by server, msg: "+line); + state = Close; + } + break; + case Body: + if (code[0] == '3') { + socket->write(message + "\r\n.\r\n"); + socket->flush(); + state = Quit; + } else { + logError(" was rejected by server, msg: "+line); + state = Close; + } + break; + case Quit: + if (code[0] == '2') { + socket->write("QUIT\r\n"); + socket->flush(); + // here, we just close. + state = Close; + } else { + logError("Message was rejected by the server, error: "+line); + state = Close; + } + break; + default: + qDebug() << "Disconnecting from host"; + socket->disconnectFromHost(); + return; + } + } +} + +QByteArray Smtp::encode_mime_header(const QString& key, const QString& value, QTextCodec* latin1, const QByteArray& prefix) +{ + QByteArray rv = ""; + QByteArray line = key.toAscii() + ": "; + if (!prefix.isEmpty()) line += prefix; + if (!value.contains("=?") && latin1->canEncode(value)) { + bool firstWord = true; + foreach(const QByteArray& word, value.toAscii().split(' ')) { + if (line.size() > 78) { + rv = rv + line + "\r\n"; + line.clear(); + } + if (firstWord) + line += word; + else + line += " " + word; + firstWord = false; + } + } else { + // The text cannot be losslessly encoded as Latin-1. Therefore, we + // must use base64 encoding. + QByteArray utf8 = value.toUtf8(); + int ct = utf8.length(); + // Use base64 encoding + QByteArray base64 = utf8.toBase64(); + ct = base64.length(); + line += "=?utf-8?b?"; + for (int i = 0; i < ct; i += 4) { + /*if (line.length() > 72) { + rv += line + "?\n\r"; + line = " =?utf-8?b?"; + }*/ + line = line + base64.mid(i, 4); + } + line += "?="; // end encoded-word atom + } + return rv + line + "\r\n"; +} + +void Smtp::ehlo() +{ + QByteArray address = "127.0.0.1"; + foreach(const QHostAddress& addr, QNetworkInterface::allAddresses()) + { + if (addr == QHostAddress::LocalHost || addr == QHostAddress::LocalHostIPv6) + continue; + address = addr.toString().toAscii(); + break; + } + // Send EHLO + socket->write("ehlo "+ address + "\r\n"); + socket->flush(); + state = EhloSent; +} + +void Smtp::parseEhloResponse(const QByteArray& code, bool continued, const QString& line) +{ + if (code != "250") { + // Error + if(state == EhloSent) { + // try to send HELO instead of EHLO + qDebug() << "EHLO failed, trying HELO instead..."; + socket->write("helo\r\n"); + socket->flush(); + state = HeloSent; + } else { + // Both EHLO and HELO failed, chances are this is NOT + // a SMTP server + logError("Both EHLO and HELO failed, msg: "+line); + state = Close; + } + return; + } + if (state != EhloGreetReceived) { + if (!continued) { + // greeting only, no extensions + qDebug() << "No extension"; + state = EhloDone; + } else { + // greeting followed by extensions + state = EhloGreetReceived; + qDebug () << "EHLO greet received"; + return; + } + } else { + qDebug() << Q_FUNC_INFO << "Supported extension: " << line.section(' ', 0, 0).toUpper() + << line.section(' ', 1); + extensions[line.section(' ', 0, 0).toUpper()] = line.section(' ', 1); + if (!continued) + state = EhloDone; + } + if (state != EhloDone) return; + if (extensions.contains("STARTTLS") && use_ssl) { + qDebug() << "STARTTLS"; + startTLS(); + } else { + authenticate(); + } +} + +void Smtp::authenticate() +{ + qDebug() << Q_FUNC_INFO; + if (!extensions.contains("AUTH") || + username.isEmpty() || password.isEmpty()) { + // Skip authentication + qDebug() << "Skipping authentication..."; + state = Authenticated; + return; + } + // AUTH extension is supported, check which + // authentication modes are supported by + // the server + QStringList auth = extensions["AUTH"].toUpper().split(' ', QString::SkipEmptyParts); + if (auth.contains("CRAM-MD5")) { + qDebug() << "Using CRAM-MD5 authentication..."; + authCramMD5(); + } + else if (auth.contains("PLAIN")) { + qDebug() << "Using PLAIN authentication..."; + authPlain(); + } + else if (auth.contains("LOGIN")) { + qDebug() << "Using LOGIN authentication..."; + authLogin(); + } else { + // Skip authentication + logError("The SMTP server does not seem to support any of the authentications modes " + "we support [CRAM-MD5|PLAIN|LOGIN], skipping authentication, " + "knowing it is likely to fail... Server Auth Modes: "+auth.join("|")); + state = Authenticated; + } +} + +void Smtp::startTLS() +{ + qDebug() << Q_FUNC_INFO; +#ifndef QT_NO_OPENSSL + socket->write("starttls\r\n"); + socket->flush(); + state = StartTLSSent; +#else + authenticate(); +#endif +} + +void Smtp::authCramMD5(const QByteArray& challenge) +{ + if (state != AuthRequestSent) { + socket->write("auth cram-md5\r\n"); + socket->flush(); + authType = AuthCramMD5; + state = AuthRequestSent; + } else { + QByteArray response = username.toAscii() + ' ' + + hmacMD5(password.toAscii(), QByteArray::fromBase64(challenge)).toHex(); + socket->write(response.toBase64() + "\r\n"); + socket->flush(); + state = AuthSent; + } +} + +void Smtp::authPlain() +{ + if (state != AuthRequestSent) { + authType = AuthPlain; + // Prepare Auth string + QByteArray auth; + auth += '\0'; + auth += username.toAscii(); + qDebug() << "username: " << username.toAscii(); + auth += '\0'; + auth += password.toAscii(); + qDebug() << "password: " << password.toAscii(); + // Send it + socket->write("auth plain "+ auth.toBase64() + "\r\n"); + socket->flush(); + state = AuthSent; + } +} + +void Smtp::authLogin() +{ + if (state != AuthRequestSent && state != AuthUsernameSent) { + socket->write("auth login\r\n"); + socket->flush(); + authType = AuthLogin; + state = AuthRequestSent; + } + else if (state == AuthRequestSent) { + socket->write(username.toAscii().toBase64() + "\r\n"); + socket->flush(); + state = AuthUsernameSent; + } + else { + socket->write(password.toAscii().toBase64() + "\r\n"); + socket->flush(); + state = AuthSent; + } +} + +void Smtp::logError(const QString &msg) +{ + qDebug() << "Email Notification Error:" << msg; + QBtSession::instance()->addConsoleMessage("Email Notification Error: "+msg, "red"); +} diff --git a/src/smtp.h b/src/smtp.h new file mode 100644 index 000000000..5602f4ac6 --- /dev/null +++ b/src/smtp.h @@ -0,0 +1,98 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +/* + * This code is based on QxtSmtp from libqxt (http://libqxt.org) + */ + +#ifndef SMTP_H +#define SMTP_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QTextStream; +#ifndef QT_NO_OPENSSL +class QSslSocket; +#else +class QTcpSocket; +#endif +class QTextCodec; +QT_END_NAMESPACE + +class Smtp : public QObject { + Q_OBJECT + +public: + Smtp(QObject *parent = 0); + ~Smtp(); + void sendMail(const QString &from, const QString &to, const QString &subject, const QString &body); + +private slots: + void readyRead(); + +private: + QByteArray encode_mime_header(const QString& key, const QString& value, QTextCodec* latin1, const QByteArray& prefix=QByteArray()); + void ehlo(); + void parseEhloResponse(const QByteArray& code, bool continued, const QString& line); + void authenticate(); + void startTLS(); + void authCramMD5(const QByteArray& challenge = QByteArray()); + void authPlain(); + void authLogin(); + void logError(const QString &msg); + +private: + enum states { Rcpt, EhloSent, HeloSent, EhloDone, EhloGreetReceived, AuthRequestSent, AuthSent, + AuthUsernameSent, Authenticated, StartTLSSent, Data, Init, Body, Quit, Close }; + enum AuthType { AuthPlain, AuthLogin, AuthCramMD5 }; + +private: + QByteArray message; +#ifndef QT_NO_OPENSSL + QSslSocket *socket; +#else + QTcpSocket *socket; +#endif + QString from; + QString rcpt; + QString response; + int state; + QHash extensions; + QByteArray buffer; + bool use_ssl; + AuthType authType; + QString username; + QString password; +}; +#endif diff --git a/src/speedlimitdlg.h b/src/speedlimitdlg.h new file mode 100644 index 000000000..ae06906fc --- /dev/null +++ b/src/speedlimitdlg.h @@ -0,0 +1,119 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef BANDWIDTH_ALLOCATION_H +#define BANDWIDTH_ALLOCATION_H + +#include +#include +#include "ui_bandwidth_limit.h" +#include "misc.h" +#include "qbtsession.h" + +class SpeedLimitDialog : public QDialog, private Ui_bandwidth_dlg { + Q_OBJECT + + public: + SpeedLimitDialog(QWidget *parent=0): QDialog(parent) { + setupUi(this); + qDebug("Bandwidth allocation dialog creation"); + // Connect to slots + connect(bandwidthSlider, SIGNAL(valueChanged(int)), this, SLOT(updateSpinValue(int))); + connect(spinBandwidth, SIGNAL(valueChanged(int)), this, SLOT(updateSliderValue(int))); + move(misc::screenCenter(this)); + } + + ~SpeedLimitDialog(){ + qDebug("Deleting bandwidth allocation dialog"); + } + + // -2: if cancel + static long askSpeedLimit(bool *ok, QString title, long default_value, long max_value=10240000) { + SpeedLimitDialog dlg; + dlg.setWindowTitle(title); + dlg.setMaxValue(max_value/1024.); + dlg.setDefaultValue(default_value/1024.); + if(dlg.exec() == QDialog::Accepted) { + *ok = true; + int val = dlg.getSpeedLimit(); + if(val <= 0) + return -1; + return val*1024; + } else { + *ok = false; + return -2; + } + } + + protected slots: + void updateSpinValue(int val) const { + qDebug("Called updateSpinValue with %d", val); + if(val <= 0){ + spinBandwidth->setValue(0); + spinBandwidth->setSpecialValueText(QString::fromUtf8("∞")); + spinBandwidth->setSuffix(QString::fromUtf8("")); + }else{ + spinBandwidth->setValue(val); + spinBandwidth->setSuffix(" "+tr("KiB/s")); + } + } + + void updateSliderValue(int val) const { + if(val <= 0) { + spinBandwidth->setValue(0); + spinBandwidth->setSpecialValueText(QString::fromUtf8("∞")); + spinBandwidth->setSuffix(QString::fromUtf8("")); + } + bandwidthSlider->setValue(val); + } + + long getSpeedLimit() const { + long val = bandwidthSlider->value(); + if(val > 0) + return val; + return -1; + } + + void setMaxValue(long val) const { + if(val > 0) { + bandwidthSlider->setMaximum(val); + spinBandwidth->setMaximum(val); + } + } + + void setDefaultValue(long val) const { + if(val < 0) val = 0; + if(val > bandwidthSlider->maximum()) val = bandwidthSlider->maximum(); + bandwidthSlider->setValue(val); + updateSpinValue(val); + } +}; + +#endif diff --git a/src/src.pro b/src/src.pro new file mode 100644 index 000000000..d299d810c --- /dev/null +++ b/src/src.pro @@ -0,0 +1,219 @@ +# Global +TEMPLATE = app +CONFIG += qt thread + +# Windows specific configuration +win32 { + include(../winconf.pri) +} + +# Mac specific configuration +macx { + include(../macxconf.pri) +} + +# Unix specific configuration +unix:!macx { + include(../unixconf.pri) +} + +# eCS(OS/2) specific configuration +os2 { + include(../os2conf.pri) +} + +nox { + QT -= gui + TARGET = qbittorrent-nox + DEFINES += DISABLE_GUI +} else { + QT += xml + TARGET = qbittorrent +} +QT += network + +# Vars +LANG_PATH = lang +ICONS_PATH = Icons + +CONFIG(debug, debug|release):message(Project is built in DEBUG mode.) +CONFIG(release, debug|release):message(Project is built in RELEASE mode.) + +# Disable debug output in release mode +CONFIG(release, debug|release) { + message(Disabling debug output.) + DEFINES += QT_NO_DEBUG_OUTPUT +} + +# VERSION DEFINES +include(../version.pri) + +DEFINES += QT_NO_CAST_TO_ASCII +# Fast concatenation (Qt >= 4.6) +DEFINES += QT_USE_FAST_CONCATENATION QT_USE_FAST_OPERATOR_PLUS + +# Fixes compilation with Boost >= v1.46 where boost +# filesystem v3 is the default. +DEFINES += BOOST_FILESYSTEM_VERSION=2 + +INCLUDEPATH += $$PWD + + +# Resource files +RESOURCES += icons.qrc \ + lang.qrc \ + about.qrc + +# Source code +usesystemqtsingleapplication { + nox { + CONFIG += qtsinglecoreapplication + } else { + CONFIG += qtsingleapplication + } +} else { + nox { + include(qtsingleapp/qtsinglecoreapplication.pri) + } else { + include(qtsingleapp/qtsingleapplication.pri) + } +} + +include(qtlibtorrent/qtlibtorrent.pri) +include(webui/webui.pri) +include(tracker/tracker.pri) +include (preferences/preferences.pri) + +!nox { + include(lineedit/lineedit.pri) + include(properties/properties.pri) + include(searchengine/searchengine.pri) + include(rss/rss.pri) + include(torrentcreator/torrentcreator.pri) + include(geoip/geoip.pri) + include(powermanagement/powermanagement.pri) +} + +HEADERS += misc.h \ + downloadthread.h \ + stacktrace.h \ + torrentpersistentdata.h \ + filesystemwatcher.h \ + scannedfoldersmodel.h \ + qinisettings.h \ + smtp.h \ + dnsupdater.h + +SOURCES += main.cpp \ + downloadthread.cpp \ + scannedfoldersmodel.cpp \ + misc.cpp \ + smtp.cpp \ + dnsupdater.cpp + +nox { + HEADERS += headlessloader.h +} else { + HEADERS += mainwindow.h\ + transferlistwidget.h \ + transferlistdelegate.h \ + transferlistfilterswidget.h \ + torrentfilesmodel.h \ + deletionconfirmationdlg.h \ + statusbar.h \ + reverseresolution.h \ + ico.h \ + speedlimitdlg.h \ + about_imp.h \ + previewselect.h \ + previewlistdelegate.h \ + downloadfromurldlg.h \ + torrentadditiondlg.h \ + trackerlogin.h \ + hidabletabwidget.h \ + sessionapplication.h \ + torrentimportdlg.h \ + executionlog.h \ + iconprovider.h \ + updownratiodlg.h + + SOURCES += mainwindow.cpp \ + ico.cpp \ + transferlistwidget.cpp \ + torrentadditiondlg.cpp \ + sessionapplication.cpp \ + torrentimportdlg.cpp \ + executionlog.cpp \ + previewselect.cpp \ + iconprovider.cpp \ + updownratiodlg.cpp + + win32 { + HEADERS += programupdater.h + SOURCES += programupdater.cpp + } + + macx { + HEADERS += qmacapplication.h \ + programupdater.h + + SOURCES += qmacapplication.cpp \ + programupdater.cpp + } + + FORMS += mainwindow.ui \ + about.ui \ + preview.ui \ + login.ui \ + downloadfromurldlg.ui \ + torrentadditiondlg.ui \ + bandwidth_limit.ui \ + updownratiodlg.ui \ + confirmdeletiondlg.ui \ + torrentimportdlg.ui \ + executionlog.ui +} + +DESTDIR = . + +# OS specific config +OTHER_FILES += ../winconf.pri ../macxconf.pri ../unixconf.pri ../os2conf.pri +# compiler specific config +OTHER_FILES += ../winconf-mingw.pri ../winconf-msvc.pri +# version file +OTHER_FILES += ../version.pri + +# Translations +TRANSLATIONS = $$LANG_PATH/qbittorrent_fr.ts \ + $$LANG_PATH/qbittorrent_zh.ts \ + $$LANG_PATH/qbittorrent_zh_TW.ts \ + $$LANG_PATH/qbittorrent_en.ts \ + $$LANG_PATH/qbittorrent_ca.ts \ + $$LANG_PATH/qbittorrent_es.ts \ + $$LANG_PATH/qbittorrent_pl.ts \ + $$LANG_PATH/qbittorrent_ko.ts \ + $$LANG_PATH/qbittorrent_de.ts \ + $$LANG_PATH/qbittorrent_nl.ts \ + $$LANG_PATH/qbittorrent_tr.ts \ + $$LANG_PATH/qbittorrent_sv.ts \ + $$LANG_PATH/qbittorrent_el.ts \ + $$LANG_PATH/qbittorrent_ru.ts \ + $$LANG_PATH/qbittorrent_uk.ts \ + $$LANG_PATH/qbittorrent_bg.ts \ + $$LANG_PATH/qbittorrent_it.ts \ + $$LANG_PATH/qbittorrent_sk.ts \ + $$LANG_PATH/qbittorrent_ro.ts \ + $$LANG_PATH/qbittorrent_pt.ts \ + $$LANG_PATH/qbittorrent_nb.ts \ + $$LANG_PATH/qbittorrent_fi.ts \ + $$LANG_PATH/qbittorrent_da.ts \ + $$LANG_PATH/qbittorrent_ja.ts \ + $$LANG_PATH/qbittorrent_hu.ts \ + $$LANG_PATH/qbittorrent_pt_BR.ts \ + $$LANG_PATH/qbittorrent_cs.ts \ + $$LANG_PATH/qbittorrent_sr.ts \ + $$LANG_PATH/qbittorrent_ar.ts \ + $$LANG_PATH/qbittorrent_hr.ts \ + $$LANG_PATH/qbittorrent_gl.ts \ + $$LANG_PATH/qbittorrent_hy.ts \ + $$LANG_PATH/qbittorrent_lt.ts diff --git a/src/stacktrace.h b/src/stacktrace.h new file mode 100644 index 000000000..48dfa9b3b --- /dev/null +++ b/src/stacktrace.h @@ -0,0 +1,94 @@ +// stacktrace.h (c) 2008, Timo Bingmann from http://idlebox.net/ +// published under the WTFPL v2.0 + +#ifndef _STACKTRACE_H_ +#define _STACKTRACE_H_ + +#include +#include +#include +#include + +/** Print a demangled stack backtrace of the caller function to FILE* out. */ +static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames = 63) +{ + fprintf(out, "stack trace:\n"); + + // storage array for stack trace address data + void* addrlist[max_frames+1]; + + // retrieve current stack addresses + int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*)); + + if (addrlen == 0) { + fprintf(out, " \n"); + return; + } + + // resolve addresses into strings containing "filename(function+address)", + // this array must be free()-ed + char** symbollist = backtrace_symbols(addrlist, addrlen); + + // allocate string which will be filled with the demangled function name + size_t funcnamesize = 256; + char* funcname = (char*)malloc(funcnamesize); + + // iterate over the returned symbol lines. skip the first, it is the + // address of this function. + for (int i = 2; i < addrlen; i++) + { + char *begin_name = 0, *begin_offset = 0, *end_offset = 0; + + // find parentheses and +address offset surrounding the mangled name: + // ./module(function+0x15c) [0x8048a6d] + //fprintf(out, "%s TT\n", symbollist[i]); + for (char *p = symbollist[i]; *p; ++p) + { + if (*p == '(') + begin_name = p; + else if (*p == '+') + begin_offset = p; + else if (*p == ')' && begin_offset) { + end_offset = p; + break; + } + } + + if (begin_name && begin_offset && end_offset + && begin_name < begin_offset) + { + *begin_name++ = '\0'; + *begin_offset++ = '\0'; + *end_offset = '\0'; + + // mangled name is now in [begin_name, begin_offset) and caller + // offset in [begin_offset, end_offset). now apply + // __cxa_demangle(): + + int status; + char* ret = abi::__cxa_demangle(begin_name, + funcname, &funcnamesize, &status); + if (status == 0) { + funcname = ret; // use possibly realloc()-ed string + fprintf(out, " %s : %s+%s %s\n", + symbollist[i], funcname, begin_offset, ++end_offset); + } + else { + // demangling failed. Output function name as a C function with + // no arguments. + fprintf(out, " %s : %s()+%s %s\n", + symbollist[i], begin_name, begin_offset, ++end_offset); + } + } + else + { + // couldn't parse the line? print the whole line. + fprintf(out, " %s\n", symbollist[i]); + } + } + + free(funcname); + free(symbollist); +} + +#endif // _STACKTRACE_H_ diff --git a/src/statusbar.h b/src/statusbar.h new file mode 100644 index 000000000..183110f0e --- /dev/null +++ b/src/statusbar.h @@ -0,0 +1,280 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef STATUSBAR_H +#define STATUSBAR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qbtsession.h" +#include "speedlimitdlg.h" +#include "iconprovider.h" +#include "preferences.h" +#include "misc.h" + +class StatusBar: public QObject { + Q_OBJECT + +public: + StatusBar(QStatusBar *bar): m_bar(bar) { + Preferences pref; + connect(QBtSession::instance(), SIGNAL(alternativeSpeedsModeChanged(bool)), this, SLOT(updateAltSpeedsBtn(bool))); + container = new QWidget(bar); + layout = new QHBoxLayout(container); + layout->setContentsMargins(0,0,0,0); + + container->setLayout(layout); + connecStatusLblIcon = new QPushButton(bar); + connecStatusLblIcon->setFlat(true); + connecStatusLblIcon->setFocusPolicy(Qt::NoFocus); + connecStatusLblIcon->setFixedWidth(32); + connecStatusLblIcon->setCursor(Qt::PointingHandCursor); + connecStatusLblIcon->setIcon(QIcon(":/Icons/skin/firewalled.png")); + connecStatusLblIcon->setToolTip(QString::fromUtf8("")+tr("Connection status:")+QString::fromUtf8("
")+QString::fromUtf8("")+tr("No direct connections. This may indicate network configuration problems.")+QString::fromUtf8("")); + dlSpeedLbl = new QPushButton(bar); + dlSpeedLbl->setIconSize(QSize(16,16)); + dlSpeedLbl->setIcon(QIcon(":/Icons/skin/download.png")); + //dlSpeedLbl->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + connect(dlSpeedLbl, SIGNAL(clicked()), this, SLOT(capDownloadSpeed())); + dlSpeedLbl->setFlat(true); + dlSpeedLbl->setFocusPolicy(Qt::NoFocus); + dlSpeedLbl->setCursor(Qt::PointingHandCursor); + + altSpeedsBtn = new QPushButton(bar); + altSpeedsBtn->setFixedWidth(36); + altSpeedsBtn->setIconSize(QSize(32,32)); + altSpeedsBtn->setFlat(true); + altSpeedsBtn->setFocusPolicy(Qt::NoFocus); + altSpeedsBtn->setCursor(Qt::PointingHandCursor); + updateAltSpeedsBtn(pref.isAltBandwidthEnabled()); + + connect(altSpeedsBtn, SIGNAL(clicked()), this, SLOT(toggleAlternativeSpeeds())); + + upSpeedLbl = new QPushButton(bar); + upSpeedLbl->setIconSize(QSize(16,16)); + upSpeedLbl->setIcon(QIcon(":/Icons/skin/seeding.png")); + //upSpeedLbl->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + connect(upSpeedLbl, SIGNAL(clicked()), this, SLOT(capUploadSpeed())); + upSpeedLbl->setFlat(true); + upSpeedLbl->setFocusPolicy(Qt::NoFocus); + upSpeedLbl->setCursor(Qt::PointingHandCursor); + DHTLbl = new QLabel(tr("DHT: %1 nodes").arg(0), bar); + DHTLbl->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + statusSep1 = new QFrame(bar); + statusSep1->setFixedSize(3, dlSpeedLbl->fontMetrics().height()); + statusSep1->setFrameStyle(QFrame::VLine); + statusSep1->setFrameShadow(QFrame::Raised); + statusSep2 = new QFrame(bar); + statusSep2->setFixedSize(3, dlSpeedLbl->fontMetrics().height()); + statusSep2->setFrameStyle(QFrame::VLine); + statusSep2->setFrameShadow(QFrame::Raised); + statusSep3 = new QFrame(bar); + statusSep3->setFixedSize(3, dlSpeedLbl->fontMetrics().height()); + statusSep3->setFrameStyle(QFrame::VLine); + statusSep3->setFrameShadow(QFrame::Raised); + statusSep4 = new QFrame(bar); + statusSep4->setFixedSize(3, dlSpeedLbl->fontMetrics().height()); + statusSep4->setFrameStyle(QFrame::VLine); + statusSep4->setFrameShadow(QFrame::Raised); + layout->addWidget(DHTLbl); + layout->addWidget(statusSep1); + layout->addWidget(connecStatusLblIcon); + layout->addWidget(statusSep2); + layout->addWidget(altSpeedsBtn); + layout->addWidget(statusSep4); + layout->addWidget(dlSpeedLbl); + layout->addWidget(statusSep3); + layout->addWidget(upSpeedLbl); + + bar->addPermanentWidget(container); + container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + //bar->setStyleSheet("QWidget {padding-top: 0; padding-bottom: 0; margin-top: 0; margin-bottom: 0;}\n"); + container->setContentsMargins(0, 0, 0, 1); + bar->setContentsMargins(0, 0, 0, 0); + container->setFixedHeight(dlSpeedLbl->fontMetrics().height()+7); + bar->setContentsMargins(12, 0, 12, 0); + bar->setFixedHeight(dlSpeedLbl->fontMetrics().height()+9); + // Is DHT enabled + DHTLbl->setVisible(pref.isDHTEnabled()); + refreshTimer = new QTimer(bar); + refreshStatusBar(); + connect(refreshTimer, SIGNAL(timeout()), this, SLOT(refreshStatusBar())); + refreshTimer->start(1500); + } + + ~StatusBar() { + qDebug() << Q_FUNC_INFO; + } + + QPushButton* connectionStatusButton() const { + return connecStatusLblIcon; + } + +public slots: + void showRestartRequired() { + // Restart required notification + const QString restart_text = tr("qBittorrent needs to be restarted"); + QLabel *restartIconLbl = new QLabel(m_bar); + restartIconLbl->setPixmap(QPixmap(":/Icons/oxygen/dialog-warning.png").scaled(QSize(24,24))); + restartIconLbl->setToolTip(restart_text); + m_bar->insertWidget(0,restartIconLbl); + QLabel *restartLbl = new QLabel(m_bar); + restartLbl->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); + m_bar->insertWidget(1, restartLbl); + QFontMetrics fm(restartLbl->font()); + restartLbl->setText(fm.elidedText(restart_text, Qt::ElideRight, restartLbl->width())); + QBtSession::instance()->addConsoleMessage(tr("qBittorrent was just updated and needs to be restarted for the changes to be effective."), "red"); + } + + void stopTimer() { + refreshTimer->stop(); + } + + void refreshStatusBar() { + // Update connection status + const libtorrent::session_status sessionStatus = QBtSession::instance()->getSessionStatus(); + if(!QBtSession::instance()->getSession()->is_listening()) { + connecStatusLblIcon->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/disconnected.png"))); + connecStatusLblIcon->setToolTip(QString::fromUtf8("")+tr("Connection Status:")+QString::fromUtf8("
")+tr("Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections.")); + } else { + if(sessionStatus.has_incoming_connections) { + // Connection OK + connecStatusLblIcon->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/connected.png"))); + connecStatusLblIcon->setToolTip(QString::fromUtf8("")+tr("Connection Status:")+QString::fromUtf8("
")+tr("Online")); + }else{ + connecStatusLblIcon->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/firewalled.png"))); + connecStatusLblIcon->setToolTip(QString::fromUtf8("")+tr("Connection status:")+QString::fromUtf8("
")+QString::fromUtf8("")+tr("No direct connections. This may indicate network configuration problems.")+QString::fromUtf8("")); + } + } + // Update Number of DHT nodes + if(QBtSession::instance()->isDHTEnabled()) { + DHTLbl->setVisible(true); + //statusSep1->setVisible(true); + DHTLbl->setText(tr("DHT: %1 nodes").arg(QString::number(sessionStatus.dht_nodes))); + } else { + DHTLbl->setVisible(false); + //statusSep1->setVisible(false); + } + // Update speed labels + dlSpeedLbl->setText(tr("%1/s", "Per second").arg(misc::friendlyUnit(sessionStatus.payload_download_rate))+" ("+misc::friendlyUnit(sessionStatus.total_payload_download)+")"); + upSpeedLbl->setText(tr("%1/s", "Per second").arg(misc::friendlyUnit(sessionStatus.payload_upload_rate))+" ("+misc::friendlyUnit(sessionStatus.total_payload_upload)+")"); + } + + void updateAltSpeedsBtn(bool alternative) { + if(alternative) { + altSpeedsBtn->setIcon(QIcon(":/Icons/slow.png")); + altSpeedsBtn->setToolTip(tr("Click to switch to regular speed limits")); + altSpeedsBtn->setDown(true); + } else { + altSpeedsBtn->setIcon(QIcon(":/Icons/slow_off.png")); + altSpeedsBtn->setToolTip(tr("Click to switch to alternative speed limits")); + altSpeedsBtn->setDown(false); + } + } + + void toggleAlternativeSpeeds() { + QBtSession::instance()->useAlternativeSpeedsLimit(!Preferences().isAltBandwidthEnabled()); + } + + void capDownloadSpeed() { + bool ok = false; +#if LIBTORRENT_VERSION_MINOR > 15 + int cur_limit = QBtSession::instance()->getSession()->settings().download_rate_limit; +#else + int cur_limit = QBtSession::instance()->getSession()->download_rate_limit(); +#endif + long new_limit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Global Download Speed Limit"), cur_limit); + if(ok) { + Preferences pref; + bool alt = pref.isAltBandwidthEnabled(); + if(new_limit <= 0) { + qDebug("Setting global download rate limit to Unlimited"); + QBtSession::instance()->setDownloadRateLimit(-1); + if(!alt) + pref.setGlobalDownloadLimit(-1); + } else { + qDebug("Setting global download rate limit to %.1fKb/s", new_limit/1024.); + QBtSession::instance()->setDownloadRateLimit(new_limit); + if(!alt) + pref.setGlobalDownloadLimit(new_limit/1024.); + } + } + } + + void capUploadSpeed() { + bool ok = false; +#if LIBTORRENT_VERSION_MINOR > 15 + int cur_limit = QBtSession::instance()->getSession()->settings().upload_rate_limit; +#else + int cur_limit = QBtSession::instance()->getSession()->upload_rate_limit(); +#endif + long new_limit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Global Upload Speed Limit"), cur_limit); + if(ok) { + Preferences pref; + bool alt = pref.isAltBandwidthEnabled(); + if(new_limit <= 0) { + qDebug("Setting global upload rate limit to Unlimited"); + QBtSession::instance()->setUploadRateLimit(-1); + if(!alt) + Preferences().setGlobalUploadLimit(-1); + } else { + qDebug("Setting global upload rate limit to %.1fKb/s", new_limit/1024.); + QBtSession::instance()->setUploadRateLimit(new_limit); + if(!alt) + Preferences().setGlobalUploadLimit(new_limit/1024.); + } + } + } + +private: + QStatusBar *m_bar; + QPushButton *dlSpeedLbl; + QPushButton *upSpeedLbl; + QLabel *DHTLbl; + QFrame *statusSep1; + QFrame *statusSep2; + QFrame *statusSep3; + QFrame *statusSep4; + QPushButton *connecStatusLblIcon; + QPushButton *altSpeedsBtn; + QTimer *refreshTimer; + QWidget *container; + QHBoxLayout *layout; + +}; + +#endif // STATUSBAR_H diff --git a/src/torrentadditiondlg.cpp b/src/torrentadditiondlg.cpp new file mode 100644 index 000000000..b7df65214 --- /dev/null +++ b/src/torrentadditiondlg.cpp @@ -0,0 +1,792 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "qbtsession.h" +#include "torrentfilesmodel.h" +#include "preferences.h" +#include "transferlistwidget.h" +#include "qinisettings.h" +#include "misc.h" +#include "proplistdelegate.h" +#include "torrentpersistentdata.h" +#include "iconprovider.h" +#include "torrentadditiondlg.h" +#include "lineedit.h" + +using namespace libtorrent; + +torrentAdditionDialog::torrentAdditionDialog(QWidget *parent) : + QDialog(parent), old_label(""), hidden_height(0) { + const Preferences pref; + setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + // Icons + CancelButton->setIcon(IconProvider::instance()->getIcon("dialog-cancel")); + OkButton->setIcon(IconProvider::instance()->getIcon("list-add")); + // Set Properties list model + PropListModel = new TorrentFilesFilterModel(this); + connect(PropListModel, SIGNAL(filteredFilesChanged()), SLOT(updateDiskSpaceLabels())); + torrentContentList->setModel(PropListModel); + torrentContentList->hideColumn(PROGRESS); + PropDelegate = new PropListDelegate(); + torrentContentList->setItemDelegate(PropDelegate); + connect(torrentContentList, SIGNAL(clicked(const QModelIndex&)), torrentContentList, SLOT(edit(const QModelIndex&))); + connect(torrentContentList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayContentListMenu(const QPoint&))); + connect(selectAllButton, SIGNAL(clicked()), PropListModel, SLOT(selectAll())); + connect(selectNoneButton, SIGNAL(clicked()), PropListModel, SLOT(selectNone())); + connect(comboLabel, SIGNAL(editTextChanged(QString)), this, SLOT(resetComboLabelIndex(QString))); + connect(comboLabel, SIGNAL(editTextChanged(QString)), this, SLOT(updateLabelInSavePath(QString))); + connect(comboLabel, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateLabelInSavePath(QString))); + LineEdit *contentFilterLine = new LineEdit(this); + connect(contentFilterLine, SIGNAL(textChanged(QString)), PropListModel, SLOT(setFilterFixedString(QString))); + contentFilterLayout->insertWidget(1, contentFilterLine); + // Important: as a default, it inserts at the bottom which is not desirable + savePathTxt->setInsertPolicy(QComboBox::InsertAtCurrent); + // Remember columns width + readSettings(); + //torrentContentList->header()->setResizeMode(0, QHeaderView::Stretch); + defaultSavePath = pref.getSavePath(); + appendLabelToSavePath = pref.appendTorrentLabel(); + QString display_path = defaultSavePath.replace("\\", "/"); + if(!display_path.endsWith("/")) + display_path += "/"; + path_history << display_path; +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + display_path = display_path.replace("/", "\\"); +#endif + savePathTxt->addItem(display_path); + + if(pref.addTorrentsInPause()) { + addInPause->setChecked(true); + //addInPause->setEnabled(false); + } + // Load custom labels + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.beginGroup(QString::fromUtf8("TransferListFilters")); + const QStringList customLabels = settings.value("customLabels", QStringList()).toStringList(); + comboLabel->addItem(""); + foreach(const QString& label, customLabels) { + comboLabel->addItem(label); + } + +#if LIBTORRENT_VERSION_MINOR < 15 + addInSeed->setVisible(false); +#endif + // Set Add button as default + OkButton->setDefault(true); +} + +torrentAdditionDialog::~torrentAdditionDialog() { + delete PropDelegate; + delete PropListModel; +} + +void torrentAdditionDialog::closeEvent(QCloseEvent *event) +{ + qDebug() << Q_FUNC_INFO; + saveSettings(); + QDialog::closeEvent(event); +} + +void torrentAdditionDialog::readSettings() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + restoreGeometry(settings.value("TorrentAdditionDlg/dimensions").toByteArray()); + if(!torrentContentList->header()->restoreState(settings.value("TorrentAdditionDlg/ContentHeaderState").toByteArray())) { + qDebug() << Q_FUNC_INFO << "First executation, resize first section to 400px..."; + torrentContentList->header()->resizeSection(0, 400); //Default + } +} + +void torrentAdditionDialog::saveSettings() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.setValue("TorrentAdditionDlg/ContentHeaderState", torrentContentList->header()->saveState()); + settings.setValue("TorrentAdditionDlg/dimensions", saveGeometry()); +} + +void torrentAdditionDialog::limitDialogWidth() { + int scrn = 0; + const QWidget *w = this->window(); + + if(w) + scrn = QApplication::desktop()->screenNumber(w); + else if(QApplication::desktop()->isVirtualDesktop()) + scrn = QApplication::desktop()->screenNumber(QCursor::pos()); + else + scrn = QApplication::desktop()->screenNumber(this); + + QRect desk(QApplication::desktop()->availableGeometry(scrn)); + int max_width = desk.width(); + if(max_width > 0) + setMaximumWidth(max_width); +} + +void torrentAdditionDialog::hideTorrentContent() { + // Disable useless widgets + hidden_height += torrentContentList->height(); + torrentContentList->setVisible(false); + hidden_height += torrentContentLbl->height(); + //torrentContentLbl->setVisible(false); + hidden_height += selectAllButton->height(); + selectNoneButton->setVisible(false); + selectAllButton->setVisible(false); + for(int i=0; icount(); ++i) { + if(contentFilterLayout->itemAt(i)->widget()) + contentFilterLayout->itemAt(i)->widget()->setVisible(false); + } + contentFilterLayout->update(); + + // Resize main window + setMinimumSize(0, 0); + resize(width(), height()-hidden_height); +} + +void torrentAdditionDialog::showLoadMagnetURI(QString magnet_uri) { + show(); + is_magnet = true; + this->from_url = magnet_uri; + + // Disable Save path combox and browse button + // Save path should be default for magnet links + savePathTxt->setEnabled(false); + browseButton->setEnabled(false); + + // Get torrent hash + hash = misc::magnetUriToHash(magnet_uri); + if(hash.isEmpty()) { + QBtSession::instance()->addConsoleMessage(tr("Unable to decode magnet link:")+QString::fromUtf8(" '")+from_url+QString::fromUtf8("'"), QString::fromUtf8("red")); + return; + } + // Set torrent name + fileName = misc::magnetUriToName(magnet_uri); + if(fileName.isEmpty()) { + fileName = tr("Magnet Link"); + } + fileNameLbl->setText(QString::fromUtf8("
")+fileName+QString::fromUtf8("
")); + // Update display + updateDiskSpaceLabels(); + + // No need to display torrent content + hideTorrentContent(); + // Limit dialog width + limitDialogWidth(); +} + +void torrentAdditionDialog::showLoad(QString filePath, QString from_url) { + is_magnet = false; + + // This is an URL to a local file, switch to local path + if(filePath.startsWith("file:", Qt::CaseInsensitive)) + filePath = QUrl::fromEncoded(filePath.toLocal8Bit()).toLocalFile(); + + if(!QFile::exists(filePath)) { + close(); + return; + } + + qDebug() << Q_FUNC_INFO << filePath; + + this->filePath = filePath; + this->from_url = from_url; + // Getting torrent file informations + try { + t = new torrent_info(filePath.toUtf8().data()); + if(!t->is_valid()) + throw std::exception(); + } catch(std::exception&) { + qDebug("Caught error loading torrent"); + if(!from_url.isNull()){ + QBtSession::instance()->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+from_url+QString::fromUtf8("'"), QString::fromUtf8("red")); + misc::safeRemove(filePath); + }else{ + QBtSession::instance()->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+filePath+QString::fromUtf8("'"), QString::fromUtf8("red")); + } + close(); + return; + } + nbFiles = t->num_files(); + if(nbFiles == 0) { + // Empty torrent file!? + close(); + return; + } +#if LIBTORRENT_VERSION_MINOR >= 16 + file_storage fs = t->files(); +#endif + // Truncate root folder + QString root_folder = misc::truncateRootFolder(t); + // Setting file name + fileName = misc::toQStringU(t->name()); + hash = misc::toQString(t->info_hash()); + // Use left() to remove .old extension + QString newFileName; + if(fileName.endsWith(QString::fromUtf8(".old"))){ + newFileName = fileName.left(fileName.size()-4); + }else{ + newFileName = fileName; + } + fileNameLbl->setText(QString::fromUtf8("
")+newFileName+QString::fromUtf8("
")); + if(t->num_files() > 1) { + // List files in torrent + PropListModel->model()->setupModelData(*t); + connect(PropDelegate, SIGNAL(filteredFilesChanged()), this, SLOT(updateDiskSpaceLabels())); + // Loads files path in the torrent + for(uint i=0; i= 16 + files_path << misc::toQStringU(fs.file_path(t->file_at(i))); +#else + files_path << misc::toQStringU(t->file_at(i).path.string()); +#endif + } + + } + + // Load save path history + loadSavePathHistory(); + + // Connect slots + connect(savePathTxt->lineEdit(), SIGNAL(editingFinished()), this, SLOT(updateDiskSpaceLabels())); + connect(savePathTxt->lineEdit(), SIGNAL(editingFinished()), this, SLOT(updateSavePathCurrentText())); + + QString save_path = savePathTxt->currentText(); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + save_path = save_path.replace("/", "\\"); +#endif + if(!save_path.endsWith(QDir::separator())) + save_path += QDir::separator(); + // If the torrent has a root folder, append it to the save path + if(!root_folder.isEmpty()) { + save_path += root_folder; + } + if(nbFiles == 1) { + // single file torrent +#if LIBTORRENT_VERSION_MINOR >= 16 + QString single_file_relpath = misc::toQStringU(fs.file_path(t->file_at(0))); +#else + QString single_file_relpath = misc::toQStringU(t->file_at(0).path.string()); +#endif +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + single_file_relpath = single_file_relpath.replace("/", "\\"); +#endif + save_path += single_file_relpath; + } + savePathTxt->setEditText(save_path); + + // Update size labels + updateDiskSpaceLabels(); + + // Show the dialog + show(); + + // Hide useless widgets + if(t->num_files() <= 1) + hideTorrentContent(); + + // Limit dialog width + limitDialogWidth(); +} + +void torrentAdditionDialog::displayContentListMenu(const QPoint&) { + Q_ASSERT(!is_magnet && t->num_files() > 1); + QMenu myFilesLlistMenu; + const QModelIndexList selectedRows = torrentContentList->selectionModel()->selectedRows(0); + QAction *actRename = 0; + if(selectedRows.size() == 1 && t->num_files() > 1) { + actRename = myFilesLlistMenu.addAction(IconProvider::instance()->getIcon("edit-rename"), tr("Rename...")); + myFilesLlistMenu.addSeparator(); + } + QMenu subMenu; + subMenu.setTitle(tr("Priority")); + subMenu.addAction(actionNot_downloaded); + subMenu.addAction(actionNormal); + subMenu.addAction(actionHigh); + subMenu.addAction(actionMaximum); + myFilesLlistMenu.addMenu(&subMenu); + // Call menu + QAction *act = myFilesLlistMenu.exec(QCursor::pos()); + if(act) { + if(act == actRename) { + renameSelectedFile(); + } else { + int prio = 1; + if(act == actionHigh) { + prio = prio::HIGH; + } else { + if(act == actionMaximum) { + prio = prio::MAXIMUM; + } else { + if(act == actionNot_downloaded) { + prio = prio::IGNORED; + } + } + } + qDebug("Setting files priority"); + foreach(const QModelIndex &index, selectedRows) { + qDebug("Setting priority(%d) for file at row %d", prio, index.row()); + PropListModel->setData(PropListModel->index(index.row(), PRIORITY, index.parent()), prio); + } + } + } +} + +void torrentAdditionDialog::renameSelectedFile() { + Q_ASSERT(!is_magnet && t->num_files() > 1); + const QModelIndexList selectedIndexes = torrentContentList->selectionModel()->selectedRows(0); + Q_ASSERT(selectedIndexes.size() == 1); + const QModelIndex &index = selectedIndexes.first(); + // Ask for new name + bool ok; + const QString new_name_last = QInputDialog::getText(this, tr("Rename the file"), + tr("New name:"), QLineEdit::Normal, + index.data().toString(), &ok); + if (ok && !new_name_last.isEmpty()) { + if(!misc::isValidFileSystemName(new_name_last)) { + QMessageBox::warning(this, tr("The file could not be renamed"), + tr("This file name contains forbidden characters, please choose a different one."), + QMessageBox::Ok); + return; + } + if(PropListModel->getType(index) == TorrentFileItem::TFILE) { + // File renaming + const uint file_index = PropListModel->getFileIndex(index); + QString old_name = files_path.at(file_index); + old_name = old_name.replace("\\", "/"); + qDebug("Old name: %s", qPrintable(old_name)); + QStringList path_items = old_name.split("/"); + path_items.removeLast(); + path_items << new_name_last; + QString new_name = path_items.join("/"); + if(old_name == new_name) { + qDebug("Name did not change"); + return; + } + new_name = QDir::cleanPath(new_name); + qDebug("New name: %s", qPrintable(new_name)); + // Check if that name is already used + for(uint i=0; isetData(index, new_name_last); + } else { + // Folder renaming + QStringList path_items; + path_items << index.data().toString(); + QModelIndex parent = PropListModel->parent(index); + while(parent.isValid()) { + path_items.prepend(parent.data().toString()); + parent = PropListModel->parent(parent); + } + const QString old_path = path_items.join("/"); + path_items.removeLast(); + path_items << new_name_last; + QString new_path = path_items.join("/"); + if(!new_path.endsWith("/")) new_path += "/"; + // Check for overwriting + for(uint i=0; isetData(index, new_name_last); + } + } +} + +void torrentAdditionDialog::updateDiskSpaceLabels() { + qDebug("Updating disk space label..."); + const long long available = misc::freeDiskSpaceOnPath(misc::expandPath(savePathTxt->currentText())); + lbl_disk_space->setText(misc::friendlyUnit(available)); + if(!is_magnet) { + // Determine torrent size + qulonglong torrent_size = 0; + if(t->num_files() > 1) { + const unsigned int nbFiles = t->num_files(); + const std::vector priorities = PropListModel->model()->getFilesPriorities(nbFiles); + + for(unsigned int i=0; i 0) + torrent_size += t->file_at(i).size; + } + } else { + torrent_size = t->total_size(); + } + lbl_torrent_size->setText(misc::friendlyUnit(torrent_size)); + + // Check if free space is sufficient + if(available > 0) { + if((unsigned long long)available > torrent_size) { + // Space is sufficient + label_space_msg->setText(tr("(%1 left after torrent download)", "e.g. (100MiB left after torrent download)").arg(misc::friendlyUnit(available-torrent_size))); + } else { + // Space is unsufficient + label_space_msg->setText(""+tr("(%1 more are required to download)", "e.g. (100MiB more are required to download)").arg(misc::friendlyUnit(torrent_size-available))+""); + } + } else { + // Available disk space is unknown + label_space_msg->setText(""); + } + } +} + +void torrentAdditionDialog::on_browseButton_clicked(){ + Q_ASSERT(!is_magnet); + QString new_path; + QString root_folder; + const QString label_name = comboLabel->currentText(); + if(t->num_files() == 1) { + new_path = QFileDialog::getSaveFileName(this, tr("Choose save path"), savePathTxt->currentText(), QString(), 0, QFileDialog::DontConfirmOverwrite); + if(!new_path.isEmpty()) { + QStringList path_parts = new_path.replace("\\", "/").split("/"); + const QString filename = path_parts.takeLast(); + // Append label + if(QDir(path_parts.join(QDir::separator())) == QDir(defaultSavePath) && !label_name.isEmpty()) + path_parts << label_name; + // Append file name + path_parts << filename; + // Construct new_path + new_path = path_parts.join(QDir::separator()); + } + } else { + QString truncated_path = getCurrentTruncatedSavePath(&root_folder); + if(!truncated_path.isEmpty() && QDir(truncated_path).exists()){ + new_path = QFileDialog::getExistingDirectory(this, tr("Choose save path"), truncated_path); + }else{ + new_path = QFileDialog::getExistingDirectory(this, tr("Choose save path"), QDir::homePath()); + } + if(!new_path.isEmpty()) { + QStringList path_parts = new_path.replace("\\", "/").split("/"); + if(path_parts.last().isEmpty()) + path_parts.removeLast(); + // Append label + if(QDir(new_path) == QDir(defaultSavePath) && !label_name.isEmpty()) + path_parts << label_name; + // Append root folder + if(!root_folder.isEmpty()) + path_parts << root_folder; + // Construct new_path + new_path = path_parts.join(QDir::separator()); + } + } + if(!new_path.isEmpty()) { + // Check if this new path already exists in the list + QString new_truncated_path = getTruncatedSavePath(new_path); +#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) + const int cur_index = path_history.indexOf(QRegExp(new_truncated_path, Qt::CaseInsensitive)); +#else + const int cur_index = path_history.indexOf(QRegExp(new_truncated_path, Qt::CaseSensitive)); +#endif + if(cur_index >= 0) { + savePathTxt->setCurrentIndex(cur_index); + } +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + new_path = new_path.replace("/", "\\"); +#endif + savePathTxt->setEditText(new_path); + } +} + +void torrentAdditionDialog::on_CancelButton_clicked(){ + close(); +} + +bool torrentAdditionDialog::allFiltered() const { + Q_ASSERT(!is_magnet); + return PropListModel->model()->allFiltered(); +} + +void torrentAdditionDialog::savePiecesPriorities(){ + qDebug("Saving pieces priorities"); + Q_ASSERT(!is_magnet); + const std::vector priorities = PropListModel->model()->getFilesPriorities(t->num_files()); + TorrentTempData::setFilesPriority(hash, priorities); +} + +void torrentAdditionDialog::on_OkButton_clicked(){ + qDebug() << "void torrentAdditionDialog::on_OkButton_clicked() - ENTER"; + if(savePathTxt->currentText().trimmed().isEmpty()){ + QMessageBox::critical(0, tr("Empty save path"), tr("Please enter a save path")); + return; + } + QString save_path = savePathTxt->currentText(); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + save_path = save_path.replace("\\", "/"); +#endif + save_path = misc::expandPath(save_path); + qDebug("Save path is %s", qPrintable(save_path)); + if(!is_magnet && t->num_files() == 1) { + // Remove file name + QStringList parts = save_path.split("/"); + const QString single_file_name = parts.takeLast(); + Q_ASSERT(files_path.isEmpty()); + files_path << single_file_name; + save_path = parts.join("/"); + } + qDebug("Save path dir is %s", qPrintable(save_path)); + QDir savePath(save_path); + const QString current_label = comboLabel->currentText().trimmed(); + if (!current_label.isEmpty() && !misc::isValidFileSystemName(current_label)) { + QMessageBox::warning(this, tr("Invalid label name"), tr("Please don't use any special characters in the label name.")); + return; + } + // Save savepath + qDebug("Saving save path to temp data: %s", qPrintable(savePath.absolutePath())); + TorrentTempData::setSavePath(hash, savePath.absolutePath()); + qDebug("Torrent label is: %s", qPrintable(comboLabel->currentText().trimmed())); + if(!current_label.isEmpty()) + TorrentTempData::setLabel(hash, current_label); + // Is download sequential? + TorrentTempData::setSequential(hash, checkIncrementalDL->isChecked()); + // Save files path + // Loads files path in the torrent + if(!is_magnet) { + bool path_changed = false; + for(uint i=0; i= 16 + file_storage fs = t->files(); + QString old_path = misc::toQStringU(fs.file_path(t->file_at(i))); +#else + QString old_path = misc::toQStringU(t->file_at(i).path.string()); +#endif +#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) + if(files_path.at(i).compare(old_path, Qt::CaseSensitive) != 0) { +#else + if(files_path.at(i).compare(old_path, Qt::CaseInsensitive) != 0) { +#endif + path_changed = true; + break; + } + } + if(path_changed) { + qDebug("Changing files paths"); + TorrentTempData::setFilesPath(hash, files_path); + } + } +#if LIBTORRENT_VERSION_MINOR > 14 + // Skip file checking and directly start seeding + if(addInSeed->isChecked()) { + // Check if local file(s) actually exist + if(is_magnet || QFile::exists(savePathTxt->currentText())) { + TorrentTempData::setSeedingMode(hash, true); + } else { + QMessageBox::warning(0, tr("Seeding mode error"), tr("You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path.")); + return; + } + } +#endif + // Check if there is at least one selected file + if(!is_magnet && t->num_files() > 1 && allFiltered()){ + QMessageBox::warning(0, tr("Invalid file selection"), tr("You must select at least one file in the torrent")); + return; + } + // Save path history + saveTruncatedPathHistory(); + // Check if savePath exists + if(!savePath.exists()){ + if(!savePath.mkpath(savePath.path())){ + QMessageBox::critical(0, tr("Save path creation error"), tr("Could not create the save path")); + return; + } + } + // save filtered files + if(!is_magnet && t->num_files() > 1) + savePiecesPriorities(); + // Add to download list + QTorrentHandle h; + if(is_magnet) + h = QBtSession::instance()->addMagnetUri(from_url, false); + else + h = QBtSession::instance()->addTorrent(filePath, false, from_url); + if(addInPause->isChecked() && h.is_valid()) { + h.pause(); + } + // Close the dialog + qDebug("Closing torrent addition dialog..."); + close(); + qDebug("Closed"); +} + +void torrentAdditionDialog::resetComboLabelIndex(QString text) { + // Select first index + if(text != comboLabel->itemText(comboLabel->currentIndex())) { + comboLabel->setItemText(0, text); + comboLabel->setCurrentIndex(0); + } +} + +void torrentAdditionDialog::updateLabelInSavePath(QString label) { + if(appendLabelToSavePath) { + // Update Label in combobox + savePathTxt->setItemText(0, misc::updateLabelInSavePath(defaultSavePath, savePathTxt->itemText(0), old_label, label)); + // update edit text + savePathTxt->setEditText(misc::updateLabelInSavePath(defaultSavePath, savePathTxt->currentText(), old_label, label)); + old_label = label; + } +} + +void torrentAdditionDialog::updateSavePathCurrentText() { + qDebug("updateSavePathCurrentText() - ENTER"); + savePathTxt->setItemText(savePathTxt->currentIndex(), savePathTxt->currentText()); + qDebug("path_history.size() == %d", path_history.size()); + qDebug("savePathTxt->currentIndex() == %d", savePathTxt->currentIndex()); + path_history.replace(savePathTxt->currentIndex(), getCurrentTruncatedSavePath()); + QString root_folder_or_file_name = ""; + getCurrentTruncatedSavePath(&root_folder_or_file_name); + // Update other combo items + for(int i=0; icount(); ++i) { + if(i == savePathTxt->currentIndex()) continue; + QString item_path = path_history.at(i); + if(item_path.isEmpty()) continue; + // Append label + if(i == 0 && appendLabelToSavePath && QDir(item_path) == QDir(defaultSavePath) && !comboLabel->currentText().isEmpty()) + item_path += comboLabel->currentText() + "/"; + // Append root_folder or filename + if(!root_folder_or_file_name.isEmpty()) + item_path += root_folder_or_file_name; +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + item_path = item_path.replace("/", "\\"); +#endif + savePathTxt->setItemText(i, item_path); + } +} + +QString torrentAdditionDialog::getCurrentTruncatedSavePath(QString* root_folder_or_file_name) const { + QString save_path = savePathTxt->currentText(); + return getTruncatedSavePath(save_path, root_folder_or_file_name); +} + +// Get current save path without the torrent root folder nor the label label +QString torrentAdditionDialog::getTruncatedSavePath(QString save_path, QString* root_folder_or_file_name) const { + // Expand and clean path (~, .., .) + save_path = misc::expandPath(save_path); + QStringList parts = save_path.replace("\\", "/").split("/"); + // Remove torrent root folder + if(!QDir(save_path).exists() || (!is_magnet && t->num_files() == 1)) { + QString tmp = parts.takeLast(); + if(root_folder_or_file_name) + *root_folder_or_file_name = tmp; + } + // Remove label + if(appendLabelToSavePath && savePathTxt->currentIndex() == 0 && parts.last() == comboLabel->currentText()) { + parts.removeLast(); + } + QString truncated_path = parts.join("/"); + if(!truncated_path.endsWith("/")) + truncated_path += "/"; + qDebug("Truncated save path: %s", qPrintable(truncated_path)); + return truncated_path; +} + +void torrentAdditionDialog::saveTruncatedPathHistory() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + const QString current_save_path = getCurrentTruncatedSavePath(); + // Get current history + QStringList history = settings.value("TorrentAdditionDlg/save_path_history").toStringList(); +#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) + if(!history.contains(current_save_path, Qt::CaseSensitive)) { +#else + if(!history.contains(current_save_path, Qt::CaseInsensitive)) { +#endif + // Add save path to history + history << current_save_path; + // Limit list size + if(history.size() > 8) + history.removeFirst(); + // Save history + settings.setValue("TorrentAdditionDlg/save_path_history", history); + } +} + +void torrentAdditionDialog::loadSavePathHistory() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + // Load save path history + QStringList raw_path_history = settings.value("TorrentAdditionDlg/save_path_history").toStringList(); + foreach(const QString &sp, raw_path_history) { + if(QDir(sp) != QDir(defaultSavePath)) { + QString dsp = sp; +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + dsp = dsp.replace("/", "\\"); +#endif + path_history << sp; + savePathTxt->addItem(dsp); + } + } +} diff --git a/src/torrentadditiondlg.h b/src/torrentadditiondlg.h new file mode 100644 index 000000000..219cd8aa7 --- /dev/null +++ b/src/torrentadditiondlg.h @@ -0,0 +1,96 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TORRENTADDITION_H +#define TORRENTADDITION_H + +#include + +#include "ui_torrentadditiondlg.h" + +#include + +class TorrentFilesFilterModel; +class PropListDelegate; + +class torrentAdditionDialog : public QDialog, private Ui_addTorrentDialog{ + Q_OBJECT + +public: + torrentAdditionDialog(QWidget *parent); + ~torrentAdditionDialog(); + void showLoadMagnetURI(QString magnet_uri); + void showLoad(QString filePath, QString from_url=QString::null); + QString getCurrentTruncatedSavePath(QString* root_folder_or_file_name = 0) const; + QString getTruncatedSavePath(QString save_path, QString* root_folder_or_file_name = 0) const; + bool allFiltered() const; + +public slots: + void displayContentListMenu(const QPoint&); + void renameSelectedFile(); + void updateDiskSpaceLabels(); + void on_browseButton_clicked(); + void on_CancelButton_clicked(); + void savePiecesPriorities(); + void on_OkButton_clicked(); + void hideTorrentContent(); + void limitDialogWidth(); + void saveTruncatedPathHistory(); + void loadSavePathHistory(); + void updateLabelInSavePath(QString label); + void updateSavePathCurrentText(); + void resetComboLabelIndex(QString text); + +protected: + void closeEvent(QCloseEvent *event); + +private: + void readSettings(); + void saveSettings(); + +private: + QString fileName; + QString hash; + QString filePath; + QString from_url; + QString defaultSavePath; + QString old_label; + bool appendLabelToSavePath; + TorrentFilesFilterModel *PropListModel; + PropListDelegate *PropDelegate; + unsigned int nbFiles; + boost::intrusive_ptr t; + QStringList files_path; + bool is_magnet; + int hidden_height; + QStringList path_history; +}; + +#endif diff --git a/src/torrentadditiondlg.ui b/src/torrentadditiondlg.ui new file mode 100644 index 000000000..ae3a4f1a3 --- /dev/null +++ b/src/torrentadditiondlg.ui @@ -0,0 +1,361 @@ + + + addTorrentDialog + + + + 0 + 0 + 560 + 517 + + + + Torrent addition dialog + + + + + + + + + + + + + Qt::Horizontal + + + + + + + + + + 0 + 0 + + + + Save path: + + + + + + + + 0 + 0 + + + + true + + + + + + + ... + + + + + + + + + + + Torrent size: + + + + + + + Unknown + + + + + + + - + + + + + + + Free disk space: + + + + + + + Unknown + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Label: + + + + + + + + 180 + 0 + + + + + 16777215 + 26 + + + + true + + + true + + + + + + + Qt::Horizontal + + + + 40 + 17 + + + + + + + + + + + + + 75 + true + + + + Torrent content: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::ExtendedSelection + + + true + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Select All + + + + + + + Select None + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Download in sequential order (slower but good for previewing) + + + + + + + Skip file checking and start seeding immediately + + + + + + + Add to download list in paused state + + + + + + + 6 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Add + + + + + + + Cancel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Normal + + + + + High + + + + + Maximum + + + + + Do not download + + + Do not download + + + + + + diff --git a/src/torrentcreator/createtorrent.ui b/src/torrentcreator/createtorrent.ui new file mode 100644 index 000000000..d68ecaffb --- /dev/null +++ b/src/torrentcreator/createtorrent.ui @@ -0,0 +1,314 @@ + + + createTorrentDialog + + + + 0 + 0 + 592 + 658 + + + + Torrent Creation Tool + + + + + + + 0 + 27 + + + + + 16777215 + 27 + + + + + Sans Serif + 14 + 75 + false + true + false + false + + + + Torrent file creation + + + Qt::AlignCenter + + + + + + + File or folder to add to the torrent: + + + + + + + + + + + + Add file + + + + + + + Add folder + + + + + + + + + + + Tracker URLs: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Web seeds urls: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Comment: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + false + + + + + + + + 0 + 0 + + + + false + + + + + + + false + + + + + + + + + + + Piece size: + + + + + + + false + + + false + + + 3 + + + + 32 KiB + + + + + 64 KiB + + + + + 128 KiB + + + + + 256 KiB + + + + + 512 KiB + + + + + 1 MiB + + + + + 2 MiB + + + + + 4 MiB + + + + + + + + Auto + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Private (won't be distributed on DHT network if enabled) + + + + + + + Start seeding after creation + + + + + + + Progress: + + + + + + + 0 + + + + + + + 6 + + + 0 + + + + + Qt::Horizontal + + + + 131 + 31 + + + + + + + + Create and save... + + + + + + + Cancel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + diff --git a/src/torrentcreator/torrentcreator.pri b/src/torrentcreator/torrentcreator.pri new file mode 100644 index 000000000..9be087937 --- /dev/null +++ b/src/torrentcreator/torrentcreator.pri @@ -0,0 +1,10 @@ +INCLUDEPATH += $$PWD + +FORMS += $$PWD/createtorrent.ui + +HEADERS += $$PWD/torrentcreatordlg.h \ + $$PWD/torrentcreatorthread.h + +SOURCES += $$PWD/torrentcreatordlg.cpp \ + $$PWD/torrentcreatorthread.cpp + diff --git a/src/torrentcreator/torrentcreatordlg.cpp b/src/torrentcreator/torrentcreatordlg.cpp new file mode 100644 index 000000000..d28a7d054 --- /dev/null +++ b/src/torrentcreator/torrentcreatordlg.cpp @@ -0,0 +1,282 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include + +#include "torrentpersistentdata.h" +#include "torrentcreatordlg.h" +#include "misc.h" +#include "qinisettings.h" +#include "torrentcreatorthread.h" +#include "iconprovider.h" + +const uint NB_PIECES_MIN = 1200; +const uint NB_PIECES_MAX = 2200; + +using namespace libtorrent; + +TorrentCreatorDlg::TorrentCreatorDlg(QWidget *parent): QDialog(parent), creatorThread(0) { + setupUi(this); + // Icons + addFile_button->setIcon(IconProvider::instance()->getIcon("document-new")); + addFolder_button->setIcon(IconProvider::instance()->getIcon("folder-new")); + createButton->setIcon(IconProvider::instance()->getIcon("document-save")); + cancelButton->setIcon(IconProvider::instance()->getIcon("dialog-cancel")); + + setAttribute(Qt::WA_DeleteOnClose); + setModal(true); + showProgressBar(false); + loadTrackerList(); + // Piece sizes + m_piece_sizes << 32 << 64 << 128 << 256 << 512 << 1024 << 2048 << 4096; + loadSettings(); + show(); +} + +TorrentCreatorDlg::~TorrentCreatorDlg() { + if(creatorThread) + delete creatorThread; +} + +void TorrentCreatorDlg::on_addFolder_button_clicked(){ + QIniSettings settings("qBittorrent", "qBittorrent"); + QString last_path = settings.value("CreateTorrent/last_add_path", QDir::homePath()).toString(); + QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), last_path, QFileDialog::ShowDirsOnly); + if(!dir.isEmpty()) { + settings.setValue("CreateTorrent/last_add_path", dir); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + dir = dir.replace("/", "\\"); +#endif + textInputPath->setText(dir); + // Update piece size + if(checkAutoPieceSize->isChecked()) + updateOptimalPieceSize(); + } +} + +void TorrentCreatorDlg::on_addFile_button_clicked(){ + QIniSettings settings("qBittorrent", "qBittorrent"); + QString last_path = settings.value("CreateTorrent/last_add_path", QDir::homePath()).toString(); + QString file = QFileDialog::getOpenFileName(this, tr("Select a file to add to the torrent"), last_path); + if(!file.isEmpty()) { + settings.setValue("CreateTorrent/last_add_path", misc::removeLastPathPart(file)); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + file = file.replace("/", "\\"); +#endif + textInputPath->setText(file); + // Update piece size + if(checkAutoPieceSize->isChecked()) + updateOptimalPieceSize(); + } +} + +int TorrentCreatorDlg::getPieceSize() const { + return m_piece_sizes.at(comboPieceSize->currentIndex())*1024; +} + +// Main function that create a .torrent file +void TorrentCreatorDlg::on_createButton_clicked(){ + QString input = textInputPath->text().trimmed(); + if (input.endsWith(QDir::separator())) + input.chop(1); + if(input.isEmpty()){ + QMessageBox::critical(0, tr("No input path set"), tr("Please type an input path first")); + return; + } + QStringList trackers = trackers_list->toPlainText().split("\n"); + if(!trackers_list->toPlainText().trimmed().isEmpty()) + saveTrackerList(); + + QIniSettings settings("qBittorrent", "qBittorrent"); + QString last_path = settings.value("CreateTorrent/last_save_path", QDir::homePath()).toString(); + + QString destination = QFileDialog::getSaveFileName(this, tr("Select destination torrent file"), last_path, tr("Torrent Files")+QString::fromUtf8(" (*.torrent)")); + if(!destination.isEmpty()) { + settings.setValue("CreateTorrent/last_save_path", misc::removeLastPathPart(destination)); + if(!destination.toUpper().endsWith(".TORRENT")) + destination += QString::fromUtf8(".torrent"); + } else { + return; + } + // Disable dialog + setInteractionEnabled(false); + showProgressBar(true); + // Set busy cursor + setCursor(QCursor(Qt::WaitCursor)); + // Actually create the torrent + QStringList url_seeds = URLSeeds_list->toPlainText().split("\n"); + QString comment = txt_comment->toPlainText(); + // Create the creator thread + creatorThread = new TorrentCreatorThread(this); + connect(creatorThread, SIGNAL(creationSuccess(QString, QString)), this, SLOT(handleCreationSuccess(QString, QString))); + connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString))); + connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int))); + creatorThread->create(input, destination, trackers, url_seeds, comment, check_private->isChecked(), getPieceSize()); +} + +void TorrentCreatorDlg::handleCreationFailure(QString msg) { + // Remove busy cursor + setCursor(QCursor(Qt::ArrowCursor)); + QMessageBox::information(0, tr("Torrent creation"), tr("Torrent creation was unsuccessful, reason: %1").arg(msg)); + setInteractionEnabled(true); + showProgressBar(false); +} + +void TorrentCreatorDlg::handleCreationSuccess(QString path, QString branch_path) { + // Remove busy cursor + setCursor(QCursor(Qt::ArrowCursor)); + if(checkStartSeeding->isChecked()) { + QString root_folder; + // Create save path temp data + boost::intrusive_ptr t; + try { + t = new torrent_info(path.toUtf8().data()); + root_folder = misc::truncateRootFolder(t); + } catch(std::exception&) { + QMessageBox::critical(0, tr("Torrent creation"), tr("Created torrent file is invalid. It won't be added to download list.")); + return; + } + QString hash = misc::toQString(t->info_hash()); + QString save_path = branch_path; + if(!root_folder.isEmpty()) { + save_path = QDir(save_path).absoluteFilePath(root_folder); + } + TorrentTempData::setSavePath(hash, save_path); +#if LIBTORRENT_VERSION_MINOR > 14 + // Enable seeding mode (do not recheck the files) + TorrentTempData::setSeedingMode(hash, true); +#endif + emit torrent_to_seed(path); + } + QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+path); + close(); +} + +void TorrentCreatorDlg::on_cancelButton_clicked() { + // End torrent creation thread + if(creatorThread && creatorThread->isRunning()) { + creatorThread->abortCreation(); + creatorThread->terminate(); + // Wait for termination + creatorThread->wait(); + } + // Close the dialog + close(); +} + +void TorrentCreatorDlg::updateProgressBar(int progress) { + progressBar->setValue(progress); +} + +void TorrentCreatorDlg::setInteractionEnabled(bool enabled) +{ + textInputPath->setEnabled(enabled); + addFile_button->setEnabled(enabled); + addFolder_button->setEnabled(enabled); + trackers_list->setEnabled(enabled); + URLSeeds_list->setEnabled(enabled); + txt_comment->setEnabled(enabled); + comboPieceSize->setEnabled(enabled); + check_private->setEnabled(enabled); + checkStartSeeding->setEnabled(enabled); + createButton->setEnabled(enabled); + //cancelButton->setEnabled(!enabled); +} + +void TorrentCreatorDlg::showProgressBar(bool show) +{ + progressLbl->setVisible(show); + progressBar->setVisible(show); +} + +void TorrentCreatorDlg::on_checkAutoPieceSize_clicked(bool checked) +{ + comboPieceSize->setEnabled(!checked); + if(checked) { + updateOptimalPieceSize(); + } +} + +void TorrentCreatorDlg::updateOptimalPieceSize() +{ + quint64 torrent_size = misc::computePathSize(textInputPath->text()); + qDebug("Torrent size is %lld", torrent_size); + if(torrent_size == 0) return; + int i = 0; + qulonglong nb_pieces = 0; + do { + nb_pieces = (double)torrent_size/(m_piece_sizes.at(i)*1024.); + qDebug("nb_pieces=%lld with piece_size=%s", nb_pieces, qPrintable(comboPieceSize->itemText(i))); + if(nb_pieces <= NB_PIECES_MIN) { + if(i > 1) + --i; + break; + } + if(nb_pieces < NB_PIECES_MAX) { + qDebug("Good, nb_pieces=%lld < %d", nb_pieces, NB_PIECES_MAX); + break; + } + ++i; + }while(isetCurrentIndex(i); +} + +void TorrentCreatorDlg::saveTrackerList() +{ + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.setValue("CreateTorrent/TrackerList", trackers_list->toPlainText()); +} + +void TorrentCreatorDlg::loadTrackerList() +{ + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + trackers_list->setPlainText(settings.value("CreateTorrent/TrackerList", "").toString()); +} + +void TorrentCreatorDlg::saveSettings() +{ + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.setValue("CreateTorrent/dimensions", saveGeometry()); +} + +void TorrentCreatorDlg::loadSettings() +{ + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + restoreGeometry(settings.value("CreateTorrent/dimensions").toByteArray()); +} + +void TorrentCreatorDlg::closeEvent(QCloseEvent *event) +{ + qDebug() << Q_FUNC_INFO; + saveSettings(); + QDialog::closeEvent(event); +} diff --git a/src/torrentcreator/torrentcreatordlg.h b/src/torrentcreator/torrentcreatordlg.h new file mode 100644 index 000000000..cda947d52 --- /dev/null +++ b/src/torrentcreator/torrentcreatordlg.h @@ -0,0 +1,78 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef CREATE_TORRENT_IMP_H +#define CREATE_TORRENT_IMP_H + +#include "ui_createtorrent.h" + +class TorrentCreatorThread; + +class TorrentCreatorDlg : public QDialog, private Ui::createTorrentDialog{ + Q_OBJECT + +public: + TorrentCreatorDlg(QWidget *parent = 0); + ~TorrentCreatorDlg(); + int getPieceSize() const; + +signals: + void torrent_to_seed(QString path); + +public slots: + void updateProgressBar(int progress); + void on_cancelButton_clicked(); + +protected slots: + void on_createButton_clicked(); + void on_addFile_button_clicked(); + void on_addFolder_button_clicked(); + void handleCreationFailure(QString msg); + void handleCreationSuccess(QString path, QString branch_path); + void setInteractionEnabled(bool enabled); + void showProgressBar(bool show); + void on_checkAutoPieceSize_clicked(bool checked); + void updateOptimalPieceSize(); + void saveTrackerList(); + void loadTrackerList(); + +protected: + void closeEvent(QCloseEvent *event); + +private: + void saveSettings(); + void loadSettings(); + +private: + TorrentCreatorThread *creatorThread; + QList m_piece_sizes; +}; + +#endif diff --git a/src/torrentcreator/torrentcreatorthread.cpp b/src/torrentcreator/torrentcreatorthread.cpp new file mode 100644 index 000000000..aa6a9da63 --- /dev/null +++ b/src/torrentcreator/torrentcreatorthread.cpp @@ -0,0 +1,130 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "torrentcreatorthread.h" +#include "misc.h" + +using namespace libtorrent; +using namespace boost::filesystem; + +// do not include files and folders whose +// name starts with a . +bool file_filter(boost::filesystem::path const& filename) +{ + if (filename.leaf()[0] == '.') return false; + std::cerr << filename << std::endl; + return true; +} + +void TorrentCreatorThread::create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size) +{ + input_path = _input_path; + save_path = _save_path; + if(QFile(save_path).exists()) + misc::safeRemove(save_path); + trackers = _trackers; + url_seeds = _url_seeds; + comment = _comment; + is_private = _is_private; + piece_size = _piece_size; + path::default_name_check(no_check); + abort = false; + start(); +} + +void sendProgressUpdateSignal(int i, int num, TorrentCreatorThread *parent){ + parent->sendProgressSignal((int)(i*100./(float)num)); +} + +void TorrentCreatorThread::sendProgressSignal(int progress) { + emit updateProgress(progress); +} + +void TorrentCreatorThread::run() { + emit updateProgress(0); + QString creator_str("qBittorrent "VERSION); + try { + file_storage fs; + // Adding files to the torrent + libtorrent::add_files(fs, input_path.toUtf8().constData(), file_filter); + if(abort) return; + create_torrent t(fs, piece_size); + + // Add url seeds + foreach(const QString &seed, url_seeds){ + t.add_url_seed(seed.trimmed().toStdString()); + } + foreach(const QString &tracker, trackers) { + t.add_tracker(tracker.trimmed().toStdString()); + } + if(abort) return; + // calculate the hash for all pieces + const QString parent_path = misc::branchPath(input_path); + set_piece_hashes(t, parent_path.toUtf8().constData(), boost::bind(&sendProgressUpdateSignal, _1, t.num_pieces(), this)); + // Set qBittorrent as creator and add user comment to + // torrent_info structure + t.set_creator(creator_str.toUtf8().constData()); + t.set_comment(comment.toUtf8().constData()); + // Is private ? + t.set_priv(is_private); + if(abort) return; + // create the torrent and print it to out + qDebug("Saving to %s", qPrintable(save_path)); + std::vector torrent; + bencode(back_inserter(torrent), t.generate()); + QFile outfile(save_path); + if(!torrent.empty() && outfile.open(QIODevice::WriteOnly)) { + outfile.write(&torrent[0], torrent.size()); + outfile.close(); + emit updateProgress(100); + emit creationSuccess(save_path, parent_path); + } else { + throw std::exception(); + } + } catch (std::exception& e){ + emit creationFailure(QString::fromLocal8Bit(e.what())); + } +} diff --git a/src/torrentcreator/torrentcreatorthread.h b/src/torrentcreator/torrentcreatorthread.h new file mode 100644 index 000000000..3e87008d6 --- /dev/null +++ b/src/torrentcreator/torrentcreatorthread.h @@ -0,0 +1,73 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TORRENTCREATORTHREAD_H +#define TORRENTCREATORTHREAD_H + +#include +#include +#include + +class TorrentCreatorThread : public QThread { + Q_OBJECT + +public: + TorrentCreatorThread(QDialog *_parent) { + parent = _parent; + } + ~TorrentCreatorThread() { + abort = true; + wait(); + } + void create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size); + void sendProgressSignal(int progress); + void abortCreation() { abort = true; } + +protected: + void run(); + +signals: + void creationFailure(QString msg); + void creationSuccess(QString path, QString branch_path); + void updateProgress(int progress); + +private: + QString input_path; + QString save_path; + QStringList trackers; + QStringList url_seeds; + QString comment; + bool is_private; + int piece_size; + bool abort; + QDialog *parent; +}; + +#endif // TORRENTCREATORTHREAD_H diff --git a/src/torrentfilesmodel.h b/src/torrentfilesmodel.h new file mode 100644 index 000000000..aac58060c --- /dev/null +++ b/src/torrentfilesmodel.h @@ -0,0 +1,680 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TORRENTFILESMODEL_H +#define TORRENTFILESMODEL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "proplistdelegate.h" +#include "iconprovider.h" + +namespace prio { +enum FilePriority {IGNORED=0, NORMAL=1, HIGH=2, MAXIMUM=7, PARTIAL=-1}; +} + +class TorrentFileItem { + +public: + enum TreeItemColumns {COL_NAME, COL_SIZE, COL_PROGRESS, COL_PRIO, NB_COL}; + enum FileType {TFILE, FOLDER, ROOT}; + +private: + QList childItems; + QList itemData; + TorrentFileItem *parentItem; + FileType m_type; + qulonglong total_done; + int file_index; + +public: + // File Construction + TorrentFileItem(const libtorrent::torrent_info &t, const libtorrent::file_entry &f, TorrentFileItem *parent, int _file_index) { + Q_ASSERT(parent); + parentItem = parent; + m_type = TFILE; + file_index = _file_index; +#if LIBTORRENT_VERSION_MINOR >= 16 + QString name = misc::fileName(misc::toQStringU(t.files().file_path(f))); +#else + Q_UNUSED(t); + QString name = misc::toQStringU(f.path.filename()); +#endif + // Do not display incomplete extensions + if(name.endsWith(".!qB")) + name.chop(4); + itemData << name; + //qDebug("Created a TreeItem file with name %s", qPrintable(getName())); + //qDebug("parent is %s", qPrintable(parent->getName())); + itemData << QVariant((qulonglong)f.size); + total_done = 0; + itemData << 0.; // Progress; + itemData << prio::NORMAL; // Priority + if(parent) { + parent->appendChild(this); + parent->updateSize(); + } + } + + // Folder constructor + TorrentFileItem(QString name, TorrentFileItem *parent=0) { + parentItem = parent; + m_type = FOLDER; + // Do not display incomplete extensions + if(name.endsWith(".!qB")) + name.chop(4); + itemData << name; + itemData << 0.; // Size + itemData << 0.; // Progress; + total_done = 0; + itemData << prio::NORMAL; // Priority + if(parent) { + parent->appendChild(this); + } + } + + TorrentFileItem(QList data) { + parentItem = 0; + m_type = ROOT; + Q_ASSERT(data.size() == 4); + itemData = data; + total_done = 0; + } + + ~TorrentFileItem() { + qDebug("Deleting item: %s", qPrintable(getName())); + qDeleteAll(childItems); + } + + FileType getType() const { + return m_type; + } + + int getFileIndex() const { + Q_ASSERT(m_type ==TFILE); + return file_index; + } + + void deleteAllChildren() { + Q_ASSERT(m_type==ROOT); + qDeleteAll(childItems); + childItems.clear(); + Q_ASSERT(childItems.empty()); + } + + QList children() const { + return childItems; + } + + QString getName() const { + //Q_ASSERT(type != ROOT); + return itemData.at(COL_NAME).toString(); + } + + void setName(QString name) { + Q_ASSERT(m_type != ROOT); + itemData.replace(COL_NAME, name); + } + + qulonglong getSize() const { + return itemData.value(COL_SIZE).toULongLong(); + } + + void setSize(qulonglong size) { + if(getSize() == size) return; + itemData.replace(COL_SIZE, (qulonglong)size); + if(parentItem) + parentItem->updateSize(); + } + + void updateSize() { + if(m_type == ROOT) return; + Q_ASSERT(m_type == FOLDER); + qulonglong size = 0; + foreach(TorrentFileItem* child, childItems) { + if(child->getPriority() != prio::IGNORED) + size += child->getSize(); + } + setSize(size); + } + + void setProgress(qulonglong done) { + if(getPriority() == 0) return; + total_done = done; + qulonglong size = getSize(); + Q_ASSERT(total_done <= size); + qreal progress; + if(size > 0) + progress = total_done/(float)size; + else + progress = 1.; + Q_ASSERT(progress >= 0. && progress <= 1.); + itemData.replace(COL_PROGRESS, progress); + if(parentItem) + parentItem->updateProgress(); + } + + qulonglong getTotalDone() const { + return total_done; + } + + qreal getProgress() const { + if(getPriority() == 0) + return 0.; + qulonglong size = getSize(); + if(size > 0) + return total_done/(float)getSize(); + return 1.; + } + + void updateProgress() { + if(m_type == ROOT) return; + Q_ASSERT(m_type == FOLDER); + total_done = 0; + foreach(TorrentFileItem* child, childItems) { + if(child->getPriority() > 0) + total_done += child->getTotalDone(); + } + //qDebug("Folder: total_done: %llu/%llu", total_done, getSize()); + Q_ASSERT(total_done <= getSize()); + setProgress(total_done); + } + + int getPriority() const { + return itemData.value(COL_PRIO).toInt(); + } + + void setPriority(int new_prio, bool update_parent=true) { + Q_ASSERT(new_prio != prio::PARTIAL || m_type == FOLDER); // PARTIAL only applies to folders + const int old_prio = getPriority(); + if(old_prio == new_prio) return; + qDebug("setPriority(%s, %d)", qPrintable(getName()), new_prio); + // Reset progress if priority is 0 + if(new_prio == 0) { + setProgress(0); + } + + itemData.replace(COL_PRIO, new_prio); + + // Update parent + if(update_parent && parentItem) { + qDebug("Updating parent item"); + parentItem->updateSize(); + parentItem->updateProgress(); + parentItem->updatePriority(); + } + + // Update children + if(new_prio != prio::PARTIAL && !childItems.empty()) { + qDebug("Updating children items"); + foreach(TorrentFileItem* child, childItems) { + // Do not update the parent since + // the parent is causing the update + child->setPriority(new_prio, false); + } + } + if(m_type == FOLDER) { + updateSize(); + updateProgress(); + } + } + + // Only non-root folders use this function + void updatePriority() { + if(m_type == ROOT) return; + Q_ASSERT(m_type == FOLDER); + if(childItems.isEmpty()) return; + // If all children have the same priority + // then the folder should have the same + // priority + const int prio = childItems.first()->getPriority(); + for(int i=1; igetPriority() != prio) { + setPriority(prio::PARTIAL); + return; + } + } + // All child items have the same priorrity + // Update mine if necessary + if(prio != getPriority()) + setPriority(prio); + } + + TorrentFileItem* childWithName(QString name) const { + foreach(TorrentFileItem *child, childItems) { + if(child->getName() == name) return child; + } + return 0; + } + + bool isFolder() const { + return (m_type==FOLDER); + } + + void appendChild(TorrentFileItem *item) { + Q_ASSERT(item); + //Q_ASSERT(!childWithName(item->getName())); + Q_ASSERT(m_type != TFILE); + int i=0; + for(i=0; igetName(); + if(QString::localeAwareCompare(newchild_name, childItems.at(i)->getName()) < 0) break; + } + childItems.insert(i, item); + //childItems.append(item); + //Q_ASSERT(type != ROOT || childItems.size() == 1); + } + + TorrentFileItem *child(int row) { + //Q_ASSERT(row >= 0 && row < childItems.size()); + return childItems.value(row, 0); + } + + int childCount() const { + return childItems.count(); + } + + int columnCount() const { + return itemData.count(); + } + + QVariant data(int column) const { + return itemData.value(column); + } + + int row() const { + if (parentItem) { + return parentItem->children().indexOf(const_cast(this)); + } + return 0; + } + + TorrentFileItem *parent() { + return parentItem; + } +}; + + +class TorrentFilesModel: public QAbstractItemModel { + Q_OBJECT + +private: + TorrentFileItem *rootItem; + TorrentFileItem **files_index; + +public: + TorrentFilesModel(QObject *parent=0): QAbstractItemModel(parent) { + files_index = 0; + QList rootData; + rootData << tr("Name") << tr("Size") << tr("Progress") << tr("Priority"); + rootItem = new TorrentFileItem(rootData); + } + + ~TorrentFilesModel() { + qDebug() << Q_FUNC_INFO << "ENTER"; + delete [] files_index; + delete rootItem; + qDebug() << Q_FUNC_INFO << "EXIT"; + } + + void updateFilesProgress(std::vector fp) { + emit layoutAboutToBeChanged(); + for(unsigned int i=0; i= 0); + files_index[i]->setProgress(fp[i]); + } + emit dataChanged(index(0,0), index(rowCount(), columnCount())); + } + + void updateFilesPriorities(const std::vector &fprio) { + emit layoutAboutToBeChanged(); + for(unsigned int i=0; isetPriority(fprio[i]); + } + emit dataChanged(index(0,0), index(rowCount(), columnCount())); + } + + std::vector getFilesPriorities(unsigned int nbFiles) const { + std::vector prio; + for(unsigned int i=0; igetPriority()); + prio.push_back(files_index[i]->getPriority()); + } + return prio; + } + + bool allFiltered() const { + for(int i=0; ichildCount(); ++i) { + if(rootItem->child(i)->getPriority() != prio::IGNORED) + return false; + } + return true; + } + + int columnCount(const QModelIndex &parent=QModelIndex()) const { + if (parent.isValid()) + return static_cast(parent.internalPointer())->columnCount(); + else + return rootItem->columnCount(); + } + + bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) { + if(!index.isValid()) return false; + if (index.column() == 0 && role == Qt::CheckStateRole) { + TorrentFileItem *item = static_cast(index.internalPointer()); + qDebug("setData(%s, %d", qPrintable(item->getName()), value.toInt()); + if(item->getPriority() != value.toInt()) { + if(value.toInt() == Qt::PartiallyChecked) + item->setPriority(prio::PARTIAL); + else if (value.toInt() == Qt::Unchecked) + item->setPriority(prio::IGNORED); + else + item->setPriority(prio::NORMAL); + emit dataChanged(this->index(0,0), this->index(rowCount(), columnCount())); + emit filteredFilesChanged(); + } + return true; + } + if (role == Qt::EditRole) { + TorrentFileItem *item = static_cast(index.internalPointer()); + switch(index.column()) { + case TorrentFileItem::COL_NAME: + item->setName(value.toString()); + break; + case TorrentFileItem::COL_SIZE: + item->setSize(value.toULongLong()); + break; + case TorrentFileItem::COL_PROGRESS: + item->setProgress(value.toDouble()); + break; + case TorrentFileItem::COL_PRIO: + item->setPriority(value.toInt()); + break; + default: + return false; + } + emit dataChanged(index, index); + return true; + } + return false; + } + + TorrentFileItem::FileType getType(const QModelIndex &index) const { + const TorrentFileItem *item = static_cast(index.internalPointer()); + return item->getType(); + } + + int getFileIndex(const QModelIndex &index) { + TorrentFileItem *item = static_cast(index.internalPointer()); + return item->getFileIndex(); + } + + QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { + if (!index.isValid()) + return QVariant(); + TorrentFileItem *item = static_cast(index.internalPointer()); + if(index.column() == 0 && role == Qt::DecorationRole) { + if(item->isFolder()) + return IconProvider::instance()->getIcon("inode-directory"); + else + return IconProvider::instance()->getIcon("text-plain"); + } + if(index.column() == 0 && role == Qt::CheckStateRole) { + if(item->data(TorrentFileItem::COL_PRIO).toInt() == prio::IGNORED) + return Qt::Unchecked; + if(item->data(TorrentFileItem::COL_PRIO).toInt() == prio::PARTIAL) + return Qt::PartiallyChecked; + return Qt::Checked; + } + if (role != Qt::DisplayRole) + return QVariant(); + + return item->data(index.column()); + } + + Qt::ItemFlags flags(const QModelIndex &index) const { + if (!index.isValid()) + return 0; + if(getType(index) == TorrentFileItem::FOLDER) + return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsTristate; + return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable; + } + + QVariant headerData(int section, Qt::Orientation orientation, int role) const { + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + return rootItem->data(section); + + return QVariant(); + } + + QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const { + if (parent.isValid() && parent.column() != 0) + return QModelIndex(); + if(column >= TorrentFileItem::NB_COL) + return QModelIndex(); + + TorrentFileItem *parentItem; + + if (!parent.isValid()) + parentItem = rootItem; + else + parentItem = static_cast(parent.internalPointer()); + Q_ASSERT(parentItem); + if(row >= parentItem->childCount()) + return QModelIndex(); + + TorrentFileItem *childItem = parentItem->child(row); + if (childItem) { + return createIndex(row, column, childItem); + } else { + return QModelIndex(); + } + } + + QModelIndex parent(const QModelIndex &index) const { + if (!index.isValid()) + return QModelIndex(); + + TorrentFileItem *childItem = static_cast(index.internalPointer()); + if(!childItem) return QModelIndex(); + TorrentFileItem *parentItem = childItem->parent(); + + if (parentItem == rootItem) + return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); + } + + int rowCount(const QModelIndex &parent=QModelIndex()) const { + TorrentFileItem *parentItem; + + if (parent.column() > 0) + return 0; + + if (!parent.isValid()) + parentItem = rootItem; + else + parentItem = static_cast(parent.internalPointer()); + + return parentItem->childCount(); + } + + void clear() { + qDebug("clear called"); + beginResetModel(); + if(files_index) { + delete [] files_index; + files_index = 0; + } + rootItem->deleteAllChildren(); + endResetModel(); + } + + void setupModelData(const libtorrent::torrent_info &t) { + qDebug("setup model data called"); + if(t.num_files() == 0) return; + emit layoutAboutToBeChanged(); + // Initialize files_index array + qDebug("Torrent contains %d files", t.num_files()); + files_index = new TorrentFileItem*[t.num_files()]; + + TorrentFileItem *parent = this->rootItem; + TorrentFileItem *root_folder = parent; + TorrentFileItem *current_parent; + + // Iterate over files + for(int i=0; i= 16 + QString path = QDir::cleanPath(misc::toQStringU(fentry.path)).replace("\\", "/"); +#else + QString path = QDir::cleanPath(misc::toQStringU(fentry.path.string())).replace("\\", "/"); +#endif + // Iterate of parts of the path to create necessary folders + QStringList pathFolders = path.split("/"); + pathFolders.removeAll(".unwanted"); + pathFolders.takeLast(); + foreach(const QString &pathPart, pathFolders) { + TorrentFileItem *new_parent = current_parent->childWithName(pathPart); + if(!new_parent) { + new_parent = new TorrentFileItem(pathPart, current_parent); + } + current_parent = new_parent; + } + // Actually create the file + TorrentFileItem *f = new TorrentFileItem(t, fentry, current_parent, i); + files_index[i] = f; + } + emit layoutChanged(); + } + +public slots: + void selectAll() { + for(int i=0; ichildCount(); ++i) { + TorrentFileItem *child = rootItem->child(i); + if(child->getPriority() == prio::IGNORED) + child->setPriority(prio::NORMAL); + } + emit dataChanged(index(0,0), index(rowCount(), columnCount())); + } + + void selectNone() { + for(int i=0; ichildCount(); ++i) { + rootItem->child(i)->setPriority(prio::IGNORED); + } + emit dataChanged(index(0,0), index(rowCount(), columnCount())); + } + +signals: + void filteredFilesChanged(); +}; + +class TorrentFilesFilterModel: public QSortFilterProxyModel { + Q_OBJECT + +public: + TorrentFilesFilterModel(QObject *parent = 0): QSortFilterProxyModel(parent) { + m_model = new TorrentFilesModel(this); + connect(m_model, SIGNAL(filteredFilesChanged()), this, SIGNAL(filteredFilesChanged())); + setSourceModel(m_model); + // Filter settings + setFilterCaseSensitivity(Qt::CaseInsensitive); + setFilterKeyColumn(TorrentFileItem::COL_NAME); + setFilterRole(Qt::DisplayRole); + setDynamicSortFilter(true); + } + + ~TorrentFilesFilterModel() { + qDebug() << Q_FUNC_INFO << "ENTER"; + delete m_model; + qDebug() << Q_FUNC_INFO << "EXIT"; + } + + TorrentFilesModel* model() const { + return m_model; + } + + TorrentFileItem::FileType getType(const QModelIndex &index) const { + return m_model->getType(mapToSource(index)); + } + + int getFileIndex(const QModelIndex &index) { + return m_model->getFileIndex(mapToSource(index)); + } + + QModelIndex parent(const QModelIndex & child) const { + if(!child.isValid()) return QModelIndex(); + QModelIndex sourceParent = m_model->parent(mapToSource(child)); + if(!sourceParent.isValid()) return QModelIndex(); + return mapFromSource(sourceParent); + } + +signals: + void filteredFilesChanged(); + +protected: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { + if (m_model->getType(m_model->index(source_row, 0, source_parent)) == TorrentFileItem::FOLDER) { + // always accept folders, since we want to filter their children + return true; + } + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); + } + +public slots: + void selectAll() { + for(int i=0; i +#include +#include + +#include "torrentimportdlg.h" +#include "ui_torrentimportdlg.h" +#include "qinisettings.h" +#include "qbtsession.h" +#include "torrentpersistentdata.h" +#include "iconprovider.h" + +using namespace libtorrent; + +TorrentImportDlg::TorrentImportDlg(QWidget *parent) : + QDialog(parent), + ui(new Ui::TorrentImportDlg) +{ + ui->setupUi(this); + // Icons + ui->lbl_info->setPixmap(IconProvider::instance()->getIcon("dialog-information").pixmap(ui->lbl_info->height())); + ui->lbl_info->setFixedWidth(ui->lbl_info->height()); + ui->importBtn->setIcon(IconProvider::instance()->getIcon("document-import")); + // Libtorrent < 0.15 does not support skipping file checking +#if LIBTORRENT_VERSION_MINOR < 15 + ui->checkSkipCheck->setVisible(false); +#endif + loadSettings(); +} + +TorrentImportDlg::~TorrentImportDlg() +{ + delete ui; +} + +void TorrentImportDlg::on_browseTorrentBtn_clicked() +{ + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + const QString default_dir = settings.value(QString::fromUtf8("MainWindowLastDir"), QDir::homePath()).toString(); + // Ask for a torrent file + m_torrentPath = QFileDialog::getOpenFileName(this, tr("Torrent file to import"), default_dir, tr("Torrent files (*.torrent)")); + if(!m_torrentPath.isEmpty()) { + loadTorrent(m_torrentPath); + } else { + ui->lineTorrent->clear(); + } +} + +void TorrentImportDlg::on_browseContentBtn_clicked() +{ + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + const QString default_dir = settings.value(QString::fromUtf8("TorrentImport/LastContentDir"), QDir::homePath()).toString(); + if(t->num_files() == 1) { + // Single file torrent +#if LIBTORRENT_VERSION_MINOR > 15 + const QString file_name = misc::fileName(misc::toQStringU(t->file_at(0).path)); +#else + const QString file_name = misc::toQStringU(t->file_at(0).path.filename()); +#endif + qDebug("Torrent has only one file: %s", qPrintable(file_name)); + QString extension = misc::file_extension(file_name); + qDebug("File extension is : %s", qPrintable(extension)); + QString filter; + if(!extension.isEmpty()) { + extension = extension.toUpper(); + filter = tr("%1 Files", "%1 is a file extension (e.g. PDF)").arg(extension)+" (*."+extension+")"; + } + m_contentPath = QFileDialog::getOpenFileName(this, tr("Please provide the location of %1", "%1 is a file name").arg(file_name), default_dir, filter); + if(m_contentPath.isEmpty() || !QFile(m_contentPath).exists()) { + m_contentPath = QString::null; + ui->importBtn->setEnabled(false); + ui->checkSkipCheck->setEnabled(false); + return; + } + // Update display +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + ui->lineContent->setText(m_contentPath.replace("/", "\\")); +#else + ui->lineContent->setText(m_contentPath); +#endif +#if LIBTORRENT_VERSION_MINOR >= 15 + // Check file size + const qint64 file_size = QFile(m_contentPath).size(); + if(t->file_at(0).size == file_size) { + qDebug("The file size matches, allowing fast seeding..."); + ui->checkSkipCheck->setEnabled(true); + } else { + qDebug("The file size does not match, forbidding fast seeding..."); + ui->checkSkipCheck->setChecked(false); + ui->checkSkipCheck->setEnabled(false); + } +#endif + // Handle file renaming + QStringList parts = m_contentPath.replace("\\", "/").split("/"); + QString new_file_name = parts.takeLast(); + if(new_file_name != file_name) { + qDebug("The file has been renamed"); + QStringList new_parts = m_filesPath.first().split("/"); + new_parts.replace(new_parts.count()-1, new_file_name); + m_filesPath.replace(0, new_parts.join("/")); + } + m_contentPath = parts.join("/"); + } else { + // multiple files torrent + m_contentPath = QFileDialog::getExistingDirectory(this, tr("Please point to the location of the torrent: %1").arg(misc::toQStringU(t->name())), + default_dir); + if(m_contentPath.isEmpty() || !QDir(m_contentPath).exists()) { + m_contentPath = QString::null; + ui->importBtn->setEnabled(false); + ui->checkSkipCheck->setEnabled(false); + return; + } + // Update the display +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + ui->lineContent->setText(m_contentPath.replace("/", "\\")); +#else + ui->lineContent->setText(m_contentPath); +#endif +#if LIBTORRENT_VERSION_MINOR >= 15 + bool size_mismatch = false; + QDir content_dir(m_contentPath); + // Check file sizes + for(int i=0; inum_files(); ++i) { +#if LIBTORRENT_VERSION_MINOR > 15 + const QString rel_path = misc::toQStringU(t->file_at(i).path); +#else + const QString rel_path = misc::toQStringU(t->file_at(i).path.string()); +#endif + if(QFile(QDir::cleanPath(content_dir.absoluteFilePath(rel_path))).size() != t->file_at(i).size) { + qDebug("%s is %lld", + qPrintable(QDir::cleanPath(content_dir.absoluteFilePath(rel_path))), (long long int) QFile(QDir::cleanPath(content_dir.absoluteFilePath(rel_path))).size()); + qDebug("%s is %lld", + qPrintable(rel_path), (long long int)t->file_at(i).size); + size_mismatch = true; + break; + } + } + if(size_mismatch) { + qDebug("The file size does not match, forbidding fast seeding..."); + ui->checkSkipCheck->setChecked(false); + ui->checkSkipCheck->setEnabled(false); + } else { + qDebug("The file size matches, allowing fast seeding..."); + ui->checkSkipCheck->setEnabled(true); + } +#endif + } + // Enable the import button + ui->importBtn->setEnabled(true); +} + +void TorrentImportDlg::on_importBtn_clicked() +{ + saveSettings(); + // Has to be accept() and not close() + // or the torrent won't be imported + accept(); +} + +QString TorrentImportDlg::getTorrentPath() const +{ + return m_torrentPath; +} + +QString TorrentImportDlg::getContentPath() const +{ + return m_contentPath; +} + +void TorrentImportDlg::importTorrent() +{ + qDebug() << Q_FUNC_INFO << "ENTER"; + TorrentImportDlg dlg; + if(dlg.exec()) { + qDebug() << "Loading the torrent file..."; + boost::intrusive_ptr t = dlg.torrent(); + if(!t->is_valid()) + return; + QString torrent_path = dlg.getTorrentPath(); + QString content_path = dlg.getContentPath(); + if(torrent_path.isEmpty() || content_path.isEmpty() || !QFile(torrent_path).exists()) { + qWarning() << "Incorrect input, aborting." << torrent_path << content_path; + return; + } + const QString hash = misc::toQString(t->info_hash()); + qDebug() << "Torrent hash is" << hash; + TorrentTempData::setSavePath(hash, content_path); +#if LIBTORRENT_VERSION_MINOR >= 15 + TorrentTempData::setSeedingMode(hash, dlg.skipFileChecking()); +#endif + qDebug("Adding the torrent to the session..."); + QBtSession::instance()->addTorrent(torrent_path); + // Remember the last opened folder + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.setValue(QString::fromUtf8("MainWindowLastDir"), torrent_path); + settings.setValue("TorrentImport/LastContentDir", content_path); + return; + } + qDebug() << Q_FUNC_INFO << "EXIT"; + return; +} + +void TorrentImportDlg::loadTorrent(const QString &torrent_path) +{ + // Load the torrent file + try { + t = new torrent_info(torrent_path.toUtf8().constData()); + if(!t->is_valid() || t->num_files() == 0) + throw std::exception(); + } catch(std::exception&) { + ui->browseContentBtn->setEnabled(false); + ui->lineTorrent->clear(); + QMessageBox::warning(this, tr("Invalid torrent file"), tr("This is not a valid torrent file.")); + return; + } + // The torrent file is valid + misc::truncateRootFolder(t); + // Update display +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + QString tmp = torrent_path; + ui->lineTorrent->setText(tmp.replace("/", "\\")); +#else + ui->lineTorrent->setText(torrent_path); +#endif + ui->browseContentBtn->setEnabled(true); + // Load the file names + initializeFilesPath(); +} + +void TorrentImportDlg::initializeFilesPath() +{ + m_filesPath.clear(); + // Loads files path in the torrent + for(int i=0; inum_files(); ++i) { +#if LIBTORRENT_VERSION_MINOR > 15 + m_filesPath << misc::toQStringU(t->file_at(i).path).replace("\\", "/"); +#else + m_filesPath << misc::toQStringU(t->file_at(i).path.string()).replace("\\", "/"); +#endif + } +} + +bool TorrentImportDlg::fileRenamed() const +{ + return m_fileRenamed; +} + + +boost::intrusive_ptr TorrentImportDlg::torrent() const +{ + return t; +} + +#if LIBTORRENT_VERSION_MINOR >= 15 +bool TorrentImportDlg::skipFileChecking() const +{ + return ui->checkSkipCheck->isChecked(); +} +#endif + +void TorrentImportDlg::loadSettings() +{ + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + restoreGeometry(settings.value("TorrentImportDlg/dimensions").toByteArray()); +} + +void TorrentImportDlg::saveSettings() +{ + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.setValue("TorrentImportDlg/dimensions", saveGeometry()); +} + +void TorrentImportDlg::closeEvent(QCloseEvent *event) +{ + qDebug() << Q_FUNC_INFO; + saveSettings(); + QDialog::closeEvent(event); +} diff --git a/src/torrentimportdlg.h b/src/torrentimportdlg.h new file mode 100644 index 000000000..e8118b09e --- /dev/null +++ b/src/torrentimportdlg.h @@ -0,0 +1,90 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TORRENTIMPORTDLG_H +#define TORRENTIMPORTDLG_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +namespace Ui { +class TorrentImportDlg; +} +QT_END_NAMESPACE + +class QBtSession; + +class TorrentImportDlg : public QDialog +{ + Q_OBJECT + +public: + explicit TorrentImportDlg(QWidget *parent = 0); + ~TorrentImportDlg(); + static void importTorrent(); + QString getTorrentPath() const; + QString getContentPath() const; + bool fileRenamed() const; + boost::intrusive_ptr torrent() const; +#if LIBTORRENT_VERSION_MINOR >= 15 + bool skipFileChecking() const; +#endif + +protected slots: + void loadTorrent(const QString &torrent_path); + void initializeFilesPath(); + +private slots: + void on_browseTorrentBtn_clicked(); + + void on_browseContentBtn_clicked(); + + void on_importBtn_clicked(); + +protected: + void closeEvent(QCloseEvent *event); + +private: + void loadSettings(); + void saveSettings(); + +private: + Ui::TorrentImportDlg *ui; + boost::intrusive_ptr t; + QStringList m_filesPath; + QString m_contentPath; + QString m_torrentPath; + bool m_fileRenamed; +}; + +#endif // TORRENTIMPORTDLG_H diff --git a/src/torrentimportdlg.ui b/src/torrentimportdlg.ui new file mode 100644 index 000000000..6e3b2fd08 --- /dev/null +++ b/src/torrentimportdlg.ui @@ -0,0 +1,124 @@ + + + TorrentImportDlg + + + + 0 + 0 + 464 + 236 + + + + Torrent Import + + + + + + 15 + + + + + + 32 + 32 + + + + + + + + + + + This assistant will help you share with qBittorrent a torrent that you have already downloaded. + + + true + + + + + + + + + Torrent file to import: + + + + + + + + + false + + + + + + + ... + + + + + + + + + Content location: + + + + + + + + + false + + + + + + + false + + + ... + + + + + + + + + false + + + Skip the data checking stage and start seeding immediately + + + + + + + false + + + Import + + + + + + + + diff --git a/src/torrentpersistentdata.h b/src/torrentpersistentdata.h new file mode 100644 index 000000000..7a5909aa0 --- /dev/null +++ b/src/torrentpersistentdata.h @@ -0,0 +1,464 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TORRENTPERSISTENTDATA_H +#define TORRENTPERSISTENTDATA_H + +#include +#include +#include +#include +#include +#include "qtorrenthandle.h" +#include "misc.h" +#include +#include "qinisettings.h" +#include + +class TorrentTempData { +public: + static bool hasTempData(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents-tmp").toHash(); + return all_data.contains(hash); + } + + static void deleteTempData(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents-tmp").toHash(); + if(all_data.contains(hash)) { + all_data.remove(hash); + settings.setValue("torrents-tmp", all_data); + } + } + + static void setFilesPriority(QString hash, const std::vector &pp) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents-tmp").toHash(); + QHash data = all_data.value(hash).toHash(); + std::vector::const_iterator pp_it = pp.begin(); + QStringList pieces_priority; + while(pp_it != pp.end()) { + pieces_priority << QString::number(*pp_it); + pp_it++; + } + data["files_priority"] = pieces_priority; + all_data[hash] = data; + settings.setValue("torrents-tmp", all_data); + } + + static void setFilesPath(QString hash, const QStringList &path_list) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents-tmp").toHash(); + QHash data = all_data.value(hash).toHash(); + data["files_path"] = path_list; + all_data[hash] = data; + settings.setValue("torrents-tmp", all_data); + } + + static void setSavePath(QString hash, QString save_path) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents-tmp").toHash(); + QHash data = all_data.value(hash).toHash(); + data["save_path"] = save_path; + all_data[hash] = data; + settings.setValue("torrents-tmp", all_data); + } + + static void setLabel(QString hash, QString label) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents-tmp").toHash(); + QHash data = all_data.value(hash).toHash(); + qDebug("Saving label %s to tmp data", label.toLocal8Bit().data()); + data["label"] = label; + all_data[hash] = data; + settings.setValue("torrents-tmp", all_data); + } + + static void setSequential(QString hash, bool sequential) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents-tmp").toHash(); + QHash data = all_data.value(hash).toHash(); + data["sequential"] = sequential; + all_data[hash] = data; + settings.setValue("torrents-tmp", all_data); + } + + static bool isSequential(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents-tmp").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("sequential", false).toBool(); + } + +#if LIBTORRENT_VERSION_MINOR > 14 + static void setSeedingMode(QString hash,bool seed){ + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents-tmp").toHash(); + QHash data = all_data.value(hash).toHash(); + data["seeding"] = seed; + all_data[hash] = data; + settings.setValue("torrents-tmp", all_data); + } + + static bool isSeedingMode(QString hash){ + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents-tmp").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("seeding", false).toBool(); + } +#endif + + static QString getSavePath(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents-tmp").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("save_path").toString(); + } + + static QStringList getFilesPath(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents-tmp").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("files_path").toStringList(); + } + + static QString getLabel(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents-tmp").toHash(); + const QHash data = all_data.value(hash).toHash(); + qDebug("Got label %s from tmp data", data.value("label", "").toString().toLocal8Bit().data()); + return data.value("label", "").toString(); + } + + static void getFilesPriority(QString hash, std::vector &fp) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents-tmp").toHash(); + const QHash data = all_data.value(hash).toHash(); + const QList list_var = misc::intListfromStringList(data.value("files_priority").toStringList()); + foreach(const int &var, list_var) { + fp.push_back(var); + } + } +}; + +class TorrentPersistentData { +public: + enum RatioLimit { + USE_GLOBAL_RATIO = -2, + NO_RATIO_LIMIT = -1 + }; + +public: + static bool isKnownTorrent(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + return all_data.contains(hash); + } + + static QStringList knownTorrents() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + return all_data.keys(); + } + + static void setRatioLimit(const QString &hash, qreal ratio) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + data["max_ratio"] = ratio; + all_data[hash] = data; + settings.setValue("torrents", all_data); + } + + static qreal getRatioLimit(const QString &hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("max_ratio", USE_GLOBAL_RATIO).toReal(); + } + + static bool hasPerTorrentRatioLimit() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + QHash::ConstIterator it; + for(it = all_data.constBegin(); it != all_data.constEnd(); it++) { + if(it.value().toHash().value("max_ratio", USE_GLOBAL_RATIO).toReal() >= 0) { + return true; + } + } + return false; + } + + static void setAddedDate(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + if(!data.contains("add_date")) { + data["add_date"] = QDateTime::currentDateTime(); + all_data[hash] = data; + settings.setValue("torrents", all_data); + } + } + + static QDateTime getAddedDate(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + QDateTime dt = data.value("add_date").toDateTime(); + if(!dt.isValid()) { + setAddedDate(hash); + dt = QDateTime::currentDateTime(); + } + return dt; + } + + static void setErrorState(QString hash, bool has_error) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + data["has_error"] = has_error; + all_data[hash] = data; + settings.setValue("torrents", all_data); + } + + static bool hasError(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("has_error", false).toBool(); + } + + static void setRootFolder(QString hash, QString root_folder) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + data["root_folder"] = root_folder; + all_data[hash] = data; + settings.setValue("torrents", all_data); + } + + static QString getRootFolder(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("root_folder").toString(); + } + + static void setPreviousSavePath(QString hash, QString previous_path) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + data["previous_path"] = previous_path; + all_data[hash] = data; + settings.setValue("torrents", all_data); + } + + static QString getPreviousPath(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("previous_path").toString(); + } + + static void saveSeedDate(const QTorrentHandle &h) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data[h.hash()].toHash(); + if(h.is_seed()) + data["seed_date"] = QDateTime::currentDateTime(); + else + data.remove("seed_date"); + all_data[h.hash()] = data; + settings.setValue("torrents", all_data); + } + + static QDateTime getSeedDate(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("seed_date").toDateTime(); + } + + static void deletePersistentData(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + if(all_data.contains(hash)) { + all_data.remove(hash); + settings.setValue("torrents", all_data); + } + } + + static void saveTorrentPersistentData(const QTorrentHandle &h, QString save_path = QString::null, bool is_magnet = false) { + Q_ASSERT(h.is_valid()); + qDebug("Saving persistent data for %s", qPrintable(h.hash())); + // Save persistent data + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(h.hash()).toHash(); + data["is_magnet"] = is_magnet; + if(is_magnet) { + data["magnet_uri"] = misc::toQString(make_magnet_uri(h)); + } + data["seed"] = h.is_seed(); + data["priority"] = h.queue_position(); + if(save_path.isEmpty()) { + qDebug("TorrentPersistantData: save path is %s", qPrintable(h.save_path())); + data["save_path"] = h.save_path(); + } else { + qDebug("TorrentPersistantData: overriding save path is %s", qPrintable(save_path)); + data["save_path"] = save_path; // Override torrent save path (e.g. because it is a temp dir) + } + // Label + data["label"] = TorrentTempData::getLabel(h.hash()); + // Save data + all_data[h.hash()] = data; + settings.setValue("torrents", all_data); + qDebug("TorrentPersistentData: Saving save_path %s, hash: %s", qPrintable(h.save_path()), qPrintable(h.hash())); + // Set Added date + setAddedDate(h.hash()); + // Finally, remove temp data + TorrentTempData::deleteTempData(h.hash()); + } + + // Setters + + static void saveSavePath(QString hash, QString save_path) { + Q_ASSERT(!hash.isEmpty()); + qDebug("TorrentPersistentData::saveSavePath(%s)", qPrintable(save_path)); + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + data["save_path"] = save_path; + all_data[hash] = data; + settings.setValue("torrents", all_data); + qDebug("TorrentPersistentData: Saving save_path: %s, hash: %s", qPrintable(save_path), qPrintable(hash)); + } + + static void saveLabel(QString hash, QString label) { + Q_ASSERT(!hash.isEmpty()); + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + data["label"] = label; + all_data[hash] = data; + settings.setValue("torrents", all_data); + } + + static void saveName(QString hash, QString name) { + Q_ASSERT(!hash.isEmpty()); + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data.value(hash).toHash(); + data["name"] = name; + all_data[hash] = data; + settings.setValue("torrents", all_data); + } + + static void savePriority(const QTorrentHandle &h) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data[h.hash()].toHash(); + data["priority"] = h.queue_position(); + all_data[h.hash()] = data; + settings.setValue("torrents", all_data); + } + + static void saveSeedStatus(const QTorrentHandle &h) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + QHash all_data = settings.value("torrents").toHash(); + QHash data = all_data[h.hash()].toHash(); + bool was_seed = data.value("seed", false).toBool(); + if(was_seed != h.is_seed()) { + data["seed"] = !was_seed; + all_data[h.hash()] = data; + settings.setValue("torrents", all_data); + if(!was_seed) { + // Save completion date + saveSeedDate(h); + } + } + } + + // Getters + static QString getSavePath(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + //qDebug("TorrentPersistentData: getSavePath %s", data["save_path"].toString().toLocal8Bit().data()); + return data.value("save_path").toString(); + } + + static QString getLabel(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("label", "").toString(); + } + + static QString getName(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("name", "").toString(); + } + + static int getPriority(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("priority", -1).toInt(); + } + + static bool isSeed(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("seed", false).toBool(); + } + + static bool isMagnet(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + return data.value("is_magnet", false).toBool(); + } + + static QString getMagnetUri(QString hash) { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume")); + const QHash all_data = settings.value("torrents").toHash(); + const QHash data = all_data.value(hash).toHash(); + Q_ASSERT(data.value("is_magnet", false).toBool()); + return data.value("magnet_uri").toString(); + } + +}; + +#endif // TORRENTPERSISTENTDATA_H diff --git a/src/tracker/qpeer.h b/src/tracker/qpeer.h new file mode 100644 index 000000000..2f4ddbac7 --- /dev/null +++ b/src/tracker/qpeer.h @@ -0,0 +1,35 @@ +#ifndef QPEER_H +#define QPEER_H + +#include +#include + +struct QPeer { + + bool operator!=(const QPeer &other) const { + return qhash() != other.qhash(); + } + + bool operator==(const QPeer &other) const { + return qhash() == other.qhash(); + } + + QString qhash() const { + return ip+":"+QString::number(port); + } + + libtorrent::entry toEntry(bool no_peer_id) const { + libtorrent::entry::dictionary_type peer_map; + if(!no_peer_id) + peer_map["id"] = libtorrent::entry(peer_id.toStdString()); + peer_map["ip"] = libtorrent::entry(ip.toStdString()); + peer_map["port"] = libtorrent::entry(port); + return libtorrent::entry(peer_map); + } + + QString ip; + QString peer_id; + int port; +}; + +#endif // QPEER_H diff --git a/src/tracker/qtracker.cpp b/src/tracker/qtracker.cpp new file mode 100644 index 000000000..6ce509bde --- /dev/null +++ b/src/tracker/qtracker.cpp @@ -0,0 +1,236 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include + +#include +#include + +#include "qtracker.h" +#include "preferences.h" + +using namespace libtorrent; + +QTracker::QTracker(QObject *parent) : + QTcpServer(parent) +{ + Q_ASSERT(Preferences().isTrackerEnabled()); + connect(this, SIGNAL(newConnection()), this, SLOT(handlePeerConnection())); +} + +QTracker::~QTracker() { + if(isListening()) { + qDebug("Shutting down the embedded tracker..."); + close(); + } + // TODO: Store the torrent list +} + +void QTracker::handlePeerConnection() +{ + QTcpSocket *socket; + while((socket = nextPendingConnection())) + { + qDebug("QTracker: New peer connection"); + connect(socket, SIGNAL(readyRead()), SLOT(readRequest())); + } +} + +bool QTracker::start() +{ + const int listen_port = Preferences().getTrackerPort(); + // + if(isListening()) { + if(serverPort() == listen_port) { + // Already listening on the right port, just return + return true; + } + // Wrong port, closing the server + close(); + } + qDebug("Starting the embedded tracker..."); + // Listen on the predefined port + return listen(QHostAddress::Any, listen_port); +} + +void QTracker::readRequest() +{ + QTcpSocket *socket = static_cast(sender()); + QByteArray input = socket->readAll(); + //qDebug("QTracker: Raw request:\n%s", input.data()); + HttpRequestParser parser; + parser.write(input); + if(!parser.isValid()) { + qDebug("QTracker: Invalid HTTP Request:\n %s", qPrintable(parser.toString())); + respondInvalidRequest(socket, 100, "Invalid request type"); + return; + } + //qDebug("QTracker received the following request:\n%s", qPrintable(parser.toString())); + // Request is correct, is it a GET request? + if(parser.method() != "GET") { + qDebug("QTracker: Unsupported HTTP request: %s", qPrintable(parser.method())); + respondInvalidRequest(socket, 100, "Invalid request type"); + return; + } + if(!parser.url().startsWith("/announce", Qt::CaseInsensitive)) { + qDebug("QTracker: Unrecognized path: %s", qPrintable(parser.url())); + respondInvalidRequest(socket, 100, "Invalid request type"); + return; + } + // OK, this is a GET request + respondToAnnounceRequest(socket, parser); +} + +void QTracker::respondInvalidRequest(QTcpSocket *socket, int code, QString msg) +{ + QHttpResponseHeader response; + response.setStatusLine(code, msg); + socket->write(response.toString().toLocal8Bit()); + socket->disconnectFromHost(); +} + +void QTracker::respondToAnnounceRequest(QTcpSocket *socket, const HttpRequestParser& parser) +{ + TrackerAnnounceRequest annonce_req; + // IP + annonce_req.peer.ip = socket->peerAddress().toString(); + // 1. Get info_hash + if(parser.get("info_hash").isNull()) { + qDebug("QTracker: Missing info_hash"); + respondInvalidRequest(socket, 101, "Missing info_hash"); + return; + } + annonce_req.info_hash = parser.get("info_hash"); + // info_hash cannot be longer than 20 bytes + /*if(annonce_req.info_hash.toAscii().length() > 20) { + qDebug("QTracker: Info_hash is not 20 byte long: %s (%d)", qPrintable(annonce_req.info_hash), annonce_req.info_hash.toAscii().length()); + respondInvalidRequest(socket, 150, "Invalid infohash"); + return; + }*/ + // 2. Get peer ID + if(parser.get("peer_id").isNull()) { + qDebug("QTracker: Missing peer_id"); + respondInvalidRequest(socket, 102, "Missing peer_id"); + return; + } + annonce_req.peer.peer_id = parser.get("peer_id"); + // peer_id cannot be longer than 20 bytes + /*if(annonce_req.peer.peer_id.length() > 20) { + qDebug("QTracker: peer_id is not 20 byte long: %s", qPrintable(annonce_req.peer.peer_id)); + respondInvalidRequest(socket, 151, "Invalid peerid"); + return; + }*/ + // 3. Get port + if(parser.get("port").isNull()) { + qDebug("QTracker: Missing port"); + respondInvalidRequest(socket, 103, "Missing port"); + return; + } + bool ok = false; + annonce_req.peer.port = parser.get("port").toInt(&ok); + if(!ok || annonce_req.peer.port < 1 || annonce_req.peer.port > 65535) { + qDebug("QTracker: Invalid port number (%d)", annonce_req.peer.port); + respondInvalidRequest(socket, 103, "Missing port"); + return; + } + // 4. Get event + annonce_req.event = ""; + if(!parser.get("event").isNull()) { + annonce_req.event = parser.get("event"); + qDebug("QTracker: event is %s", qPrintable(annonce_req.event)); + } + // 5. Get numwant + annonce_req.numwant = 50; + if(!parser.get("numwant").isNull()) { + int tmp = parser.get("numwant").toInt(); + if(tmp > 0) { + qDebug("QTracker: numwant=%d", tmp); + annonce_req.numwant = tmp; + } + } + // 6. no_peer_id (extension) + annonce_req.no_peer_id = false; + if(parser.hasKey("no_peer_id")) { + annonce_req.no_peer_id = true; + } + // 7. TODO: support "compact" extension + // Done parsing, now let's reply + if(m_torrents.contains(annonce_req.info_hash)) { + if(annonce_req.event == "stopped") { + qDebug("QTracker: Peer stopped downloading, deleting it from the list"); + m_torrents[annonce_req.info_hash].remove(annonce_req.peer.qhash()); + return; + } + } else { + // Unknown torrent + if(m_torrents.size() == MAX_TORRENTS) { + // Reached max size, remove a random torrent + m_torrents.erase(m_torrents.begin()); + } + } + // Register the user + PeerList peers = m_torrents.value(annonce_req.info_hash); + if(peers.size() == MAX_PEERS_PER_TORRENT) { + // Too many peers, remove a random one + peers.erase(peers.begin()); + } + peers[annonce_req.peer.qhash()] = annonce_req.peer; + m_torrents[annonce_req.info_hash] = peers; + // Reply + ReplyWithPeerList(socket, annonce_req); +} + +void QTracker::ReplyWithPeerList(QTcpSocket *socket, const TrackerAnnounceRequest &annonce_req) +{ + // Prepare the entry for bencoding + entry::dictionary_type reply_dict; + reply_dict["interval"] = entry(ANNOUNCE_INTERVAL); + QList peers = m_torrents.value(annonce_req.info_hash).values(); + entry::list_type peer_list; + foreach(const QPeer & p, peers) { + //if(p != annonce_req.peer) + peer_list.push_back(p.toEntry(annonce_req.no_peer_id)); + } + reply_dict["peers"] = entry(peer_list); + entry reply_entry(reply_dict); + // bencode + std::vector buf; + bencode(std::back_inserter(buf), reply_entry); + QByteArray reply(&buf[0], buf.size()); + qDebug("QTracker: reply with the following bencoded data:\n %s", reply.constData()); + // HTTP reply + QHttpResponseHeader response; + response.setStatusLine(200, "OK"); + socket->write(response.toString().toLocal8Bit() + reply); + socket->disconnectFromHost(); +} + + diff --git a/src/tracker/qtracker.h b/src/tracker/qtracker.h new file mode 100644 index 000000000..7fa0d5bd6 --- /dev/null +++ b/src/tracker/qtracker.h @@ -0,0 +1,74 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef QTRACKER_H +#define QTRACKER_H + +#include +#include +#include + +#include "httprequestparser.h" +#include "trackerannouncerequest.h" +#include "qpeer.h" + +// static limits +const int MAX_TORRENTS = 100; +const int MAX_PEERS_PER_TORRENT = 1000; +const int ANNOUNCE_INTERVAL = 1800; // 30min + +typedef QHash PeerList; +typedef QHash TorrentList; + +/* Basic Bittorrent tracker implementation in Qt4 */ +/* Following http://wiki.theory.org/BitTorrent_Tracker_Protocol */ +class QTracker : public QTcpServer +{ + Q_OBJECT + Q_DISABLE_COPY(QTracker) + +public: + explicit QTracker(QObject *parent = 0); + ~QTracker(); + bool start(); + +protected slots: + void readRequest(); + void handlePeerConnection(); + void respondInvalidRequest(QTcpSocket *socket, int code, QString msg); + void respondToAnnounceRequest(QTcpSocket *socket, const HttpRequestParser& parser); + void ReplyWithPeerList(QTcpSocket *socket, const TrackerAnnounceRequest &annonce_req); + +private: + TorrentList m_torrents; + +}; + +#endif // QTRACKER_H diff --git a/src/tracker/tracker.pri b/src/tracker/tracker.pri new file mode 100644 index 000000000..5b5809a86 --- /dev/null +++ b/src/tracker/tracker.pri @@ -0,0 +1,9 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qtracker.h \ + $$PWD/trackerannouncerequest.h \ + $$PWD/qpeer.h + +SOURCES += \ + $$PWD/qtracker.cpp diff --git a/src/tracker/trackerannouncerequest.h b/src/tracker/trackerannouncerequest.h new file mode 100644 index 000000000..273ced385 --- /dev/null +++ b/src/tracker/trackerannouncerequest.h @@ -0,0 +1,15 @@ +#ifndef TRACKERANNOUNCEREQUEST_H +#define TRACKERANNOUNCEREQUEST_H + +#include + +struct TrackerAnnounceRequest { + QString info_hash; + QString event; + int numwant; + QPeer peer; + // Extensions + bool no_peer_id; +}; + +#endif // TRACKERANNOUNCEREQUEST_H diff --git a/src/trackerlogin.h b/src/trackerlogin.h new file mode 100644 index 000000000..59249d2a2 --- /dev/null +++ b/src/trackerlogin.h @@ -0,0 +1,75 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TRACKERLOGIN_H +#define TRACKERLOGIN_H + +#include +#include +#include +#include "ui_login.h" +#include "qtorrenthandle.h" + +class trackerLogin : public QDialog, private Ui::authentication{ + Q_OBJECT + + private: + QTorrentHandle h; + + public: + trackerLogin(QWidget *parent, QTorrentHandle h): QDialog(parent), h(h){ + setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + login_logo->setPixmap(QPixmap(QString::fromUtf8(":/Icons/oxygen/encrypted.png"))); + tracker_url->setText(h.current_tracker()); + connect(this, SIGNAL(trackerLoginCancelled(QPair)), parent, SLOT(addUnauthenticatedTracker(QPair))); + show(); + } + + ~trackerLogin(){} + + signals: + void trackerLoginCancelled(QPair tracker); + + public slots: + void on_loginButton_clicked(){ + // login + h.set_tracker_login(lineUsername->text(), linePasswd->text()); + close(); + } + + void on_cancelButton_clicked(){ + // Emit a signal to GUI to stop asking for authentication + emit trackerLoginCancelled(QPair(h, h.current_tracker())); + close(); + } +}; + +#endif diff --git a/src/transferlistdelegate.h b/src/transferlistdelegate.h new file mode 100644 index 000000000..2b9e1fe8d --- /dev/null +++ b/src/transferlistdelegate.h @@ -0,0 +1,213 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TRANSFERLISTDELEGATE_H +#define TRANSFERLISTDELEGATE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "misc.h" +#include "torrentmodel.h" +#include "qbtsession.h" + +#ifdef Q_WS_WIN + #include +#endif + +// Defines for download list list columns + +class TransferListDelegate: public QItemDelegate { + Q_OBJECT + +public: + TransferListDelegate(QObject *parent) : QItemDelegate(parent){} + + ~TransferListDelegate(){} + + void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const{ + QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option); + painter->save(); + switch(index.column()){ + case TorrentModelItem::TR_AMOUNT_DOWNLOADED: + case TorrentModelItem::TR_AMOUNT_LEFT: + case TorrentModelItem::TR_SIZE:{ + QItemDelegate::drawBackground(painter, opt, index); + opt.displayAlignment = Qt::AlignRight; + QItemDelegate::drawDisplay(painter, opt, option.rect, misc::friendlyUnit(index.data().toLongLong())); + break; + } + case TorrentModelItem::TR_ETA:{ + QItemDelegate::drawBackground(painter, opt, index); + QItemDelegate::drawDisplay(painter, opt, option.rect, misc::userFriendlyDuration(index.data().toLongLong())); + break; + } + case TorrentModelItem::TR_SEEDS: + case TorrentModelItem::TR_PEERS: { + QString display = QString::number(index.data().toLongLong()); + if(index.data(Qt::UserRole).toLongLong() > 0) { + // Scrape was successful, we have total values + display += " ("+QString::number(index.data(Qt::UserRole).toLongLong())+")"; + } + QItemDelegate::drawBackground(painter, opt, index); + opt.displayAlignment = Qt::AlignRight; + QItemDelegate::drawDisplay(painter, opt, opt.rect, display); + break; + } + case TorrentModelItem::TR_STATUS: { + const int state = index.data().toInt(); + QString display; + switch(state) { + case TorrentModelItem::STATE_DOWNLOADING: + display = tr("Downloading"); + break; + case TorrentModelItem::STATE_PAUSED_DL: + case TorrentModelItem::STATE_PAUSED_UP: + display = tr("Paused"); + break; + case TorrentModelItem::STATE_QUEUED_DL: + case TorrentModelItem::STATE_QUEUED_UP: + display = tr("Queued", "i.e. torrent is queued"); + break; + case TorrentModelItem::STATE_SEEDING: + case TorrentModelItem::STATE_STALLED_UP: + display = tr("Seeding", "Torrent is complete and in upload-only mode"); + break; + case TorrentModelItem::STATE_STALLED_DL: + display = tr("Stalled", "Torrent is waiting for download to begin"); + break; + case TorrentModelItem::STATE_CHECKING_DL: + case TorrentModelItem::STATE_CHECKING_UP: + display = tr("Checking", "Torrent local data is being checked"); + break; + default: + display = ""; + } + QItemDelegate::drawBackground(painter, opt, index); + QItemDelegate::drawDisplay(painter, opt, opt.rect, display); + break; + } + case TorrentModelItem::TR_UPSPEED: + case TorrentModelItem::TR_DLSPEED:{ + QItemDelegate::drawBackground(painter, opt, index); + const qulonglong speed = index.data().toULongLong(); + opt.displayAlignment = Qt::AlignRight; + QItemDelegate::drawDisplay(painter, opt, opt.rect, misc::friendlyUnit(speed)+tr("/s", "/second (.i.e per second)")); + break; + } + case TorrentModelItem::TR_UPLIMIT: + case TorrentModelItem::TR_DLLIMIT:{ + QItemDelegate::drawBackground(painter, opt, index); + const qlonglong limit = index.data().toLongLong(); + opt.displayAlignment = Qt::AlignRight; + if(limit > 0) + QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(limit/1024., 'f', 1) + " " + tr("KiB/s", "KiB/second (.i.e per second)")); + else + QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8("∞")); + break; + } + case TorrentModelItem::TR_TIME_ELAPSED: { + QItemDelegate::drawBackground(painter, opt, index); + QString txt = misc::userFriendlyDuration(index.data().toLongLong()); + qlonglong seeding_time = index.data(Qt::UserRole).toLongLong(); + if(seeding_time > 0) + txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(seeding_time))+")"; + QItemDelegate::drawDisplay(painter, opt, opt.rect, txt); + break; + } + case TorrentModelItem::TR_ADD_DATE: + case TorrentModelItem::TR_SEED_DATE: + QItemDelegate::drawBackground(painter, opt, index); + QItemDelegate::drawDisplay(painter, opt, opt.rect, index.data().toDateTime().toLocalTime().toString(Qt::DefaultLocaleShortDate)); + break; + case TorrentModelItem::TR_RATIO:{ + QItemDelegate::drawBackground(painter, opt, index); + opt.displayAlignment = Qt::AlignRight; + const qreal ratio = index.data().toDouble(); + if(ratio > QBtSession::MAX_RATIO) + QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8("∞")); + else + QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(ratio, 'f', 2)); + break; + } + case TorrentModelItem::TR_PRIORITY: { + const int priority = index.data().toInt(); + if(priority >= 0) { + opt.displayAlignment = Qt::AlignRight; + QItemDelegate::paint(painter, opt, index); + } else { + QItemDelegate::drawBackground(painter, opt, index); + opt.displayAlignment = Qt::AlignRight; + QItemDelegate::drawDisplay(painter, opt, opt.rect, "*"); + } + break; + } + case TorrentModelItem::TR_PROGRESS:{ + QStyleOptionProgressBarV2 newopt; + qreal progress = index.data().toDouble()*100.; + // We don't want to display 100% unless + // the torrent is really complete + if(progress > 99.94 && progress < 100.) + progress = 99.9; + newopt.rect = opt.rect; + newopt.text = QString::number(progress, 'f', 1)+"%"; + newopt.progress = (int)progress; + newopt.maximum = 100; + newopt.minimum = 0; + newopt.state |= QStyle::State_Enabled; + newopt.textVisible = true; +#ifndef Q_WS_WIN + QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); +#else + // XXX: To avoid having the progress text on the right of the bar + QPlastiqueStyle st; + st.drawControl(QStyle::CE_ProgressBar, &newopt, painter, 0); +#endif + break; + } + default: + QItemDelegate::paint(painter, option, index); + } + painter->restore(); + } + + QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const { + // No editor here + return 0; + } + +}; + +#endif // TRANSFERLISTDELEGATE_H diff --git a/src/transferlistfilterswidget.h b/src/transferlistfilterswidget.h new file mode 100644 index 000000000..82e759821 --- /dev/null +++ b/src/transferlistfilterswidget.h @@ -0,0 +1,492 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TRANSFERLISTFILTERSWIDGET_H +#define TRANSFERLISTFILTERSWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "transferlistdelegate.h" +#include "transferlistwidget.h" +#include "preferences.h" +#include "qinisettings.h" +#include "torrentmodel.h" +#include "iconprovider.h" + +class LabelFiltersList: public QListWidget { + Q_OBJECT + +private: + QListWidgetItem *itemHover; + +public: + LabelFiltersList(QWidget *parent): QListWidget(parent) { + itemHover = 0; + // Accept drop + setAcceptDrops(true); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + } + + // Redefine addItem() to make sure the list stays sorted + void addItem(QListWidgetItem *it) { + Q_ASSERT(count() >= 2); + for(int i=2; itext().localeAwareCompare(it->text()) >= 0) { + insertItem(i, it); + return; + } + } + QListWidget::addItem(it); + } + + QString labelFromRow(int row) const { + Q_ASSERT(row > 1); + const QString &label = item(row)->text(); + QStringList parts = label.split(" "); + Q_ASSERT(parts.size() >= 2); + parts.removeLast(); // Remove trailing number + return parts.join(" "); + } + + int rowFromLabel(QString label) const { + Q_ASSERT(!label.isEmpty()); + for(int i=2; ipos()) && row(itemAt(event->pos())) > 0) { + if(itemHover) { + if(itemHover != itemAt(event->pos())) { + setItemHover(false); + itemHover = itemAt(event->pos()); + setItemHover(true); + } + } else { + itemHover = itemAt(event->pos()); + setItemHover(true); + } + event->acceptProposedAction(); + } else { + if(itemHover) + setItemHover(false); + event->ignore(); + } + } + + void dropEvent(QDropEvent *event) { + qDebug("Drop Event in labels list"); + if(itemAt(event->pos())) { + emit torrentDropped(row(itemAt(event->pos()))); + } + event->ignore(); + setItemHover(false); + // Select current item again + currentItem()->setSelected(true); + } + + void dragLeaveEvent(QDragLeaveEvent*) { + if(itemHover) + setItemHover(false); + // Select current item again + currentItem()->setSelected(true); + } + + void setItemHover(bool hover) { + Q_ASSERT(itemHover); + if(hover) { + itemHover->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("folder-documents.png")); + itemHover->setSelected(true); + //setCurrentItem(itemHover); + } else { + itemHover->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory.png")); + //itemHover->setSelected(false); + itemHover = 0; + } + } +}; + +class StatusFiltersWidget : public QListWidget { + Q_OBJECT + +public: + StatusFiltersWidget(QWidget *parent) : QListWidget(parent), m_shown(false) { + //setFixedHeight(120); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + } + +public slots: + void updateHeight() { + qDebug("Adjusting statuslist widget height..."); + m_shown = true; + setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + int cur_height = 50; + do { + setFixedHeight(cur_height); + cur_height += 10; + }while(verticalScrollBar()->isVisible()); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + } + +protected: + void changeEvent(QEvent *e) { + QListWidget::changeEvent(e); + switch (e->type()) { + case QEvent::StyleChange: + qDebug("Style has changed, adapting the statusfilters widget height"); + if(m_shown) + updateHeight(); + break; + default: + break; + } + } + +private: + bool m_shown; + +}; + +class TransferListFiltersWidget: public QFrame { + Q_OBJECT + +private: + QHash customLabels; + StatusFiltersWidget* statusFilters; + LabelFiltersList* labelFilters; + QVBoxLayout* vLayout; + TransferListWidget *transferList; + int nb_labeled; + int nb_torrents; + +public: + TransferListFiltersWidget(QWidget *parent, TransferListWidget *transferList): QFrame(parent), transferList(transferList), nb_labeled(0), nb_torrents(0) { + // Construct lists + vLayout = new QVBoxLayout(); + vLayout->setContentsMargins(0, 4, 0, 4); + statusFilters = new StatusFiltersWidget(this); + vLayout->addWidget(statusFilters); + labelFilters = new LabelFiltersList(this); + vLayout->addWidget(labelFilters); + setLayout(vLayout); + labelFilters->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + statusFilters->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + statusFilters->setSpacing(0); + setContentsMargins(0,0,0,0); + vLayout->setSpacing(2); + // Add status filters + QListWidgetItem *all = new QListWidgetItem(statusFilters); + all->setData(Qt::DisplayRole, QVariant(tr("All") + " (0)")); + all->setData(Qt::DecorationRole, QIcon(":/Icons/skin/filterall.png")); + QListWidgetItem *downloading = new QListWidgetItem(statusFilters); + downloading->setData(Qt::DisplayRole, QVariant(tr("Downloading") + " (0)")); + downloading->setData(Qt::DecorationRole, QIcon(":/Icons/skin/downloading.png")); + QListWidgetItem *completed = new QListWidgetItem(statusFilters); + completed->setData(Qt::DisplayRole, QVariant(tr("Completed") + " (0)")); + completed->setData(Qt::DecorationRole, QIcon(":/Icons/skin/uploading.png")); + QListWidgetItem *paused = new QListWidgetItem(statusFilters); + paused->setData(Qt::DisplayRole, QVariant(tr("Paused") + " (0)")); + paused->setData(Qt::DecorationRole, QIcon(":/Icons/skin/paused.png")); + QListWidgetItem *active = new QListWidgetItem(statusFilters); + active->setData(Qt::DisplayRole, QVariant(tr("Active") + " (0)")); + active->setData(Qt::DecorationRole, QIcon(":/Icons/skin/filteractive.png")); + QListWidgetItem *inactive = new QListWidgetItem(statusFilters); + inactive->setData(Qt::DisplayRole, QVariant(tr("Inactive") + " (0)")); + inactive->setData(Qt::DecorationRole, QIcon(":/Icons/skin/filterinactive.png")); + + // SIGNAL/SLOT + connect(statusFilters, SIGNAL(currentRowChanged(int)), transferList, SLOT(applyStatusFilter(int))); + connect(transferList->getSourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(updateTorrentNumbers())); + connect(transferList->getSourceModel(), SIGNAL(torrentAdded(TorrentModelItem*)), SLOT(handleNewTorrent(TorrentModelItem*))); + connect(labelFilters, SIGNAL(currentRowChanged(int)), this, SLOT(applyLabelFilter(int))); + connect(labelFilters, SIGNAL(torrentDropped(int)), this, SLOT(torrentDropped(int))); + connect(transferList->getSourceModel(), SIGNAL(torrentAboutToBeRemoved(TorrentModelItem*)), SLOT(torrentAboutToBeDeleted(TorrentModelItem*))); + connect(transferList->getSourceModel(), SIGNAL(torrentChangedLabel(TorrentModelItem*,QString,QString)), SLOT(torrentChangedLabel(TorrentModelItem*, QString, QString))); + + // Add Label filters + QListWidgetItem *allLabels = new QListWidgetItem(labelFilters); + allLabels->setData(Qt::DisplayRole, QVariant(tr("All labels") + " (0)")); + allLabels->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); + QListWidgetItem *noLabel = new QListWidgetItem(labelFilters); + noLabel->setData(Qt::DisplayRole, QVariant(tr("Unlabeled") + " (0)")); + noLabel->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); + + // Load settings + loadSettings(); + + labelFilters->setCurrentRow(0); + //labelFilters->selectionModel()->select(labelFilters->model()->index(0,0), QItemSelectionModel::Select); + + // Label menu + labelFilters->setContextMenuPolicy(Qt::CustomContextMenu); + connect(labelFilters, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showLabelMenu(QPoint))); + } + + ~TransferListFiltersWidget() { + saveSettings(); + delete statusFilters; + delete labelFilters; + delete vLayout; + } + + StatusFiltersWidget* getStatusFilters() const { + return statusFilters; + } + + void saveSettings() const { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.beginGroup(QString::fromUtf8("TransferListFilters")); + settings.setValue("selectedFilterIndex", QVariant(statusFilters->currentRow())); + //settings.setValue("selectedLabelIndex", QVariant(labelFilters->currentRow())); + settings.setValue("customLabels", QVariant(customLabels.keys())); + } + + void loadSettings() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + statusFilters->setCurrentRow(settings.value("TransferListFilters/selectedFilterIndex", 0).toInt()); + const QStringList label_list = Preferences().getTorrentLabels(); + foreach(const QString &label, label_list) { + customLabels.insert(label, 0); + qDebug("Creating label QListWidgetItem: %s", qPrintable(label)); + QListWidgetItem *newLabel = new QListWidgetItem(); + newLabel->setText(label + " (0)"); + newLabel->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); + labelFilters->addItem(newLabel); + } + } + +protected slots: + void updateTorrentNumbers() { + const TorrentStatusReport report = transferList->getSourceModel()->getTorrentStatusReport(); + statusFilters->item(FILTER_ALL)->setData(Qt::DisplayRole, QVariant(tr("All")+" ("+QString::number(report.nb_active+report.nb_inactive)+")")); + statusFilters->item(FILTER_DOWNLOADING)->setData(Qt::DisplayRole, QVariant(tr("Downloading")+" ("+QString::number(report.nb_downloading)+")")); + statusFilters->item(FILTER_COMPLETED)->setData(Qt::DisplayRole, QVariant(tr("Completed")+" ("+QString::number(report.nb_seeding)+")")); + statusFilters->item(FILTER_PAUSED)->setData(Qt::DisplayRole, QVariant(tr("Paused")+" ("+QString::number(report.nb_paused)+")")); + statusFilters->item(FILTER_ACTIVE)->setData(Qt::DisplayRole, QVariant(tr("Active")+" ("+QString::number(report.nb_active)+")")); + statusFilters->item(FILTER_INACTIVE)->setData(Qt::DisplayRole, QVariant(tr("Inactive")+" ("+QString::number(report.nb_inactive)+")")); + } + + void torrentDropped(int row) { + Q_ASSERT(row > 0); + if(row == 1) { + transferList->setSelectionLabel(""); + } else { + transferList->setSelectionLabel(labelFilters->labelFromRow(row)); + } + } + + void addLabel(QString label) { + label = misc::toValidFileSystemName(label.trimmed()); + if(label.isEmpty() || customLabels.contains(label)) return; + QListWidgetItem *newLabel = new QListWidgetItem(); + newLabel->setText(label + " (0)"); + newLabel->setData(Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); + labelFilters->addItem(newLabel); + customLabels.insert(label, 0); + Preferences().addTorrentLabel(label); + } + + void showLabelMenu(QPoint) { + QMenu labelMenu(labelFilters); + QAction *removeAct = 0; + if(!labelFilters->selectedItems().empty() && labelFilters->row(labelFilters->selectedItems().first()) > 1) + removeAct = labelMenu.addAction(IconProvider::instance()->getIcon("list-remove"), tr("Remove label")); + QAction *addAct = labelMenu.addAction(IconProvider::instance()->getIcon("list-add"), tr("Add label...")); + labelMenu.addSeparator(); + QAction *startAct = labelMenu.addAction(IconProvider::instance()->getIcon("media-playback-start"), tr("Resume torrents")); + QAction *pauseAct = labelMenu.addAction(IconProvider::instance()->getIcon("media-playback-pause"), tr("Pause torrents")); + QAction *deleteTorrentsAct = labelMenu.addAction(IconProvider::instance()->getIcon("edit-delete"), tr("Delete torrents")); + QAction *act = 0; + act = labelMenu.exec(QCursor::pos()); + if(act) { + if(act == removeAct) { + removeSelectedLabel(); + return; + } + if(act == deleteTorrentsAct) { + transferList->deleteVisibleTorrents(); + return; + } + if(act == startAct) { + transferList->startVisibleTorrents(); + return; + } + if(act == pauseAct) { + transferList->pauseVisibleTorrents(); + return; + } + if(act == addAct) { + bool ok; + QString label = ""; + bool invalid; + do { + invalid = false; + label = QInputDialog::getText(this, tr("New Label"), tr("Label:"), QLineEdit::Normal, label, &ok); + if (ok && !label.isEmpty()) { + if(misc::isValidFileSystemName(label)) { + addLabel(label); + } else { + QMessageBox::warning(this, tr("Invalid label name"), tr("Please don't use any special characters in the label name.")); + invalid = true; + } + } + } while(invalid); + return; + } + } + } + + void removeSelectedLabel() { + const int row = labelFilters->row(labelFilters->selectedItems().first()); + Q_ASSERT(row > 1); + const QString &label = labelFilters->labelFromRow(row); + Q_ASSERT(customLabels.contains(label)); + customLabels.remove(label); + transferList->removeLabelFromRows(label); + // Select first label + labelFilters->setCurrentItem(labelFilters->item(0)); + labelFilters->selectionModel()->select(labelFilters->model()->index(0,0), QItemSelectionModel::Select); + applyLabelFilter(0); + // Un display filter + delete labelFilters->takeItem(row); + // Save custom labels to remember it was deleted + Preferences().removeTorrentLabel(label); + } + + void applyLabelFilter(int row) { + switch(row) { + case 0: + transferList->applyLabelFilter("all"); + break; + case 1: + transferList->applyLabelFilter("none"); + break; + default: + transferList->applyLabelFilter(labelFilters->labelFromRow(row)); + } + } + + void torrentChangedLabel(TorrentModelItem *torrentItem, QString old_label, QString new_label) { + Q_UNUSED(torrentItem); + qDebug("Torrent label changed from %s to %s", qPrintable(old_label), qPrintable(new_label)); + if(!old_label.isEmpty()) { + if(customLabels.contains(old_label)) { + const int new_count = customLabels.value(old_label, 0) - 1; + Q_ASSERT(new_count >= 0); + customLabels.insert(old_label, new_count); + const int row = labelFilters->rowFromLabel(old_label); + Q_ASSERT(row >= 2); + labelFilters->item(row)->setText(old_label + " ("+ QString::number(new_count) +")"); + } + --nb_labeled; + } + if(!new_label.isEmpty()) { + if(!customLabels.contains(new_label)) + addLabel(new_label); + const int new_count = customLabels.value(new_label, 0) + 1; + Q_ASSERT(new_count >= 1); + customLabels.insert(new_label, new_count); + const int row = labelFilters->rowFromLabel(new_label); + Q_ASSERT(row >= 2); + labelFilters->item(row)->setText(new_label + " ("+ QString::number(new_count) +")"); + ++nb_labeled; + } + updateStickyLabelCounters(); + } + + void handleNewTorrent(TorrentModelItem* torrentItem) { + QString label = torrentItem->data(TorrentModelItem::TR_LABEL).toString(); + qDebug("New torrent was added with label: %s", qPrintable(label)); + if(!label.isEmpty()) { + if(!customLabels.contains(label)) { + addLabel(label); + } + // Update label counter + Q_ASSERT(customLabels.contains(label)); + const int new_count = customLabels.value(label, 0) + 1; + customLabels.insert(label, new_count); + const int row = labelFilters->rowFromLabel(label); + qDebug("torrentAdded, Row: %d", row); + Q_ASSERT(row >= 2); + Q_ASSERT(labelFilters->item(row)); + labelFilters->item(row)->setText(label + " ("+ QString::number(new_count) +")"); + ++nb_labeled; + } + ++nb_torrents; + Q_ASSERT(nb_torrents >= 0); + Q_ASSERT(nb_labeled >= 0); + Q_ASSERT(nb_labeled <= nb_torrents); + updateStickyLabelCounters(); + } + + void torrentAboutToBeDeleted(TorrentModelItem* torrentItem) { + Q_ASSERT(torrentItem); + QString label = torrentItem->data(TorrentModelItem::TR_LABEL).toString(); + if(!label.isEmpty()) { + // Update label counter + const int new_count = customLabels.value(label, 0) - 1; + customLabels.insert(label, new_count); + const int row = labelFilters->rowFromLabel(label); + Q_ASSERT(row >= 2); + labelFilters->item(row)->setText(label + " ("+ QString::number(new_count) +")"); + --nb_labeled; + } + --nb_torrents; + qDebug("nb_torrents: %d, nb_labeled: %d", nb_torrents, nb_labeled); + Q_ASSERT(nb_torrents >= 0); + Q_ASSERT(nb_labeled >= 0); + Q_ASSERT(nb_labeled <= nb_torrents); + updateStickyLabelCounters(); + } + + void updateStickyLabelCounters() { + labelFilters->item(0)->setText(tr("All labels") + " ("+QString::number(nb_torrents)+")"); + labelFilters->item(1)->setText(tr("Unlabeled") + " ("+QString::number(nb_torrents-nb_labeled)+")"); + } + +}; + +#endif // TRANSFERLISTFILTERSWIDGET_H diff --git a/src/transferlistwidget.cpp b/src/transferlistwidget.cpp new file mode 100644 index 000000000..a05695c00 --- /dev/null +++ b/src/transferlistwidget.cpp @@ -0,0 +1,917 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "transferlistwidget.h" +#include "qbtsession.h" +#include "torrentpersistentdata.h" +#include "transferlistdelegate.h" +#include "previewselect.h" +#include "speedlimitdlg.h" +#include "updownratiodlg.h" +#include "options_imp.h" +#include "mainwindow.h" +#include "preferences.h" +#include "torrentmodel.h" +#include "deletionconfirmationdlg.h" +#include "propertieswidget.h" +#include "qinisettings.h" +#include "iconprovider.h" + +using namespace libtorrent; + +TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *main_window, QBtSession *_BTSession): + QTreeView(parent), BTSession(_BTSession), main_window(main_window) { + + // Load settings + bool column_loaded = loadSettings(); + + // Create and apply delegate + listDelegate = new TransferListDelegate(this); + setItemDelegate(listDelegate); + + // Create transfer list model + listModel = new TorrentModel(this); + + // Set Sort/Filter proxy + labelFilterModel = new QSortFilterProxyModel(); + labelFilterModel->setDynamicSortFilter(true); + labelFilterModel->setSourceModel(listModel); + labelFilterModel->setFilterKeyColumn(TorrentModelItem::TR_LABEL); + labelFilterModel->setFilterRole(Qt::DisplayRole); + + statusFilterModel = new QSortFilterProxyModel(); + statusFilterModel->setDynamicSortFilter(true); + statusFilterModel->setSourceModel(labelFilterModel); + statusFilterModel->setFilterKeyColumn(TorrentModelItem::TR_STATUS); + statusFilterModel->setFilterRole(Qt::DisplayRole); + + nameFilterModel = new QSortFilterProxyModel(); + nameFilterModel->setDynamicSortFilter(true); + nameFilterModel->setSourceModel(statusFilterModel); + nameFilterModel->setFilterKeyColumn(TorrentModelItem::TR_NAME); + nameFilterModel->setFilterRole(Qt::DisplayRole); + + setModel(nameFilterModel); + + // Visual settings + setRootIsDecorated(false); + setAllColumnsShowFocus(true); + setSortingEnabled(true); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setItemsExpandable(false); + setAutoScroll(true); + setDragDropMode(QAbstractItemView::DragOnly); + + // Default hidden columns + if(!column_loaded) { + setColumnHidden(TorrentModelItem::TR_PRIORITY, true); + setColumnHidden(TorrentModelItem::TR_ADD_DATE, true); + setColumnHidden(TorrentModelItem::TR_SEED_DATE, true); + setColumnHidden(TorrentModelItem::TR_UPLIMIT, true); + setColumnHidden(TorrentModelItem::TR_DLLIMIT, true); + setColumnHidden(TorrentModelItem::TR_TRACKER, true); + setColumnHidden(TorrentModelItem::TR_AMOUNT_DOWNLOADED, true); + setColumnHidden(TorrentModelItem::TR_AMOUNT_LEFT, true); + setColumnHidden(TorrentModelItem::TR_TIME_ELAPSED, true); + } + + setContextMenuPolicy(Qt::CustomContextMenu); + + // Listen for list events + connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(torrentDoubleClicked(QModelIndex))); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayListMenu(const QPoint&))); + header()->setContextMenuPolicy(Qt::CustomContextMenu); + connect(header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLHoSMenu(const QPoint&))); +} + +TransferListWidget::~TransferListWidget() { + qDebug() << Q_FUNC_INFO << "ENTER"; + // Save settings + saveSettings(); + // Clean up + delete labelFilterModel; + delete statusFilterModel; + delete nameFilterModel; + delete listModel; + delete listDelegate; + qDebug() << Q_FUNC_INFO << "EXIT"; +} + +TorrentModel* TransferListWidget::getSourceModel() const { + return listModel; +} + +void TransferListWidget::previewFile(QString filePath) { + QDesktopServices::openUrl(QUrl::fromLocalFile(filePath)); +} + +void TransferListWidget::setRefreshInterval(int t) { + qDebug("Settings transfer list refresh interval to %dms", t); + listModel->setRefreshInterval(t); +} + +int TransferListWidget::getRowFromHash(QString hash) const{ + return listModel->torrentRow(hash); +} + +inline QString TransferListWidget::getHashFromRow(int row) const { + return listModel->torrentHash(row); +} + +inline QModelIndex TransferListWidget::mapToSource(const QModelIndex &index) const { + Q_ASSERT(index.isValid()); + if(index.model() == nameFilterModel) + return labelFilterModel->mapToSource(statusFilterModel->mapToSource(nameFilterModel->mapToSource(index))); + if(index.model() == statusFilterModel) + return labelFilterModel->mapToSource(statusFilterModel->mapToSource(index)); + return labelFilterModel->mapToSource(index); +} + +inline QModelIndex TransferListWidget::mapFromSource(const QModelIndex &index) const { + Q_ASSERT(index.isValid()); + Q_ASSERT(index.model() == labelFilterModel); + return nameFilterModel->mapFromSource(statusFilterModel->mapFromSource(labelFilterModel->mapFromSource(index))); +} + + +QStringList TransferListWidget::getCustomLabels() const { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + return settings.value("TransferListFilters/customLabels", QStringList()).toStringList(); +} + +void TransferListWidget::torrentDoubleClicked(const QModelIndex& index) { + const int row = mapToSource(index).row(); + const QString hash = getHashFromRow(row); + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(!h.is_valid()) return; + int action; + if(h.is_seed()) { + action = Preferences().getActionOnDblClOnTorrentFn(); + } else { + action = Preferences().getActionOnDblClOnTorrentDl(); + } + + switch(action) { + case TOGGLE_PAUSE: + if(h.is_paused()) { + h.resume(); + } else { + h.pause(); + } + break; + case OPEN_DEST: + QDesktopServices::openUrl(QUrl::fromLocalFile(h.save_path())); + break; + } +} + +QStringList TransferListWidget::getSelectedTorrentsHashes() const { + QStringList hashes; + const QModelIndexList selectedIndexes = selectionModel()->selectedRows(); + foreach(const QModelIndex &index, selectedIndexes) { + hashes << getHashFromRow(mapToSource(index).row()); + } + return hashes; +} + +void TransferListWidget::setSelectedTorrentsLocation() { + const QStringList hashes = getSelectedTorrentsHashes(); + if(hashes.isEmpty()) return; + QString dir; + const QDir saveDir(TorrentPersistentData::getSavePath(hashes.first())); + qDebug("Old save path is %s", qPrintable(saveDir.absolutePath())); + dir = QFileDialog::getExistingDirectory(this, tr("Choose save path"), saveDir.absolutePath(), + QFileDialog::DontConfirmOverwrite|QFileDialog::ShowDirsOnly|QFileDialog::HideNameFilterDetails); + if(!dir.isNull()) { + qDebug("New path is %s", qPrintable(dir)); + // Check if savePath exists + QDir savePath(misc::expandPath(dir)); + qDebug("New path after clean up is %s", qPrintable(savePath.absolutePath())); + foreach(const QString & hash, hashes) { + // Actually move storage + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(!BTSession->useTemporaryFolder() || h.is_seed()) { + if(!savePath.exists()) savePath.mkpath(savePath.absolutePath()); + h.move_storage(savePath.absolutePath()); + } else { + TorrentPersistentData::saveSavePath(h.hash(), savePath.absolutePath()); + main_window->getProperties()->updateSavePath(h); + } + } + } +} + +void TransferListWidget::startSelectedTorrents() { + const QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + BTSession->resumeTorrent(hash); + } +} + +void TransferListWidget::startVisibleTorrents() { + QStringList hashes; + for(int i=0; irowCount(); ++i) { + const int row = mapToSource(nameFilterModel->index(i, 0)).row(); + hashes << getHashFromRow(row); + } + foreach(const QString &hash, hashes) { + BTSession->resumeTorrent(hash); + } +} + +void TransferListWidget::pauseSelectedTorrents() { + const QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + BTSession->pauseTorrent(hash); + } +} + +void TransferListWidget::pauseVisibleTorrents() { + QStringList hashes; + for(int i=0; irowCount(); ++i) { + const int row = mapToSource(nameFilterModel->index(i, 0)).row(); + hashes << getHashFromRow(row); + } + foreach(const QString &hash, hashes) { + BTSession->pauseTorrent(hash); + } +} + +void TransferListWidget::deleteSelectedTorrents() { + if(main_window->getCurrentTabWidget() != this) return; + const QStringList& hashes = getSelectedTorrentsHashes(); + if(hashes.empty()) return; + bool delete_local_files = false; + if(Preferences().confirmTorrentDeletion() && + !DeletionConfirmationDlg::askForDeletionConfirmation(&delete_local_files)) + return; + foreach(const QString &hash, hashes) { + BTSession->deleteTorrent(hash, delete_local_files); + } +} + +void TransferListWidget::deleteVisibleTorrents() { + if(nameFilterModel->rowCount() <= 0) return; + bool delete_local_files = false; + if(Preferences().confirmTorrentDeletion() && + !DeletionConfirmationDlg::askForDeletionConfirmation(&delete_local_files)) + return; + QStringList hashes; + for(int i=0; irowCount(); ++i) { + const int row = mapToSource(nameFilterModel->index(i, 0)).row(); + hashes << getHashFromRow(row); + } + foreach(const QString &hash, hashes) { + BTSession->deleteTorrent(hash, delete_local_files); + } +} + +void TransferListWidget::increasePrioSelectedTorrents() { + qDebug() << Q_FUNC_INFO; + if(main_window->getCurrentTabWidget() != this) return; + const QStringList hashes = getSelectedTorrentsHashes(); + std::priority_queue, std::vector >, std::greater > > torrent_queue; + // Sort torrents by priority + foreach(const QString &hash, hashes) { + try { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(!h.is_seed()) { + torrent_queue.push(qMakePair(h.queue_position(), h)); + } + }catch(invalid_handle&){} + } + // Increase torrents priority (starting with the ones with highest priority) + while(!torrent_queue.empty()) { + QTorrentHandle h = torrent_queue.top().second; + try { + h.queue_position_up(); + } catch(invalid_handle& h) {} + torrent_queue.pop(); + } +} + +void TransferListWidget::decreasePrioSelectedTorrents() { + qDebug() << Q_FUNC_INFO; + if(main_window->getCurrentTabWidget() != this) return; + const QStringList hashes = getSelectedTorrentsHashes(); + std::priority_queue, std::vector >, std::less > > torrent_queue; + // Sort torrents by priority + foreach(const QString &hash, hashes) { + try { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(!h.is_seed()) { + torrent_queue.push(qMakePair(h.queue_position(), h)); + } + }catch(invalid_handle&){} + } + // Decrease torrents priority (starting with the ones with lowest priority) + while(!torrent_queue.empty()) { + QTorrentHandle h = torrent_queue.top().second; + try { + h.queue_position_down(); + } catch(invalid_handle& h) {} + torrent_queue.pop(); + } +} + +void TransferListWidget::topPrioSelectedTorrents() { + if(main_window->getCurrentTabWidget() != this) return; + const QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_valid() && !h.is_seed()) { + h.queue_position_top(); + } + } +} + +void TransferListWidget::bottomPrioSelectedTorrents() { + if(main_window->getCurrentTabWidget() != this) return; + const QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_valid() && !h.is_seed()) { + h.queue_position_bottom(); + } + } +} + +void TransferListWidget::copySelectedMagnetURIs() const { + QStringList magnet_uris; + const QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + const QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_valid() && h.has_metadata()) + magnet_uris << misc::toQString(make_magnet_uri(h.get_torrent_info())); + } + qApp->clipboard()->setText(magnet_uris.join("\n")); +} + +void TransferListWidget::hidePriorityColumn(bool hide) { + qDebug("hidePriorityColumn(%d)", hide); + setColumnHidden(TorrentModelItem::TR_PRIORITY, hide); +} + +void TransferListWidget::openSelectedTorrentsFolder() const { + QStringList pathsList; + const QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + const QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_valid()) { + const QString savePath = h.save_path(); + qDebug("Opening path at %s", qPrintable(savePath)); + if(!pathsList.contains(savePath)) { + pathsList.append(savePath); + QDesktopServices::openUrl(QUrl::fromLocalFile(savePath)); + } + } + } +} + +void TransferListWidget::previewSelectedTorrents() { + const QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + const QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_valid() && h.has_metadata()) { + new PreviewSelect(this, h); + } + } +} + +void TransferListWidget::setDlLimitSelectedTorrents() { + QList selected_torrents; + bool first = true; + bool all_same_limit = true; + const QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + const QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_valid() && !h.is_seed()) { + selected_torrents << h; + // Determine current limit for selected torrents + if(first) { + first = false; + } else { + if(all_same_limit && h.download_limit() != selected_torrents.first().download_limit()) + all_same_limit = false; + } + } + } + if(selected_torrents.empty()) return; + + bool ok=false; + int default_limit = -1; + if(all_same_limit) + default_limit = selected_torrents.first().download_limit(); + const long new_limit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Torrent Download Speed Limiting"), default_limit, Preferences().getGlobalDownloadLimit()*1024.); + if(ok) { + foreach(const QTorrentHandle &h, selected_torrents) { + qDebug("Applying download speed limit of %ld Kb/s to torrent %s", (long)(new_limit/1024.), qPrintable(h.hash())); + BTSession->setDownloadLimit(h.hash(), new_limit); + } + } +} + +void TransferListWidget::setUpLimitSelectedTorrents() { + QList selected_torrents; + bool first = true; + bool all_same_limit = true; + const QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + const QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_valid()) { + selected_torrents << h; + // Determine current limit for selected torrents + if(first) { + first = false; + } else { + if(all_same_limit && h.upload_limit() != selected_torrents.first().upload_limit()) + all_same_limit = false; + } + } + } + if(selected_torrents.empty()) return; + + bool ok=false; + int default_limit = -1; + if(all_same_limit) + default_limit = selected_torrents.first().upload_limit(); + const long new_limit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Torrent Upload Speed Limiting"), default_limit, Preferences().getGlobalUploadLimit()*1024.); + if(ok) { + foreach(const QTorrentHandle &h, selected_torrents) { + qDebug("Applying upload speed limit of %ld Kb/s to torrent %s", (long)(new_limit/1024.), qPrintable(h.hash())); + BTSession->setUploadLimit(h.hash(), new_limit); + } + } +} + +void TransferListWidget::setMaxRatioSelectedTorrents() { + const QStringList hashes = getSelectedTorrentsHashes(); + if (hashes.isEmpty()) + return; + bool useGlobalValue; + qreal currentMaxRatio; + if (hashes.count() == 1) { + currentMaxRatio = BTSession->getMaxRatioPerTorrent(hashes.first(), &useGlobalValue); + } else { + useGlobalValue = true; + currentMaxRatio = BTSession->getGlobalMaxRatio(); + } + UpDownRatioDlg dlg(useGlobalValue, currentMaxRatio, QBtSession::MAX_RATIO, this); + if (dlg.exec() != QDialog::Accepted) + return; + foreach (const QString &hash, hashes) { + if (dlg.useDefault()) + BTSession->removeRatioPerTorrent(hash); + else + BTSession->setMaxRatioPerTorrent(hash, dlg.ratio()); + } +} + +void TransferListWidget::recheckSelectedTorrents() { + const QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + BTSession->recheckTorrent(hash); + } +} + +// hide/show columns menu +void TransferListWidget::displayDLHoSMenu(const QPoint&){ + QMenu hideshowColumn(this); + hideshowColumn.setTitle(tr("Column visibility")); + QList actions; + for(int i=0; i < listModel->columnCount(); ++i) { + if(!BTSession->isQueueingEnabled() && i == TorrentModelItem::TR_PRIORITY) { + actions.append(0); + continue; + } + QAction *myAct = hideshowColumn.addAction(listModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString()); + myAct->setCheckable(true); + myAct->setChecked(!isColumnHidden(i)); + actions.append(myAct); + } + // Call menu + QAction *act = hideshowColumn.exec(QCursor::pos()); + if(act) { + int col = actions.indexOf(act); + Q_ASSERT(col >= 0); + qDebug("Toggling column %d visibility", col); + setColumnHidden(col, !isColumnHidden(col)); + if(!isColumnHidden(col) && columnWidth(col) <= 5) + setColumnWidth(col, 100); + } +} + +#if LIBTORRENT_VERSION_MINOR > 14 +void TransferListWidget::toggleSelectedTorrentsSuperSeeding() const { + const QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_valid() && h.has_metadata()) { + h.super_seeding(!h.super_seeding()); + } + } +} +#endif + +void TransferListWidget::toggleSelectedTorrentsSequentialDownload() const { + const QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_valid() && h.has_metadata()) { + bool was_sequential = h.is_sequential_download(); + h.set_sequential_download(!was_sequential); + if(!was_sequential) + h.prioritize_first_last_piece(true); + } + } +} + +void TransferListWidget::toggleSelectedFirstLastPiecePrio() const { + QStringList hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(h.is_valid() && h.has_metadata()) { + h.prioritize_first_last_piece(!h.first_last_piece_first()); + } + } +} + +void TransferListWidget::askNewLabelForSelection() { + // Ask for label + bool ok; + bool invalid; + do { + invalid = false; + const QString label = QInputDialog::getText(this, tr("New Label"), tr("Label:"), QLineEdit::Normal, "", &ok); + if (ok && !label.isEmpty()) { + if(misc::isValidFileSystemName(label)) { + setSelectionLabel(label); + } else { + QMessageBox::warning(this, tr("Invalid label name"), tr("Please don't use any special characters in the label name.")); + invalid = true; + } + } + }while(invalid); +} + +void TransferListWidget::renameSelectedTorrent() { + const QModelIndexList selectedIndexes = selectionModel()->selectedRows(); + if(selectedIndexes.size() != 1) return; + if(!selectedIndexes.first().isValid()) return; + const QString hash = getHashFromRow(mapToSource(selectedIndexes.first()).row()); + const QTorrentHandle h = BTSession->getTorrentHandle(hash); + if(!h.is_valid()) return; + // Ask for a new Name + bool ok; + const QString name = QInputDialog::getText(this, tr("Rename"), tr("New name:"), QLineEdit::Normal, h.name(), &ok); + if (ok && !name.isEmpty()) { + // Rename the torrent + nameFilterModel->setData(selectedIndexes.first(), name, Qt::DisplayRole); + } +} + +void TransferListWidget::setSelectionLabel(QString label) { + const QStringList& hashes = getSelectedTorrentsHashes(); + foreach(const QString &hash, hashes) { + Q_ASSERT(!hash.isEmpty()); + const int row = getRowFromHash(hash); + const QString old_label = listModel->data(listModel->index(row, TorrentModelItem::TR_LABEL)).toString(); + listModel->setData(listModel->index(row, TorrentModelItem::TR_LABEL), QVariant(label), Qt::DisplayRole); + // Update save path if necessary + QTorrentHandle h = BTSession->getTorrentHandle(hash); + BTSession->changeLabelInTorrentSavePath(h, old_label, label); + } +} + +void TransferListWidget::removeLabelFromRows(QString label) { + for(int i=0; irowCount(); ++i) { + if(listModel->data(listModel->index(i, TorrentModelItem::TR_LABEL)) == label) { + const QString hash = getHashFromRow(i); + listModel->setData(listModel->index(i, TorrentModelItem::TR_LABEL), "", Qt::DisplayRole); + // Update save path if necessary + QTorrentHandle h = BTSession->getTorrentHandle(hash); + BTSession->changeLabelInTorrentSavePath(h, label, ""); + } + } +} + +void TransferListWidget::displayListMenu(const QPoint&) { + // Create actions + QAction actionStart(IconProvider::instance()->getIcon("media-playback-start"), tr("Resume", "Resume/start the torrent"), 0); + connect(&actionStart, SIGNAL(triggered()), this, SLOT(startSelectedTorrents())); + QAction actionPause(IconProvider::instance()->getIcon("media-playback-pause"), tr("Pause", "Pause the torrent"), 0); + connect(&actionPause, SIGNAL(triggered()), this, SLOT(pauseSelectedTorrents())); + QAction actionDelete(IconProvider::instance()->getIcon("edit-delete"), tr("Delete", "Delete the torrent"), 0); + connect(&actionDelete, SIGNAL(triggered()), this, SLOT(deleteSelectedTorrents())); + QAction actionPreview_file(IconProvider::instance()->getIcon("view-preview"), tr("Preview file..."), 0); + connect(&actionPreview_file, SIGNAL(triggered()), this, SLOT(previewSelectedTorrents())); + QAction actionSet_max_ratio(QIcon(QString::fromUtf8(":/Icons/skin/ratio.png")), tr("Limit share ratio..."), 0); + connect(&actionSet_max_ratio, SIGNAL(triggered()), this, SLOT(setMaxRatioSelectedTorrents())); + QAction actionSet_upload_limit(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")), tr("Limit upload rate..."), 0); + connect(&actionSet_upload_limit, SIGNAL(triggered()), this, SLOT(setUpLimitSelectedTorrents())); + QAction actionSet_download_limit(QIcon(QString::fromUtf8(":/Icons/skin/download.png")), tr("Limit download rate..."), 0); + connect(&actionSet_download_limit, SIGNAL(triggered()), this, SLOT(setDlLimitSelectedTorrents())); + QAction actionOpen_destination_folder(IconProvider::instance()->getIcon("inode-directory"), tr("Open destination folder"), 0); + connect(&actionOpen_destination_folder, SIGNAL(triggered()), this, SLOT(openSelectedTorrentsFolder())); + QAction actionIncreasePriority(IconProvider::instance()->getIcon("go-up"), tr("Move up", "i.e. move up in the queue"), 0); + connect(&actionIncreasePriority, SIGNAL(triggered()), this, SLOT(increasePrioSelectedTorrents())); + QAction actionDecreasePriority(IconProvider::instance()->getIcon("go-down"), tr("Move down", "i.e. Move down in the queue"), 0); + connect(&actionDecreasePriority, SIGNAL(triggered()), this, SLOT(decreasePrioSelectedTorrents())); + QAction actionTopPriority(IconProvider::instance()->getIcon("go-top"), tr("Move to top", "i.e. Move to top of the queue"), 0); + connect(&actionTopPriority, SIGNAL(triggered()), this, SLOT(topPrioSelectedTorrents())); + QAction actionBottomPriority(IconProvider::instance()->getIcon("go-bottom"), tr("Move to bottom", "i.e. Move to bottom of the queue"), 0); + connect(&actionBottomPriority, SIGNAL(triggered()), this, SLOT(bottomPrioSelectedTorrents())); + QAction actionSetTorrentPath(IconProvider::instance()->getIcon("inode-directory"), tr("Set location..."), 0); + connect(&actionSetTorrentPath, SIGNAL(triggered()), this, SLOT(setSelectedTorrentsLocation())); + QAction actionForce_recheck(IconProvider::instance()->getIcon("document-edit-verify"), tr("Force recheck"), 0); + connect(&actionForce_recheck, SIGNAL(triggered()), this, SLOT(recheckSelectedTorrents())); + QAction actionCopy_magnet_link(QIcon(":/Icons/magnet.png"), tr("Copy magnet link"), 0); + connect(&actionCopy_magnet_link, SIGNAL(triggered()), this, SLOT(copySelectedMagnetURIs())); +#if LIBTORRENT_VERSION_MINOR > 14 + QAction actionSuper_seeding_mode(tr("Super seeding mode"), 0); + actionSuper_seeding_mode.setCheckable(true); + connect(&actionSuper_seeding_mode, SIGNAL(triggered()), this, SLOT(toggleSelectedTorrentsSuperSeeding())); +#endif + QAction actionRename(IconProvider::instance()->getIcon("edit-rename"), tr("Rename..."), 0); + connect(&actionRename, SIGNAL(triggered()), this, SLOT(renameSelectedTorrent())); + QAction actionSequential_download(tr("Download in sequential order"), 0); + actionSequential_download.setCheckable(true); + connect(&actionSequential_download, SIGNAL(triggered()), this, SLOT(toggleSelectedTorrentsSequentialDownload())); + QAction actionFirstLastPiece_prio(tr("Download first and last piece first"), 0); + actionFirstLastPiece_prio.setCheckable(true); + connect(&actionFirstLastPiece_prio, SIGNAL(triggered()), this, SLOT(toggleSelectedFirstLastPiecePrio())); + // End of actions + QMenu listMenu(this); + // Enable/disable pause/start action given the DL state + QModelIndexList selectedIndexes = selectionModel()->selectedRows(); + bool has_pause = false, has_start = false, has_preview = false; +#if LIBTORRENT_VERSION_MINOR > 14 + bool all_same_super_seeding = true; + bool super_seeding_mode = false; +#endif + bool all_same_sequential_download_mode = true, all_same_prio_firstlast = true; + bool sequential_download_mode = false, prioritize_first_last = false; + bool one_has_metadata = false, one_not_seed = false; + bool first = true; + QTorrentHandle h; + qDebug("Displaying menu"); + foreach(const QModelIndex &index, selectedIndexes) { + // Get the file name + QString hash = getHashFromRow(mapToSource(index).row()); + // Get handle and pause the torrent + h = BTSession->getTorrentHandle(hash); + if(!h.is_valid()) continue; + if(h.has_metadata()) + one_has_metadata = true; + if(!h.is_seed()) { + one_not_seed = true; + if(h.has_metadata()) { + if(first) { + sequential_download_mode = h.is_sequential_download(); + prioritize_first_last = h.first_last_piece_first(); + } else { + if(sequential_download_mode != h.is_sequential_download()) { + all_same_sequential_download_mode = false; + } + if(prioritize_first_last != h.first_last_piece_first()) { + all_same_prio_firstlast = false; + } + } + } + } +#if LIBTORRENT_VERSION_MINOR > 14 + else { + if(!one_not_seed && all_same_super_seeding && h.has_metadata()) { + if(first) { + super_seeding_mode = h.super_seeding(); + } else { + if(super_seeding_mode != h.super_seeding()) { + all_same_super_seeding = false; + } + } + } + } +#endif + if(h.is_paused()) { + if(!has_start) { + listMenu.addAction(&actionStart); + has_start = true; + } + }else{ + if(!has_pause) { + listMenu.addAction(&actionPause); + has_pause = true; + } + } + if(h.has_metadata() && BTSession->isFilePreviewPossible(hash) && !has_preview) { + has_preview = true; + } + first = false; + if(has_pause && has_start && has_preview && one_not_seed) break; + } + listMenu.addSeparator(); + listMenu.addAction(&actionDelete); + listMenu.addSeparator(); + listMenu.addAction(&actionSetTorrentPath); + if(selectedIndexes.size() == 1) + listMenu.addAction(&actionRename); + // Label Menu + QStringList customLabels = getCustomLabels(); + customLabels.sort(); + QList labelActions; + QMenu *labelMenu = listMenu.addMenu(IconProvider::instance()->getIcon("view-categories"), tr("Label")); + labelActions << labelMenu->addAction(IconProvider::instance()->getIcon("list-add"), tr("New...", "New label...")); + labelActions << labelMenu->addAction(IconProvider::instance()->getIcon("edit-clear"), tr("Reset", "Reset label")); + labelMenu->addSeparator(); + foreach(const QString &label, customLabels) { + labelActions << labelMenu->addAction(IconProvider::instance()->getIcon("inode-directory"), label); + } + listMenu.addSeparator(); + if(one_not_seed) + listMenu.addAction(&actionSet_download_limit); + listMenu.addAction(&actionSet_max_ratio); + listMenu.addAction(&actionSet_upload_limit); +#if LIBTORRENT_VERSION_MINOR > 14 + if(!one_not_seed && all_same_super_seeding && one_has_metadata) { + actionSuper_seeding_mode.setChecked(super_seeding_mode); + listMenu.addAction(&actionSuper_seeding_mode); + } +#endif + listMenu.addSeparator(); + bool added_preview_action = false; + if(has_preview) { + listMenu.addAction(&actionPreview_file); + added_preview_action = true; + } + if(one_not_seed && one_has_metadata) { + if(all_same_sequential_download_mode) { + actionSequential_download.setChecked(sequential_download_mode); + listMenu.addAction(&actionSequential_download); + added_preview_action = true; + } + if(all_same_prio_firstlast) { + actionFirstLastPiece_prio.setChecked(prioritize_first_last); + listMenu.addAction(&actionFirstLastPiece_prio); + added_preview_action = true; + } + } + if(added_preview_action) + listMenu.addSeparator(); + if(one_has_metadata) { + listMenu.addAction(&actionForce_recheck); + listMenu.addSeparator(); + } + listMenu.addAction(&actionOpen_destination_folder); + if(BTSession->isQueueingEnabled() && one_not_seed) { + listMenu.addSeparator(); + QMenu *prioMenu = listMenu.addMenu(tr("Priority")); + prioMenu->addAction(&actionTopPriority); + prioMenu->addAction(&actionIncreasePriority); + prioMenu->addAction(&actionDecreasePriority); + prioMenu->addAction(&actionBottomPriority); + } + listMenu.addSeparator(); + if(one_has_metadata) + listMenu.addAction(&actionCopy_magnet_link); + // Call menu + QAction *act = 0; + act = listMenu.exec(QCursor::pos()); + if(act) { + // Parse label actions only (others have slots assigned) + int i = labelActions.indexOf(act); + if(i >= 0) { + // Label action + if(i == 0) { + // New Label + askNewLabelForSelection(); + } else { + QString label = ""; + if(i > 1) + label = customLabels.at(i-2); + // Update Label + setSelectionLabel(label); + } + } + } +} + +void TransferListWidget::currentChanged(const QModelIndex& current, const QModelIndex&) { + qDebug("CURRENT CHANGED"); + QTorrentHandle h; + if(current.isValid()) { + const int row = mapToSource(current).row(); + h = BTSession->getTorrentHandle(getHashFromRow(row)); + // Scroll Fix + scrollTo(current); + } + emit currentTorrentChanged(h); +} + +void TransferListWidget::applyLabelFilter(QString label) { + if(label == "all") { + labelFilterModel->setFilterRegExp(QRegExp()); + return; + } + if(label == "none") { + labelFilterModel->setFilterRegExp(QRegExp("^$")); + return; + } + qDebug("Applying Label filter: %s", qPrintable(label)); + labelFilterModel->setFilterRegExp(QRegExp("^"+label+"$", Qt::CaseSensitive)); +} + +void TransferListWidget::applyNameFilter(QString name) { + nameFilterModel->setFilterRegExp(QRegExp(name, Qt::CaseInsensitive)); +} + +void TransferListWidget::applyStatusFilter(int f) { + switch(f) { + case FILTER_DOWNLOADING: + statusFilterModel->setFilterRegExp(QRegExp(QString::number(TorrentModelItem::STATE_DOWNLOADING)+"|"+QString::number(TorrentModelItem::STATE_STALLED_DL)+"|"+ + QString::number(TorrentModelItem::STATE_PAUSED_DL)+"|"+QString::number(TorrentModelItem::STATE_CHECKING_DL)+"|"+ + QString::number(TorrentModelItem::STATE_QUEUED_DL), Qt::CaseSensitive)); + break; + case FILTER_COMPLETED: + statusFilterModel->setFilterRegExp(QRegExp(QString::number(TorrentModelItem::STATE_SEEDING)+"|"+QString::number(TorrentModelItem::STATE_STALLED_UP)+"|"+ + QString::number(TorrentModelItem::STATE_PAUSED_UP)+"|"+QString::number(TorrentModelItem::STATE_CHECKING_UP)+"|"+ + QString::number(TorrentModelItem::STATE_QUEUED_UP), Qt::CaseSensitive)); + break; + case FILTER_ACTIVE: + statusFilterModel->setFilterRegExp(QRegExp(QString::number(TorrentModelItem::STATE_DOWNLOADING)+"|"+QString::number(TorrentModelItem::STATE_SEEDING), Qt::CaseSensitive)); + break; + case FILTER_INACTIVE: + statusFilterModel->setFilterRegExp(QRegExp("[^"+QString::number(TorrentModelItem::STATE_DOWNLOADING)+QString::number(TorrentModelItem::STATE_SEEDING)+"]", Qt::CaseSensitive)); + break; + case FILTER_PAUSED: + statusFilterModel->setFilterRegExp(QRegExp(QString::number(TorrentModelItem::STATE_PAUSED_UP)+"|"+QString::number(TorrentModelItem::STATE_PAUSED_DL))); + break; + default: + statusFilterModel->setFilterRegExp(QRegExp()); + } + // Select first item if nothing is selected + if(selectionModel()->selectedRows(0).empty() && nameFilterModel->rowCount() > 0) { + qDebug("Nothing is selected, selecting first row: %s", qPrintable(nameFilterModel->index(0, TorrentModelItem::TR_NAME).data().toString())); + selectionModel()->setCurrentIndex(nameFilterModel->index(0, TorrentModelItem::TR_NAME), QItemSelectionModel::SelectCurrent|QItemSelectionModel::Rows); + } +} + +void TransferListWidget::saveSettings() +{ + QIniSettings settings("qBittorrent", "qBittorrent"); + settings.setValue("TransferList/HeaderState", header()->saveState()); +} + +bool TransferListWidget::loadSettings() +{ + QIniSettings settings("qBittorrent", "qBittorrent"); + bool ok = header()->restoreState(settings.value("TransferList/HeaderState").toByteArray()); + if(!ok) { + header()->resizeSection(0, 200); // Default + } + return ok; +} + diff --git a/src/transferlistwidget.h b/src/transferlistwidget.h new file mode 100644 index 000000000..807cfb3d9 --- /dev/null +++ b/src/transferlistwidget.h @@ -0,0 +1,122 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TRANSFERLISTWIDGET_H +#define TRANSFERLISTWIDGET_H + +#include +#include +#include "qtorrenthandle.h" + +class QBtSession; +class TransferListDelegate; +class MainWindow; +class TorrentModel; + +QT_BEGIN_NAMESPACE +class QSortFilterProxyModel; +class QStandardItemModel; +QT_END_NAMESPACE + +enum TorrentFilter {FILTER_ALL, FILTER_DOWNLOADING, FILTER_COMPLETED, FILTER_PAUSED, FILTER_ACTIVE, FILTER_INACTIVE}; + +class TransferListWidget: public QTreeView { + Q_OBJECT + +public: + TransferListWidget(QWidget *parent, MainWindow *main_window, QBtSession* BTSession); + ~TransferListWidget(); + TorrentModel* getSourceModel() const; + +public slots: + void setSelectionLabel(QString label); + void setRefreshInterval(int t); + void setSelectedTorrentsLocation(); + void startSelectedTorrents(); + void startVisibleTorrents(); + void pauseSelectedTorrents(); + void pauseVisibleTorrents(); + void deleteSelectedTorrents(); + void deleteVisibleTorrents(); + void increasePrioSelectedTorrents(); + void decreasePrioSelectedTorrents(); + void topPrioSelectedTorrents(); + void bottomPrioSelectedTorrents(); + void copySelectedMagnetURIs() const; + void openSelectedTorrentsFolder() const; + void recheckSelectedTorrents(); + void setDlLimitSelectedTorrents(); + void setUpLimitSelectedTorrents(); + void setMaxRatioSelectedTorrents(); + void previewSelectedTorrents(); + void hidePriorityColumn(bool hide); + void displayDLHoSMenu(const QPoint&); + void applyNameFilter(QString name); + void applyStatusFilter(int f); + void applyLabelFilter(QString label); + void previewFile(QString filePath); + void removeLabelFromRows(QString label); + void renameSelectedTorrent(); + +protected: + int getRowFromHash(QString hash) const; + QString getHashFromRow(int row) const; + QModelIndex mapToSource(const QModelIndex &index) const; + QModelIndex mapFromSource(const QModelIndex &index) const; + QStringList getCustomLabels() const; + void saveSettings(); + bool loadSettings(); + QStringList getSelectedTorrentsHashes() const; + +protected slots: + void torrentDoubleClicked(const QModelIndex& index); + void displayListMenu(const QPoint&); + void currentChanged(const QModelIndex& current, const QModelIndex&); +#if LIBTORRENT_VERSION_MINOR > 14 + void toggleSelectedTorrentsSuperSeeding() const; +#endif + void toggleSelectedTorrentsSequentialDownload() const; + void toggleSelectedFirstLastPiecePrio() const; + void askNewLabelForSelection(); + +signals: + void currentTorrentChanged(const QTorrentHandle &h); + +private: + TransferListDelegate *listDelegate; + TorrentModel *listModel; + QSortFilterProxyModel *nameFilterModel; + QSortFilterProxyModel *statusFilterModel; + QSortFilterProxyModel *labelFilterModel; + QBtSession* BTSession; + MainWindow *main_window; +}; + +#endif // TRANSFERLISTWIDGET_H diff --git a/src/update_qrc_files.py b/src/update_qrc_files.py new file mode 100755 index 000000000..c4ec090be --- /dev/null +++ b/src/update_qrc_files.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the author nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# Small script to update qrc files (lang.qrc, icons.qrc) +# by Christophe Dumez + +import os +from os.path import splitext, join + +# update languages files directory +languages_list = [x for x in os.listdir('lang') if x.endswith('.qm')] +output = ''' + +''' +for language in languages_list: + output += ' %s'%('lang'+os.sep+language) + output += os.linesep +output += ''' +''' +lang_file = open('lang.qrc', 'w') +lang_file.write(output) +lang_file.close() + +# update search_engine directory +os.chdir('searchengine') +search_list = [] +for root, dirs, files in os.walk('nova/'): + for file in files: + if file.startswith("__"): + continue + if splitext(file)[-1] in ('.py', '.png'): + search_list.append(join(root, file)) + +output = ''' + +''' +for file in search_list: + output += ' %s'%(file) + output += os.linesep +output += ''' +''' +search_file = open('search.qrc', 'w') +search_file.write(output) +search_file.close() + +os.chdir('..'); + +# update icons files directory +icons_list = [] +for root, dirs, files in os.walk('Icons'): + if 'skin_unused' in dirs: + dirs.remove('skin_unused') + for file in files: + if splitext(file)[-1] in ('.png', '.jpg', '.gif'): + icons_list.append(join(root, file)) + +output = ''' + +''' +for icon in icons_list: + output += ' %s'%(icon) + output += os.linesep +output += ''' +''' +icons_file = open('icons.qrc', 'w') +icons_file.write(output) +icons_file.close() + diff --git a/src/updownratiodlg.cpp b/src/updownratiodlg.cpp new file mode 100644 index 000000000..ae9762b86 --- /dev/null +++ b/src/updownratiodlg.cpp @@ -0,0 +1,75 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Christian Kandeler, Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include "updownratiodlg.h" +#include "ui_updownratiodlg.h" + +#include "preferences.h" + +UpDownRatioDlg::UpDownRatioDlg(bool useDefault, qreal initialValue, + qreal maxValue, QWidget *parent) + : QDialog(parent), ui(new Ui::UpDownRatioDlg) +{ + ui->setupUi(this); + if (useDefault) { + ui->useDefaultButton->setChecked(true); + } else if (initialValue == -1) { + ui->noLimitButton->setChecked(true); + initialValue = Preferences().getGlobalMaxRatio(); + } else { + ui->torrentLimitButton->setChecked(true); + } + ui->ratioSpinBox->setMinimum(0); + ui->ratioSpinBox->setMaximum(maxValue); + ui->ratioSpinBox->setValue(initialValue); + connect(ui->buttonGroup, SIGNAL(buttonClicked(int)), + SLOT(handleRatioTypeChanged())); + handleRatioTypeChanged(); +} + +bool UpDownRatioDlg::useDefault() const +{ + return ui->useDefaultButton->isChecked(); +} + +qreal UpDownRatioDlg::ratio() const +{ + return ui->noLimitButton->isChecked() ? -1 : ui->ratioSpinBox->value(); +} + +void UpDownRatioDlg::handleRatioTypeChanged() +{ + ui->ratioSpinBox->setEnabled(ui->torrentLimitButton->isChecked()); +} + +UpDownRatioDlg::~UpDownRatioDlg() +{ + delete ui; +} diff --git a/src/updownratiodlg.h b/src/updownratiodlg.h new file mode 100644 index 000000000..2675dc99a --- /dev/null +++ b/src/updownratiodlg.h @@ -0,0 +1,61 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Christian Kandeler, Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef UPDOWNRATIODLG_H +#define UPDOWNRATIODLG_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { + class UpDownRatioDlg; +} +QT_END_NAMESPACE + +class UpDownRatioDlg : public QDialog +{ + Q_OBJECT + +public: + explicit UpDownRatioDlg(bool useDefault, qreal initialValue, qreal maxValue, + QWidget *parent = 0); + ~UpDownRatioDlg(); + + bool useDefault() const; + qreal ratio() const; + +private slots: + void handleRatioTypeChanged(); + +private: + Ui::UpDownRatioDlg *ui; +}; + +#endif // UPDOWNRATIODLG_H diff --git a/src/updownratiodlg.ui b/src/updownratiodlg.ui new file mode 100644 index 000000000..8cf822a3a --- /dev/null +++ b/src/updownratiodlg.ui @@ -0,0 +1,137 @@ + + + UpDownRatioDlg + + + + 0 + 0 + 317 + 152 + + + + Torrent Upload/Download Ratio Limiting + + + + + + Use global ratio limit + + + buttonGroup + + + + + + + Set no ratio limit + + + buttonGroup + + + + + + + + + Set ratio limit to + + + buttonGroup + + + + + + + 1 + + + 0.100000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + UpDownRatioDlg + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + UpDownRatioDlg + reject() + + + 316 + 260 + + + 286 + 274 + + + + + + + + diff --git a/src/webui/css/Core.css b/src/webui/css/Core.css new file mode 100644 index 000000000..5475e1e52 --- /dev/null +++ b/src/webui/css/Core.css @@ -0,0 +1,54 @@ +/* + +Core.css for Mocha UI + +Theme: Default + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Notes: + CSS rules in this file: + + 1. Rules required by all MochaUI components or are shared by more than one. + 2. Theme specific ajustments to plugin styles. + 3. Miscellaneous rules that have no better place to go. + +*/ + +/* Required By All +---------------------------------------------------------------- */ + +/* Clears */ + +.clear { + clear: both; + height: 0; +} + +* html .clear { + font-size: 1px; + line-height: 1px; + overflow: hidden; + visibility: hidden; +} + +/* Miscellaneous +---------------------------------------------------------------- */ + +#themeControl { + margin-top: 2px; +} + + +/* Theme Specific Adjustments to Default Plugin Styles +---------------------------------------------------------------- */ + +/* Folder Tree */ + +.tree li a { + color: #3f3f3f !important; +} diff --git a/src/webui/css/Layout.css b/src/webui/css/Layout.css new file mode 100644 index 000000000..8543982b9 --- /dev/null +++ b/src/webui/css/Layout.css @@ -0,0 +1,427 @@ +/* + +Core.css for Mocha UI + +Theme: Default + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Required by: + Layout.js + +*/ + +/* Layout +---------------------------------------------------------------- */ + +html, body { + background: #fff; +} + +body { + margin: 0; /* Required */ +} + +#desktop { + position: relative; + min-width: 400px; /* Helps keep header content from wrapping */ + height: 100%; + min-height: 100%; + overflow: hidden; + cursor: default; /* Fix for issue in IE7. IE7 wants to use the I-bar text cursor */ +} + +#desktopHeader { + background: #f2f2f2; +} + +#desktopTitlebarWrapper { + position: relative; + height: 45px; + overflow: hidden; + background: #718BA6 url(../images/skin/bg-header.gif) repeat-x; +} + +#desktopTitlebar { + padding: 7px 8px 6px 8px; + height: 32px; + background: url(../images/skin/logo.gif) no-repeat; + background-position: left 0; +} + +#desktopTitlebar h1.applicationTitle { + display: none; + margin: 0; + padding: 0 5px 0 0; + font-size: 20px; + line-height: 25px; + font-weight: bold; + color: #fff; +} + +#desktopTitlebar h2.tagline { + padding: 7px 0 0 0; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; + color: #d4dce4; + font-weight: bold; + text-align: center; + text-transform: uppercase; +} + +#desktopTitlebar h2.tagline .taglineEm { + color: #fff; + font-weight: bold; +} + +#topNav { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; + position: absolute; + right: 0; + top: 0; + color: #d4dce4; + text-align: right; + padding: 13px 10px 0 0; +} + +#topNav a { + color: #fff; + font-weight: normal; +} + +#topNav a:hover { + text-decoration: none; +} + +/* Navbar */ + +#desktopNavbar { + background: #f2f2f2; + /*height: 30px;*/ + margin: 0 0px; + overflow: hidden; /* Remove this line if you want the menu to be backward compatible with Firefox 2 */ + /* Fixes by Chris */ + /*background-color: #ccc;*/ + height: 20px; + margin-bottom: 5px; + border-bottom: 1px solid #3f3f3f; +} + +#desktopNavbar ul { + padding: 0; + margin: 0; + list-style: none; + font-size: 12px; +} + +#desktopNavbar li { + float: left; +} + +#desktopNavbar a { + display: block; +} + +#desktopNavbar ul li a { + /*padding: 6px 10px 6px 10px;*/ + color: #333; + font-weight: normal; + /* Fix by Chris */ + padding: 2px 10px 6px 10px; +} + +#desktopNavbar ul li a:hover { + color: #333; + /* Fix By Chris */ + background-color: #fff; +} + +#desktopNavbar ul li a.arrow-right, #desktopNavbar ul li a:hover.arrow-right { + background-image: url(../images/skin/arrow-right.gif); + background-repeat: no-repeat; + background-position: right 7px; +} + +#desktopNavbar li ul { + padding: 2px; + border: 1px solid #3f3f3f; + background: #fff url(../images/skin/bg-dropdown.gif) repeat-y; + position: absolute; + width: 164px; + left: -999em; + z-index: 8000; + /* Fix by Chris */ + margin-top: -6px; +} + +#desktopNavbar li:hover ul ul, +#desktopNavbar li.ieHover ul ul, +#desktopNavbar li:hover ul ul ul, +#desktopNavbar li.ieHover ul ul ul { + left: -999em; +} + +#desktopNavbar li ul ul { /* third-and-above-level lists */ + margin: -22px 0 0 163px; +} + +#desktopNavbar li ul li .check { + position: absolute; + top: 8px; + left: 6px; + width: 5px; + height: 5px; + background: #555; + overflow: hidden; + line-height: 1px; + font-size: 1px; +} + +#desktopNavbar li ul li a { + position: relative; + /*padding: 1px 9px 1px 25px;*/ + width: 130px; + color: #3f3f3f; + font-weight: normal; + /* Fix By Chris */ + padding: 1px 9px 1px 20px; /* Reduce left padding */ +} + +#desktopNavbar li ul li a:hover { + background: #6C98D9; + color: #fff; + -moz-border-radius: 2px; +} + +#desktopNavbar li ul li a:hover .check { + background: #fff; +} + +#desktopNavbar li:hover ul, +#desktopNavbar li.ieHover ul, +#desktopNavbar li li.ieHover ul, +#desktopNavbar li li li.ieHover ul, +#desktopNavbar li li:hover ul, +#desktopNavbar li li li:hover ul { /* lists nested under hovered list items */ + left: auto; +} + +#desktopNavbar li:hover { /* For IE7 */ + position: static; +} + +li.divider { + margin-top: 2px; + padding-top: 3px; + border-top: 1px solid #ebebeb; +} + +#pageWrapper { + position: relative; + overflow: hidden; /* This can be set to hidden or auto */ + border-top: 1px solid #909090; + border-bottom: 1px solid #909090; + /*height: 100%;*/ +} + +/* Footer */ + +#desktopFooterWrapper { + position: absolute; + left: 0; + bottom: 0; + width: 100%; + height: 30px; + overflow: hidden; +} + +#desktopFooter { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; + height: 24px; + padding: 6px 8px 0 8px; + background: #f2f2f2; +} + + + +/* Panel Layout +---------------------------------------------------------------- */ + +/* Columns */ + +.column { + position: relative; + float: left; + overflow: hidden; /* Required by IE6 */ +} + +/* Panels */ + +.panel { + position: relative; + overflow: auto; + background: #f8f8f8; + border-bottom: 1px solid #b9b9b9; +} + +.panelWrapper.collapsed .panel-header { + border-bottom: 0; +} + +.panelAlt { + background: #f2f2f2; +} + +.bottomPanel { + border-bottom: 0; +} + +.pad { + padding: 8px; +} + +#mainPanel { + background: #fff; +} + +.panel-header { + position: relative; + background: #f1f1f1 url(../images/skin/bg-panel-header.gif) repeat-x; + height: 30px; + overflow: hidden; + border-bottom: 1px solid #d3d3d3; +} + +.panel-headerContent { + padding-top: 2px; +} + +.panel-headerContent.tabs { + background: url(../images/skin/tabs.gif) repeat-x; + background-position: left -68px; +} + +.panel-header h2 { + display: inline-block; + font-size: 12px; + margin: 0; + padding: 3px 8px 0 8px; + height: 22px; + overflow: hidden; + color: #333; +} + +.panel-collapse { + background: url(../images/skin/collapse-expand.gif) left top no-repeat; +} + +.panel-expand { + background: url(../images/skin/collapse-expand.gif) left -16px no-repeat; +} + +.icon16 { + margin: 4px 0 0 2px; + cursor: pointer; +} + +/* Column and Panel Handles */ + +.horizontalHandle { + height: 4px; + line-height: 1px; + font-size: 1px; + overflow: hidden; + background: #eee url(../images/skin/bg-handle-horizontal.gif) repeat-x; +} + +.horizontalHandle.detached .handleIcon { + background: transparent; +} + +.horizontalHandle .handleIcon { + margin: 0 auto; + height: 4px; + line-height: 1px; + font-size: 1px; + overflow: hidden; + background: url(../images/skin/handle-icon-horizontal.gif) center center no-repeat; +} + +.columnHandle { + min-height: 10px; + float: left; + width: 4px; + overflow: hidden; + background: #c3c3c3 url(../images/skin/handle-icon.gif) center center no-repeat; + border: 1px solid #909090; + border-top: 0; + border-bottom: 0; +} + +/* Toolboxes */ + +.toolbox { + float: right; + margin-top: 3px; + padding: 0 5px; + height: 24px; + overflow: hidden; + text-align: right; +} + +.panel-header-toolbox { +} + +div.toolbox.divider { /* Have to specify div here for IE6's sake */ + background: url(../images/skin/toolbox-divider.gif) repeat-y; + padding-left: 8px; +} + +.toolbox img.disabled { + cursor: default; +} + +.iconWrapper { + display: inline-block; + height: 22px; + min-width: 22px; + overflow: hidden; + border: 1px solid transparent; +} + +* html .iconWrapper { + padding: 1px; + border: 0; +} + +.iconWrapper img { + cursor: pointer; + margin: 0; + padding: 3px; +} + +.iconWrapper:hover { + border: 1px solid #a0a0a0; + -moz-border-radius: 3px; +} + +#spinnerWrapper { + width: 16px; + height: 16px; + background: url(../images/skin/spinner-placeholder.gif) no-repeat; + margin: 4px 5px 0 5px; +} + +#spinner { + display: none; + background: url(../images/skin/spinner.gif) no-repeat; + width: 16px; + height: 16px; +} + diff --git a/src/webui/css/Tabs.css b/src/webui/css/Tabs.css new file mode 100644 index 000000000..aa2985f19 --- /dev/null +++ b/src/webui/css/Tabs.css @@ -0,0 +1,66 @@ +/* + +Tabs.css for Mocha UI + +Theme: Default + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Required by: + Tabs.js + +*/ + +/* Toolbar Tabs */ + +.toolbarTabs { + padding: 0 5px 2px 2px; + background: url(../images/skin/tabs.gif) repeat-x; + background-position: left -70px; + overflow: visible; +} + +.tab-menu { + padding-top: 1px; + list-style: none; + margin: 0; + padding: 0; + line-height: 16px; + font-size: 11px; +} + +.tab-menu li { + display: block; + float: left; + margin: 0 0 5px 0; + cursor: pointer; + background: url(../images/skin/tabs.gif) repeat-x; + background-position: left -35px; +} + +.tab-menu li.selected { + background: url(../images/skin/tabs.gif) repeat-x; + background-position: left 0; +} + +.tab-menu li a { + display: block; + margin-left: 8px; + padding: 6px 15px 5px 9px; + text-align: center; + font-weight: normal; + color: #181818; + background: url(../images/skin/tabs.gif) repeat-x; + background-position: right -35px; +} + +.tab-menu li.selected a { + color: #181818; + font-weight: bold; + background: url(../images/skin/tabs.gif) repeat-x; + background-position: right 0; +} diff --git a/src/webui/css/Window.css b/src/webui/css/Window.css new file mode 100644 index 000000000..c362fdbfc --- /dev/null +++ b/src/webui/css/Window.css @@ -0,0 +1,371 @@ +/* + +Window.css for Mocha UI + +Theme: Default + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Required by: + Window.js and Modal.css + +*/ + +/* Windows +---------------------------------------------------------------- */ + +.mocha { + display: none; + overflow: hidden; + background-color: #e5e5e5; +} + +.mocha.isFocused { +} + +.mochaOverlay { + position: absolute; /* This is also set in theme.js in order to make theme transitions smoother */ + top: 0; + left: 0; +} + +/* + + We get a little creative here in order to define a gradient in the CSS using a query + string appended to a background image. + + "from" is the top color of the gradient. "to" is the bottom color of the gradient. + + Both must be hex values without the leading # sign. + +*/ + +.mochaTitlebar { + width: 100%; + overflow: hidden; + background: url(../images/spacer.gif?from=fafafa&to=e5e5e5); +} + +.mochaTitlebar h3 { + font-size: 12px; + line-height: 15px; + font-weight: bold; + margin: 0; + padding: 5px 10px 4px 12px; + color: #888; +} + +.mocha.isFocused .mochaTitlebar h3 { + color: #181818; +} + +.mochaToolbarWrapper { + width: 100%; /* For IE */ + position: relative; + height: 29px; + background: #f1f1f1; + overflow: hidden; + border-top: 1px solid #d9d9d9; +} + +div.mochaToolbarWrapper.bottom { + border: 0; + border-bottom: 1px solid #d9d9d9; +} + +.mochaToolbar { + width: 100%; /* For IE */ + border-top: 1px solid #fff; +} + +.mochaContentBorder { + border-top: 1px solid #dadada; + border-bottom: 1px solid #dadada; +} + +.mochaContentWrapper { /* Has a fixed height and scrollbars if required. */ + font-size: 12px; + overflow: auto; + background: #fff; +} + +.mochaContent { + padding: 10px 12px; +} + +.mocha .handle { + position: absolute; + background: #0f0; + width: 3px; + height: 3px; + z-index: 2; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; /* IE8 */ + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0); /* IE6 and 7*/ + opacity: .0; + -moz-opacity: .0; + overflow: hidden; + font-size: 1px; /* For IE6 */ +} + +.mocha .corner { /* Corner resize handles */ + width: 10px; + height: 10px; + background: #f00; +} + +.mocha .cornerSE { /* Bottom right resize handle */ + width: 20px; + height: 20px; + background: #fefefe; /* This is the color of the visible resize handle */ +} + +.mochaCanvasHeader { + position: absolute; + top: 0; + left: 0; + background: transparent; + z-index: -1; + visibility: hidden; + overflow: hidden; +} + +.mochaControls { + position: absolute; + width: 52px; + top: 8px; + right: 8px; + height: 14px; + z-index: 4; + background: transparent; +} + +.mochaCanvasControls { + position: absolute; + top: 8px; + right: 8px; + z-index: 3; + background: transparent; +} + +/* + To use images for these buttons: + 1. Set the useCanvasControls window option to false. + 2. If you use a different button size you may need to reposition the controls. + Modify the controlsOffset window option. + 2. Replcac the background-color with a background-image for each button. + +*/ +.mochaMinimizeButton, .mochaMaximizeButton, .mochaCloseButton { + float: right; + width: 14px; + height: 14px; + font-size: 1px; + cursor: pointer; + z-index: 4; + color: #666; + background-color: #fff; + margin-left: 5px; +} + +.mochaMinimizeButton { + margin-left: 0; +} + +.mochaMaximizeButton { +} + +.mochaCloseButton { +} + +.mochaSpinner{ + display: none; + position: absolute; + bottom: 7px; + left: 6px; + width: 16px; + height: 16px; + background: url(../images/spinner.gif) no-repeat; +} + +.mochaIframe { + width: 100%; +} + +/* Fix for IE6 select z-index issue */ +.zIndexFix { + display: block; + position: absolute; + top: 0; + left: 0; + z-index: -1; + filter: mask(); + width: 100px; + height: 100px; + border: 1px solid transparent; +} + +/* Viewport overlays +---------------------------------------------------------------- */ + +#modalOverlay { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + background: #000; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; /* IE8 */ + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0); /* IE6 and 7*/ + opacity: 0; + -moz-opacity: 0; + z-index: 10000; +} + +/* Fix for IE6 select z-index issue */ +#modalFix { + display: none; + position: absolute; + top: 0; + left: 0; + width: 100%; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; /* IE8 */ + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0); /* IE6 and 7*/ + opacity: 0; + -moz-opacity: 0; + z-index: 9999; +} + +/* Underlay */ + +#windowUnderlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + background: #fff; +} + +* html #windowUnderlay { + position: absolute; +} + +/* The replaced class is used internally when converting CSS values to Canvas. These classes should not be removed. */ + +.mocha.replaced, .mochaTitlebar.replaced, .mochaMinimizeButton.replaced, .mochaMaximizeButton.replaced, .mochaCloseButton.replaced { + background-color: transparent !important; +} + +.windowClosed { + visibility: hidden; + display: none; + position: absolute; + top: -20000px; + left: -20000px; + z-index: -1; + overflow: hidden; +} + +.windowClosed .mochaContentBorder, .windowClosed .mochaToolbarWrapper, .windowClosed .mochaTitlebar, .windowClosed .mochaControls, +.windowClosed .mochaCanvasControls { + position: absolute; + top: 0; + left: 0; + visibility: hidden; + display: none; + z-index: -1; +} + +/* Modals */ + +.modal2 { + border: 8px solid #fff; +} + +.modal2 .mochaContentBorder { + border-width: 0px; +} + +/* Window Themes */ + +.mocha.no-canvas { + background: #e5e5e5; + border: 1px solid #555; +} + +.mocha.no-canvas .mochaTitlebar { + background: #e5e5e5; +} + +.mocha.transparent .mochaTitlebar h3 { + color: #fff; + display: none; +} + +.mocha.transparent .mochaContentWrapper { + background: transparent; +} + +.mocha.notification { + background: #cedff2; +} + +.mocha.notification .mochaTitlebar { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; /* IE8 */ + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0); /* IE6 and 7*/ + opacity: .0; + -moz-opacity: 0; +} + +.mocha.notification .mochaContentBorder { + border-width: 0px; +} + +.mocha.notification .mochaContentWrapper { + text-align: center; + font-size: 12px; + font-weight: bold; + background: transparent; +} + +/* Example Window Themes */ + +#about_contentWrapper { + background: #e5e5e5 url(../images/logo2.gif) 3px 3px no-repeat; +} + +#builder_contentWrapper { + background: #f5f5f7; +} + +#json01 .mochaTitlebar { + background: #6dd2db; +} + +#json02 .mochaTitlebar { + background: #6db6db; +} + +#json03 .mochaTitlebar { + background: #6d92db; +} + +.jsonExample .mochaTitlebar h3 { + color: #ddd; +} + +/* This does not work in IE6. */ +.isFocused.jsonExample .mochaTitlebar h3 { + color: #fff; +} + +#fxmorpherExample .mochaContentWrapper { + background: #577a9e; +} + +#clock { + background: #fff; +} diff --git a/src/webui/css/dynamicTable.css b/src/webui/css/dynamicTable.css new file mode 100644 index 000000000..0a9583f23 --- /dev/null +++ b/src/webui/css/dynamicTable.css @@ -0,0 +1,62 @@ + + +/************************************************************** + + Dynamic Table + v 0.4 + +**************************************************************/ + +#properties #torrentFiles table, +#properties #trackers table, +#transferList table { + border: 1px solid #ccc; + width: 100%; +} + +#properties #torrentFiles th, +#properties #trackers th, +#transferList th { + background-color: #eee; + padding: 4px; +} + +#properties #torrentFiles tr, +#properties #trackers tr, +#transferList tr { + background-color: #fff; + padding: 4px; +} + + +#properties #torrentFiles tr.alt, +#properties #trackers tr.alt, +#transferList tr.alt { + background-color: #eee; + padding: 4px; +} + +#properties #torrentFiles td, +#properties #trackers td, +#transferList td { + padding: 0 2px; +} + +#properties #torrentFiles tr.selected, +#properties #trackers tr.selected, +#transferList tr.selected { + background-color: #354158; + color: #fff; +} + +#properties #torrentFiles tr.over, +#properties #trackers tr.over, +#transferList tr.over { + background-color: #ee6600; + color: #fff; + cursor: pointer; +} + +#transferList img.statusIcon { + margin-bottom: -4px; +} diff --git a/src/webui/css/style.css b/src/webui/css/style.css new file mode 100644 index 000000000..416d8b11d --- /dev/null +++ b/src/webui/css/style.css @@ -0,0 +1,292 @@ +/* Reset */ + +ul,ol,dl,li,dt,dd,h1,h2,h3,h4,h5,h6,pre,form,body,html,p,blockquote,fieldset,input,object,iframe { margin: 0; padding: 0; } +a img,:link img,:visited img { border: none; } +table { border-collapse: collapse; border-spacing: 0; } +:focus { outline: none; } + +/* Structure */ + +body { + margin: 0; + text-align: left; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + line-height: 18px; + color: #555; +} + +.aside { + width: 300px; +} + +.invisible { + display: none; +} + +/* Typography */ + +h2, h3, h4 { + margin: 0; + padding: 0 0 5px 0; + font-size: 12px; + font-weight: bold; + color: #333; +} + +h2 { + font-size: 14px; + color: #555; + font-weight: bold; +} + +#mochaPage h3 { + display: block; + font-size: 12px; + padding: 6px 0 6px 0; + margin: 0 0 8px 0; + border-bottom: 1px solid #bbb; +} + +#error_div { + color: #f00; + font-weight: bold; +} + +h4 { + font-size: 11px; +} + +a { + color: #e60; + text-decoration: none; + cursor: pointer; +} + +a:hover { + text-decoration: none; +} + +p { + margin: 0; + padding: 0 0 9px 0; +} + +/* List Elements */ + +ul { + list-style: outside; + margin: 0 0 9px 16px; +} + +dt { + font-weight: bold; + } + +dd { + padding: 0 0 9px 0; +} + +/* Code */ + +pre { + background-color: #f6f6f6; + color: #006600; + display: block; + font-family: 'Courier New', Courier, monospace; + font-size: 11px; + max-height: 250px; + overflow: auto; + margin: 0 0 10px 0; + padding: 10px; + border: 1px solid #d1d7dc; + } + +/* Dividers */ + +hr { + background-color: #ddd; + color: #ccc; + height: 1px; + border: 0px; +} + +.vcenter { + vertical-align: middle; +} + +#urls { + width:90%; + height:100%; +} + +#trackersUrls { + width:90%; + height:100%; +} + +#Filters ul { + list-style-type: none; +} + +#Filters ul li { + margin-left: -16px; +} + +#Filters ul img { + padding-left: 4px; + padding-right: 2px; + margin-bottom: -4px; +} + +.selectedFilter { + background-color: #354158; + color: #000; +} + +#properties { + background-color: #e5e5e5; +} + +a.propButton { + border: 1px solid rgb(85, 81, 91); + /*border-radius: 3px;*/ + padding: 2px; + margin-left: 3px; + margin-right: 3px; +} + +a.propButton img { + margin-bottom: -4px; +} + +/* context menu specific */ +#contextmenu { border:1px solid #999; padding:0; background:#eee; list-style-type:none; display:none; width: 164px;} +#contextmenu .separator { border-top:1px solid #999; } +#contextmenu li { margin:0; padding:0;} +#contextmenu li a { display:block; padding:5px 10px 5px 5px; font-size:12px; text-decoration:none; font-family:tahoma,arial,sans-serif; color:#000; } +#contextmenu li a:hover { background-color:#ddd; } +#contextmenu li a.disabled { color:#ccc; font-style:italic; } +#contextmenu li a.disabled:hover { background-color:#eee; } +#contextmenu li ul { + padding: 0; + border:1px solid #999; padding:0; background:#eee; + list-style-type:none; + position: absolute; + left: -999em; + z-index: 8000; + margin: -29px 0 0 164px; + width: 164px; +} +#contextmenu li ul li a { + position: relative; +} +#contextmenu li a.arrow-right, #contextmenu li a:hover.arrow-right { + background-image: url(../images/skin/arrow-right.gif); + background-repeat: no-repeat; + background-position: right center; +} +#contextmenu li:hover ul, +#contextmenu li.ieHover ul, +#contextmenu li li.ieHover ul, +#contextmenu li li li.ieHover ul, +#contextmenu li li:hover ul, +#contextmenu li li li:hover ul { /* lists nested under hovered list items */ + left: auto; +} + +#contextmenu li img { + width: 16px; + height: 16px; + margin-bottom: -4px; + -ms-interpolation-mode : bicubic; +} + +/* Sliders */ + +.slider { + clear: both; + position: relative; + font-size: 12px; + font-weight: bold; + width: 400px; + margin-bottom: 15px; +} + +.sliderWrapper { + position: relative; + font-size: 1px; + line-height: 1px; + height: 9px; + width: 422px; +} + +.sliderarea { + position: absolute; + top: 0; + left: 0; + height: 7px; + width: 420px; + font-size: 1px; + line-height: 1px; + background: #f2f2f2 url(../images/skin/slider-area.gif) repeat-x; + border: 1px solid #a3a3a3; + border-bottom: 1px solid #ccc; + border-left: 1px solid #ccc; + margin: 0; + padding: 0; + overflow: hidden; +} + +.sliderknob { + position: absolute; + top: 0; + left: 0; + height: 9px; + width: 19px; + font-size: 1px; + line-height: 1px; + background: url(../images/skin/knob.gif) no-repeat; + cursor: pointer; + overflow: hidden; + z-index: 2; +} + +.update { + padding-bottom: 5px; +} + +.mochaToolButton { + margin-right: 10px; +} + +/* Mocha Customization */ +#mochaToolbar .divider { + background-image: url(../images/skin/toolbox-divider.gif); + background-repeat: no-repeat; + background-position: left center; + padding-left: 14px; + padding-top: 15px; +} + +.MyMenuIcon { + margin-left: -16px; + margin-bottom: -3px; + padding-right: 3px; +} + +/* Tri-state checkbox */ +a.tristate { + background: url(../images/3-state-checkbox.gif) 0 0 no-repeat; + display: block; + float: left; + height: 13px; + margin: .15em 8px 5px 0px; + overflow: hidden; + text-indent: -999em; + width: 13px; +} +a.checked { background-position: 0 -13px; } +a.partial { background-position: 0 -26px; } + + diff --git a/src/webui/eventmanager.cpp b/src/webui/eventmanager.cpp new file mode 100644 index 000000000..357521019 --- /dev/null +++ b/src/webui/eventmanager.cpp @@ -0,0 +1,525 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Ishan Arora and Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + + +#include +#include "eventmanager.h" +#include "qbtsession.h" +#include "scannedfoldersmodel.h" +#include "misc.h" +#include "preferences.h" +//#include "proplistdelegate.h" +#include "torrentpersistentdata.h" +#include +#include +#ifndef QT_NO_OPENSSL +#include +#include +#endif + +using namespace libtorrent; + +EventManager::EventManager(QObject *parent) + : QObject(parent) +{ +} + +QList EventManager::getEventList() const { + return event_list.values(); +} + +QList EventManager::getPropTrackersInfo(QString hash) const { + QList trackersInfo; + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(h.is_valid()) { + QHash trackers_data = QBtSession::instance()->getTrackersInfo(hash); + std::vector vect_trackers = h.trackers(); + std::vector::iterator it; + for(it = vect_trackers.begin(); it != vect_trackers.end(); it++) { + QVariantMap tracker; + QString tracker_url = misc::toQString(it->url); + tracker["url"] = tracker_url; + TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); + QString error_message = data.last_message.trimmed(); +#if LIBTORRENT_VERSION_MINOR > 14 + if(it->verified) { + tracker["status"] = tr("Working"); + } else { + if(it->updating && it->fails == 0) { + tracker["status"] = tr("Updating..."); + } else { + if(it->fails > 0) { + tracker["status"] = tr("Not working"); + } else { + tracker["status"] = tr("Not contacted yet"); + } + } + } +#else + if(data.verified) { + tracker["status"] = tr("Working"); + } else { + if(data.fail_count > 0) + tracker["status"] = tr("Not working"); + else + tracker["status"] = tr("Not contacted yet"); + } +#endif + tracker["num_peers"] = QString::number(trackers_data.value(tracker_url, TrackerInfos(tracker_url)).num_peers); + tracker["msg"] = error_message; + trackersInfo << tracker; + } + } + return trackersInfo; +} + +QList EventManager::getPropFilesInfo(QString hash) const { + QList files; + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(!h.is_valid() || !h.has_metadata()) return files; + std::vector priorities = h.file_priorities(); + std::vector fp; + h.file_progress(fp); + for(int i=0; i 0) + file["progress"] = fp[i]/(double)size; + else + file["progress"] = 1.; // Empty file... + file["priority"] = priorities[i]; + if(i == 0) + file["is_seed"] = h.is_seed(); + files << file; + } + return files; +} + +void EventManager::setGlobalPreferences(QVariantMap m) const { + // UI + Preferences pref; + if(m.contains("locale")) { + QString locale = m["locale"].toString(); + if(pref.getLocale() != locale) { + QTranslator *translator = new QTranslator; + if(translator->load(QString::fromUtf8(":/lang/qbittorrent_") + locale)){ + qDebug("%s locale recognized, using translation.", qPrintable(locale)); + }else{ + qDebug("%s locale unrecognized, using default (en_GB).", qPrintable(locale)); + } + qApp->installTranslator(translator); + } + + pref.setLocale(locale); + } + // Downloads + if(m.contains("save_path")) + pref.setSavePath(m["save_path"].toString()); + if(m.contains("temp_path_enabled")) + pref.setTempPathEnabled(m["temp_path_enabled"].toBool()); + if(m.contains("temp_path")) + pref.setTempPath(m["temp_path"].toString()); + if(m.contains("scan_dirs") && m.contains("download_in_scan_dirs")) { + QVariantList download_at_path_tmp = m["download_in_scan_dirs"].toList(); + QList download_at_path; + foreach(QVariant var, download_at_path_tmp) { + download_at_path << var.toBool(); + } + QStringList old_folders = pref.getScanDirs(); + QStringList new_folders = m["scan_dirs"].toStringList(); + if(download_at_path.size() == new_folders.size()) { + pref.setScanDirs(new_folders); + pref.setDownloadInScanDirs(download_at_path); + foreach(const QString &old_folder, old_folders) { + // Update deleted folders + if(!new_folders.contains(old_folder)) { + QBtSession::instance()->getScanFoldersModel()->removePath(old_folder); + } + } + int i = 0; + foreach(const QString &new_folder, new_folders) { + qDebug("New watched folder: %s", qPrintable(new_folder)); + // Update new folders + if(!old_folders.contains(new_folder)) { + QBtSession::instance()->getScanFoldersModel()->addPath(new_folder, download_at_path.at(i)); + } + ++i; + } + } + } + if(m.contains("export_dir")) + pref.setExportDir(m["export_dir"].toString()); + if(m.contains("mail_notification_enabled")) + pref.setMailNotificationEnabled(m["mail_notification_enabled"].toBool()); + if(m.contains("mail_notification_email")) + pref.setMailNotificationEmail(m["mail_notification_email"].toString()); + if(m.contains("mail_notification_smtp")) + pref.setMailNotificationSMTP(m["mail_notification_smtp"].toString()); + if(m.contains("mail_notification_ssl_enabled")) + pref.setMailNotificationSMTPSSL(m["mail_notification_ssl_enabled"].toBool()); + if(m.contains("mail_notification_auth_enabled")) + pref.setMailNotificationSMTPAuth(m["mail_notification_auth_enabled"].toBool()); + if(m.contains("mail_notification_username")) + pref.setMailNotificationSMTPUsername(m["mail_notification_username"].toString()); + if(m.contains("mail_notification_password")) + pref.setMailNotificationSMTPPassword(m["mail_notification_password"].toString()); + if(m.contains("autorun_enabled")) + pref.setAutoRunEnabled(m["autorun_enabled"].toBool()); + if(m.contains("autorun_program")) + pref.setAutoRunProgram(m["autorun_program"].toString()); + if(m.contains("preallocate_all")) + pref.preAllocateAllFiles(m["preallocate_all"].toBool()); + if(m.contains("queueing_enabled")) + pref.setQueueingSystemEnabled(m["queueing_enabled"].toBool()); + if(m.contains("max_active_downloads")) + pref.setMaxActiveDownloads(m["max_active_downloads"].toInt()); + if(m.contains("max_active_torrents")) + pref.setMaxActiveTorrents(m["max_active_torrents"].toInt()); + if(m.contains("max_active_uploads")) + pref.setMaxActiveUploads(m["max_active_uploads"].toInt()); +#if LIBTORRENT_VERSION_MINOR > 14 + if(m.contains("incomplete_files_ext")) + pref.useIncompleteFilesExtension(m["incomplete_files_ext"].toBool()); +#endif + // Connection + if(m.contains("listen_port")) + pref.setSessionPort(m["listen_port"].toInt()); + if(m.contains("upnp")) + pref.setUPnPEnabled(m["upnp"].toBool()); + if(m.contains("dl_limit")) + pref.setGlobalDownloadLimit(m["dl_limit"].toInt()); + if(m.contains("up_limit")) + pref.setGlobalUploadLimit(m["up_limit"].toInt()); + if(m.contains("max_connec")) + pref.setMaxConnecs(m["max_connec"].toInt()); + if(m.contains("max_connec_per_torrent")) + pref.setMaxConnecsPerTorrent(m["max_connec_per_torrent"].toInt()); + if(m.contains("max_uploads_per_torrent")) + pref.setMaxUploadsPerTorrent(m["max_uploads_per_torrent"].toInt()); +#if LIBTORRENT_VERSION_MINOR >= 16 + if(m.contains("enable_utp")) + pref.setuTPEnabled(m["enable_utp"].toBool()); + if(m.contains("limit_utp_rate")) + pref.setuTPRateLimited(m["limit_utp_rate"].toBool()); +#endif + if(m.contains("limit_tcp_overhead")) + pref.includeOverheadInLimits(m["limit_tcp_overhead"].toBool()); + // Bittorrent + if(m.contains("dht")) + pref.setDHTEnabled(m["dht"].toBool()); + if(m.contains("dhtSameAsBT")) + pref.setDHTPortSameAsBT(m["dhtSameAsBT"].toBool()); + if(m.contains("dht_port")) + pref.setDHTPort(m["dht_port"].toInt()); + if(m.contains("pex")) + pref.setPeXEnabled(m["pex"].toBool()); + qDebug("Pex support: %d", (int)m["pex"].toBool()); + if(m.contains("lsd")) + pref.setLSDEnabled(m["lsd"].toBool()); + if(m.contains("encryption")) + pref.setEncryptionSetting(m["encryption"].toInt()); + // Proxy + if(m.contains("proxy_type")) + pref.setProxyType(m["proxy_type"].toInt()); + if(m.contains("proxy_ip")) + pref.setProxyIp(m["proxy_ip"].toString()); + if(m.contains("proxy_port")) + pref.setProxyPort(m["proxy_port"].toUInt()); + if(m.contains("proxy_peer_connections")) + pref.setProxyPeerConnections(m["proxy_peer_connections"].toBool()); + if(m.contains("proxy_auth_enabled")) + pref.setProxyAuthEnabled(m["proxy_auth_enabled"].toBool()); + if(m.contains("proxy_username")) + pref.setProxyUsername(m["proxy_username"].toString()); + if(m.contains("proxy_password")) + pref.setProxyPassword(m["proxy_password"].toString()); + // IP Filter + if(m.contains("ip_filter_enabled")) + pref.setFilteringEnabled(m["ip_filter_enabled"].toBool()); + if(m.contains("ip_filter_path")) + pref.setFilter(m["ip_filter_path"].toString()); + // Web UI + if(m.contains("web_ui_port")) + pref.setWebUiPort(m["web_ui_port"].toUInt()); + if(m.contains("web_ui_username")) + pref.setWebUiUsername(m["web_ui_username"].toString()); + if(m.contains("web_ui_password")) + pref.setWebUiPassword(m["web_ui_password"].toString()); + if(m.contains("bypass_local_auth")) + pref.setWebUiLocalAuthEnabled(!m["bypass_local_auth"].toBool()); + if(m.contains("use_https")) + pref.setWebUiHttpsEnabled(m["use_https"].toBool()); +#ifndef QT_NO_OPENSSL + if(m.contains("ssl_key")) { + QByteArray raw_key = m["ssl_key"].toString().toAscii(); + if (!QSslKey(raw_key, QSsl::Rsa).isNull()) + pref.setWebUiHttpsKey(raw_key); + } + if(m.contains("ssl_cert")) { + QByteArray raw_cert = m["ssl_cert"].toString().toAscii(); + if (!QSslCertificate(raw_cert).isNull()) + pref.setWebUiHttpsCertificate(raw_cert); + } +#endif + // Dyndns + if(m.contains("dyndns_enabled")) + pref.setDynDNSEnabled(m["dyndns_enabled"].toBool()); + if(m.contains("dyndns_service")) + pref.setDynDNSService(m["dyndns_service"].toInt()); + if(m.contains("dyndns_username")) + pref.setDynDNSUsername(m["dyndns_username"].toString()); + if(m.contains("dyndns_password")) + pref.setDynDNSPassword(m["dyndns_password"].toString()); + if(m.contains("dyndns_domain")) + pref.setDynDomainName(m["dyndns_domain"].toString()); + // Reload preferences + QBtSession::instance()->configureSession(); +} + +QVariantMap EventManager::getGlobalPreferences() const { + const Preferences pref; + QVariantMap data; + // UI + data["locale"] = pref.getLocale(); + // Downloads + data["save_path"] = pref.getSavePath(); + data["temp_path_enabled"] = pref.isTempPathEnabled(); + data["temp_path"] = pref.getTempPath(); + data["scan_dirs"] = pref.getScanDirs(); + QVariantList var_list; + foreach(bool b, pref.getDownloadInScanDirs()) { + var_list << b; + } + data["download_in_scan_dirs"] = var_list; + data["export_dir_enabled"] = pref.isTorrentExportEnabled(); + data["export_dir"] = pref.getExportDir(); + data["mail_notification_enabled"] = pref.isMailNotificationEnabled(); + data["mail_notification_email"] = pref.getMailNotificationEmail(); + data["mail_notification_smtp"] = pref.getMailNotificationSMTP(); + data["mail_notification_ssl_enabled"] = pref.getMailNotificationSMTPSSL(); + data["mail_notification_auth_enabled"] = pref.getMailNotificationSMTPAuth(); + data["mail_notification_username"] = pref.getMailNotificationSMTPUsername(); + data["mail_notification_password"] = pref.getMailNotificationSMTPPassword(); + data["autorun_enabled"] = pref.isAutoRunEnabled(); + data["autorun_program"] = pref.getAutoRunProgram(); + data["preallocate_all"] = pref.preAllocateAllFiles(); + data["queueing_enabled"] = pref.isQueueingSystemEnabled(); + data["max_active_downloads"] = pref.getMaxActiveDownloads(); + data["max_active_torrents"] = pref.getMaxActiveTorrents(); + data["max_active_uploads"] = pref.getMaxActiveUploads(); +#if LIBTORRENT_VERSION_MINOR > 14 + data["incomplete_files_ext"] = pref.useIncompleteFilesExtension(); +#endif + // Connection + data["listen_port"] = pref.getSessionPort(); + data["upnp"] = pref.isUPnPEnabled(); + data["dl_limit"] = pref.getGlobalDownloadLimit(); + data["up_limit"] = pref.getGlobalUploadLimit(); + data["max_connec"] = pref.getMaxConnecs(); + data["max_connec_per_torrent"] = pref.getMaxConnecsPerTorrent(); + data["max_uploads_per_torrent"] = pref.getMaxUploadsPerTorrent(); +#if LIBTORRENT_VERSION_MINOR >= 16 + data["enable_utp"] = pref.isuTPEnabled(); + data["limit_utp_rate"] = pref.isuTPRateLimited(); +#endif + data["limit_tcp_overhead"] = pref.includeOverheadInLimits(); + // Bittorrent + data["dht"] = pref.isDHTEnabled(); + data["dhtSameAsBT"] = pref.isDHTPortSameAsBT(); + data["dht_port"] = pref.getDHTPort(); + data["pex"] = pref.isPeXEnabled(); + data["lsd"] = pref.isLSDEnabled(); + data["encryption"] = pref.getEncryptionSetting(); + // Proxy + data["proxy_type"] = pref.getProxyType(); + data["proxy_ip"] = pref.getProxyIp(); + data["proxy_port"] = pref.getProxyPort(); + data["proxy_peer_connections"] = pref.proxyPeerConnections(); + data["proxy_auth_enabled"] = pref.isProxyAuthEnabled(); + data["proxy_username"] = pref.getProxyUsername(); + data["proxy_password"] = pref.getProxyPassword(); + // IP Filter + data["ip_filter_enabled"] = pref.isFilteringEnabled(); + data["ip_filter_path"] = pref.getFilter(); + // Web UI + data["web_ui_port"] = pref.getWebUiPort(); + data["web_ui_username"] = pref.getWebUiUsername(); + data["web_ui_password"] = pref.getWebUiPassword(); + data["bypass_local_auth"] = !pref.isWebUiLocalAuthEnabled(); + data["use_https"] = pref.isWebUiHttpsEnabled(); + data["ssl_key"] = QString::fromAscii(pref.getWebUiHttpsKey()); + data["ssl_cert"] = QString::fromAscii(pref.getWebUiHttpsCertificate()); + // DynDns + data["dyndns_enabled"] = pref.isDynDNSEnabled(); + data["dyndns_service"] = pref.getDynDNSService(); + data["dyndns_username"] = pref.getDynDNSUsername(); + data["dyndns_password"] = pref.getDynDNSPassword(); + data["dyndns_domain"] = pref.getDynDomainName(); + return data; +} + +QVariantMap EventManager::getPropGeneralInfo(QString hash) const { + QVariantMap data; + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(h.is_valid() && h.has_metadata()) { + // Save path + QString p = TorrentPersistentData::getSavePath(hash); + if(p.isEmpty()) p = h.save_path(); + data["save_path"] = p; + // Creation date + data["creation_date"] = h.creation_date(); + // Piece size + data["piece_size"] = misc::friendlyUnit(h.piece_length()); + // Comment + data["comment"] = h.comment(); + data["total_wasted"] = QVariant(misc::friendlyUnit(h.total_failed_bytes()+h.total_redundant_bytes())); + data["total_uploaded"] = QVariant(misc::friendlyUnit(h.all_time_upload()) + " ("+misc::friendlyUnit(h.total_payload_upload())+" "+tr("this session")+")"); + data["total_downloaded"] = QVariant(misc::friendlyUnit(h.all_time_download()) + " ("+misc::friendlyUnit(h.total_payload_download())+" "+tr("this session")+")"); + if(h.upload_limit() <= 0) + data["up_limit"] = QString::fromUtf8("∞"); + else + data["up_limit"] = QVariant(misc::friendlyUnit(h.upload_limit())+tr("/s", "/second (i.e. per second)")); + if(h.download_limit() <= 0) + data["dl_limit"] = QString::fromUtf8("∞"); + else + data["dl_limit"] = QVariant(misc::friendlyUnit(h.download_limit())+tr("/s", "/second (i.e. per second)")); + QString elapsed_txt = misc::userFriendlyDuration(h.active_time()); + if(h.is_seed()) { + elapsed_txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(h.seeding_time()))+")"; + } + data["time_elapsed"] = elapsed_txt; + data["nb_connections"] = QVariant(QString::number(h.num_connections())+" ("+tr("%1 max", "e.g. 10 max").arg(QString::number(h.connections_limit()))+")"); + // Update ratio info + qreal ratio = QBtSession::instance()->getRealRatio(h.hash()); + if(ratio > 100.) + data["share_ratio"] = QString::fromUtf8("∞"); + else + data["share_ratio"] = QString(QByteArray::number(ratio, 'f', 1)); + } + return data; +} + +void EventManager::addedTorrent(const QTorrentHandle& h) +{ + modifiedTorrent(h); +} + +void EventManager::deletedTorrent(QString hash) +{ + event_list.remove(hash); +} + +void EventManager::modifiedTorrent(const QTorrentHandle& h) +{ + QString hash = h.hash(); + QVariantMap event; + event["eta"] = QVariant(QString::fromUtf8("∞")); + if(h.is_paused()) { + if(h.has_error()) { + event["state"] = QVariant("error"); + } else { + if(h.is_seed()) + event["state"] = QVariant("pausedUP"); + else + event["state"] = QVariant("pausedDL"); + } + } else { + if(QBtSession::instance()->isQueueingEnabled() && h.is_queued()) { + if(h.is_seed()) + event["state"] = QVariant("queuedUP"); + else + event["state"] = QVariant("queuedDL"); + } else { + switch(h.state()) + { + case torrent_status::finished: + case torrent_status::seeding: + if(h.upload_payload_rate() > 0) { + event["state"] = QVariant("uploading"); + } else { + event["state"] = QVariant("stalledUP"); + } + break; + case torrent_status::allocating: + case torrent_status::checking_files: + case torrent_status::queued_for_checking: + case torrent_status::checking_resume_data: + if(h.is_seed()) { + event["state"] = QVariant("checkingUP"); + } else { + event["state"] = QVariant("checkingDL"); + } + break; + case torrent_status::downloading: + case torrent_status::downloading_metadata: + if(h.download_payload_rate() > 0) + event["state"] = QVariant("downloading"); + else + event["state"] = QVariant("stalledDL"); + event["eta"] = misc::userFriendlyDuration(QBtSession::instance()->getETA(hash)); + break; + default: + qDebug("No status, should not happen!!! status is %d", h.state()); + event["state"] = QVariant(); + } + } + } + event["name"] = QVariant(h.name()); + event["size"] = QVariant(misc::friendlyUnit(h.actual_size())); + event["progress"] = QVariant((double)h.progress()); + event["dlspeed"] = QVariant(tr("%1/s", "e.g. 120 KiB/s").arg(misc::friendlyUnit(h.download_payload_rate()))); + if(QBtSession::instance()->isQueueingEnabled()) { + if(h.queue_position() >= 0) + event["priority"] = QVariant(QString::number(h.queue_position())); + else + event["priority"] = "*"; + } else { + event["priority"] = "*"; + } + event["upspeed"] = QVariant(tr("%1/s", "e.g. 120 KiB/s").arg(misc::friendlyUnit(h.upload_payload_rate()))); + QString seeds = QString::number(h.num_seeds()); + if(h.num_complete() > 0) + seeds += " ("+QString::number(h.num_complete())+")"; + event["num_seeds"] = QVariant(seeds); + QString leechs = QString::number(h.num_peers()-h.num_seeds()); + if(h.num_incomplete() > 0) + leechs += " ("+QString::number(h.num_incomplete())+")"; + event["num_leechs"] = QVariant(leechs); + event["seed"] = QVariant(h.is_seed()); + qreal ratio = QBtSession::instance()->getRealRatio(hash); + if(ratio > 100.) + event["ratio"] = QString::fromUtf8("∞"); + else + event["ratio"] = QVariant(QString::number(ratio, 'f', 1)); + event["hash"] = QVariant(hash); + event_list[hash] = event; +} diff --git a/src/webui/eventmanager.h b/src/webui/eventmanager.h new file mode 100644 index 000000000..01104c1df --- /dev/null +++ b/src/webui/eventmanager.h @@ -0,0 +1,65 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Ishan Arora and Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + + +#ifndef EVENTMANAGER_H +#define EVENTMANAGER_H + +#include "qtorrenthandle.h" +#include +#include + +class EventManager : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(EventManager) + +private: + QHash event_list; + +protected: + void update(QVariantMap event); + +public: + EventManager(QObject *parent); + QList getEventList() const; + QVariantMap getPropGeneralInfo(QString hash) const; + QList getPropTrackersInfo(QString hash) const; + QList getPropFilesInfo(QString hash) const; + QVariantMap getGlobalPreferences() const; + void setGlobalPreferences(QVariantMap m) const; + +public slots: + void addedTorrent(const QTorrentHandle& h); + void deletedTorrent(QString hash); + void modifiedTorrent(const QTorrentHandle& h); +}; + +#endif diff --git a/src/webui/html/about.html b/src/webui/html/about.html new file mode 100644 index 000000000..cd8f9d31a --- /dev/null +++ b/src/webui/html/about.html @@ -0,0 +1,380 @@ + + + + qBittorrent web User Interface + + + + + + + +

About

+ +

qBittorrent Web UI

+

Copyright (c) 2010 by Christophe Dumez

+

Homepage : http://www.qbittorrent.com

+ +

Initial authors

+ +Name : Ishan Arora
+Email : ishanarora@gmail.com
+
+Name : Ankit Gupta
+Email : ank.iitd@gmail.com
+
+Name : Chandan Shikhar Dua
+Email : shikhar.ap@gmail.com
+
+Name : Swapnil Kumar
+Email : swapnil.iitd@gmail.com
+ +

License

+
+
+GNU GENERAL PUBLIC LICENSE
+
+Version 2, June 1991
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+
+Preamble
+The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+GNU GENERAL PUBLIC LICENSE
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The 'Program', below,
+refers to any such program or work, and a 'work based on the Program'
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term 'modification'.) Each licensee is addressed as 'you'.
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+a) You must cause the modified files to carry prominent notices
+stating that you changed the files and the date of any change.
+
+b) You must cause any work that you distribute or publish, that in
+whole or in part contains or is derived from the Program or any
+part thereof, to be licensed as a whole at no charge to all third
+parties under the terms of this License.
+
+c) If the modified program normally reads commands interactively
+when run, you must cause it, when started running for such
+interactive use in the most ordinary way, to print or display an
+announcement including an appropriate copyright notice and a
+notice that there is no warranty (or else, saying that you provide
+a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this
+License. (Exception: if the Program itself is interactive but
+does not normally print such an announcement, your work based on
+the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+a) Accompany it with the complete corresponding machine-readable
+source code, which must be distributed under the terms of Sections
+1 and 2 above on a medium customarily used for software interchange; or,
+
+b) Accompany it with a written offer, valid for at least three
+years, to give any third party, for a charge no more than your
+cost of physically performing source distribution, a complete
+machine-readable copy of the corresponding source code, to be
+distributed under the terms of Sections 1 and 2 above on a medium
+customarily used for software interchange; or,
+
+c) Accompany it with the information you received as to the offer
+to distribute corresponding source code. (This alternative is
+allowed only for noncommercial distribution and only if you
+received the program in object code or executable form with such
+an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and 'any
+later version', you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+
+NO WARRANTY
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the 'copyright' line and a pointer to where the full notice is found.
+
+
+Copyright (C) 
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+Gnomovision version 69, Copyright (C) year name of author
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a 'copyright disclaimer' for the program, if
+necessary. Here is a sample; alter the names:
+
+Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+`Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+'signature of Ty Coon', 1 April 1989
+Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+
+
+ + diff --git a/src/webui/html/addtrackers.html b/src/webui/html/addtrackers.html new file mode 100644 index 000000000..64a5264b0 --- /dev/null +++ b/src/webui/html/addtrackers.html @@ -0,0 +1,32 @@ + + + + + _(Trackers addition dialog) + + + + + + +
+

_(List of trackers to add (one per line):)


+ +
+ _(Add) +
+ + diff --git a/src/webui/html/confirmdeletion.html b/src/webui/html/confirmdeletion.html new file mode 100644 index 000000000..15af4e30b --- /dev/null +++ b/src/webui/html/confirmdeletion.html @@ -0,0 +1,73 @@ + + + + + _(Deletion confirmation - qBittorrent) + + + + + + + + +
+ +

_(Are you sure you want to delete the selected torrents from the transfer list?)

+      _(Also delete the files on the hard disk)

+
+      +
+ + diff --git a/src/webui/html/download.html b/src/webui/html/download.html new file mode 100644 index 000000000..7132acec6 --- /dev/null +++ b/src/webui/html/download.html @@ -0,0 +1,17 @@ + + + + + _(Add &link to torrent...) + + + + + +
+
+

_(Download Torrents from their URL or Magnet link)

+

_(Only one link per line)

_(Download) +
+ + diff --git a/src/webui/html/downloadlimit.html b/src/webui/html/downloadlimit.html new file mode 100644 index 000000000..011206018 --- /dev/null +++ b/src/webui/html/downloadlimit.html @@ -0,0 +1,54 @@ + + + + + _(Torrent Download Speed Limiting) + + + + + + + + +
+
+
_(Download limit:) 0 _(KiB/s)
+
+
+
+
+
+
+ + +
+ + + + + \ No newline at end of file diff --git a/src/webui/html/filters.html b/src/webui/html/filters.html new file mode 100644 index 000000000..1461d989d --- /dev/null +++ b/src/webui/html/filters.html @@ -0,0 +1,17 @@ + + + diff --git a/src/webui/html/index.html b/src/webui/html/index.html new file mode 100644 index 000000000..9864ff84d --- /dev/null +++ b/src/webui/html/index.html @@ -0,0 +1,112 @@ + + + + + + + qBittorrent web User Interface + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+ + + + diff --git a/src/webui/html/preferences.html b/src/webui/html/preferences.html new file mode 100644 index 000000000..581fda5d3 --- /dev/null +++ b/src/webui/html/preferences.html @@ -0,0 +1,56 @@ + + + + + _(Download from URL) + + + + + + + + + + + + + diff --git a/src/webui/html/preferences_content.html b/src/webui/html/preferences_content.html new file mode 100644 index 000000000..e279ac74f --- /dev/null +++ b/src/webui/html/preferences_content.html @@ -0,0 +1,1012 @@ +
+
+ _(Listening Port) +
+ _(Port used for incoming connections:) + +
+ + + + +
_(Use UPnP / NAT-PMP port forwarding from my router)
+
+
+
+ _(Connections Limits) +
+ + + + + + + + + + +
_(Global maximum number of connections:)
_(Maximum number of connections per torrent:)
_(Maximum number of upload slots per torrent:)
+
+
+
+ _(Global Rate Limits) +
+ + + + + + + +
_(Upload:)  _(KiB/s)
_(Download:)  _(KiB/s)
+
+ _(Options) +   _(Enable bandwidth management (uTP))
+   _(Apply rate limit to uTP connections)
+   _(Apply rate limit to transport overhead)
+
+
+
+
+ + + + + + + + + + + +
+
+ + diff --git a/src/webui/html/prop-files.html b/src/webui/html/prop-files.html new file mode 100644 index 000000000..e54eb2c50 --- /dev/null +++ b/src/webui/html/prop-files.html @@ -0,0 +1,318 @@ + + + + + + + + + + + + +
  _(Downloaded)_(Name)_(Size)_(Progress)_(Priority)
+
+ + diff --git a/src/webui/html/prop-general.html b/src/webui/html/prop-general.html new file mode 100644 index 000000000..a8283ff79 --- /dev/null +++ b/src/webui/html/prop-general.html @@ -0,0 +1,108 @@ +
+ _(Transfer) + + + + +
_(Uploaded:)0 Kb_(UP limit:)xx_(Share ratio:)xx
_(Downloaded:)0 Kb_(DL limit:)xx_(Connections:)xx
_(Wasted:)0 Kb_(Time active:)xx
+
+ +
+ _(Information) + + + + + + +
_(Save path:)xxx
_(Created on:)xxx
_(Pieces size:)xxx
_(Torrent hash:)xxx
+
+ _(Comment:) +
+ +
+
+
+ + + + diff --git a/src/webui/html/prop-trackers.html b/src/webui/html/prop-trackers.html new file mode 100644 index 000000000..904f2bb2b --- /dev/null +++ b/src/webui/html/prop-trackers.html @@ -0,0 +1,146 @@ + + + + + + + + + + + + +
_(URL) _(Status)_(Peers)_(Message)
+
+ + diff --git a/src/webui/html/properties.html b/src/webui/html/properties.html new file mode 100644 index 000000000..0aa80f3cd --- /dev/null +++ b/src/webui/html/properties.html @@ -0,0 +1,37 @@ + + + diff --git a/src/webui/html/transferlist.html b/src/webui/html/transferlist.html new file mode 100644 index 000000000..b5425449d --- /dev/null +++ b/src/webui/html/transferlist.html @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + +
_(Name)#_(Size)_(Done)_(Seeds)_(Peers)_(Down Speed)_(Up Speed)_(ETA)_(Ratio)
+ + diff --git a/src/webui/html/upload.html b/src/webui/html/upload.html new file mode 100644 index 000000000..7ba68cfde --- /dev/null +++ b/src/webui/html/upload.html @@ -0,0 +1,22 @@ + + + + + _(Download local torrent) + + + + + +
+

_(Download local torrent)

+ +
+ + diff --git a/src/webui/html/uploadframe.html b/src/webui/html/uploadframe.html new file mode 100644 index 000000000..8f29481ba --- /dev/null +++ b/src/webui/html/uploadframe.html @@ -0,0 +1,25 @@ + + + + + _(Download local torrent) + + + + + +
+ +

_(Point to torrent file)

+ _(Download) +
+ + diff --git a/src/webui/html/uploadlimit.html b/src/webui/html/uploadlimit.html new file mode 100644 index 000000000..43c57070f --- /dev/null +++ b/src/webui/html/uploadlimit.html @@ -0,0 +1,54 @@ + + + + + _(Torrent Upload Speed Limiting) + + + + + + + + +
+
+
_(Upload limit:) 0 _(KiB/s)
+
+
+
+
+
+
+ + +
+ + + + + \ No newline at end of file diff --git a/src/webui/httpconnection.cpp b/src/webui/httpconnection.cpp new file mode 100644 index 000000000..121eb33f1 --- /dev/null +++ b/src/webui/httpconnection.cpp @@ -0,0 +1,633 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Ishan Arora and Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + + +#include "httpconnection.h" +#include "httpserver.h" +#include "eventmanager.h" +#include "preferences.h" +#include "json.h" +#include "qbtsession.h" +#include "misc.h" +#ifndef DISABLE_GUI +#include "iconprovider.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace libtorrent; + +HttpConnection::HttpConnection(QTcpSocket *socket, HttpServer *parent) + : QObject(parent), socket(socket), httpserver(parent) +{ + socket->setParent(this); + connect(socket, SIGNAL(readyRead()), this, SLOT(read())); + connect(socket, SIGNAL(disconnected()), this, SLOT(deleteLater())); +} + +HttpConnection::~HttpConnection() +{ + delete socket; +} + +void HttpConnection::processDownloadedFile(QString url, QString file_path) { + qDebug("URL %s successfully downloaded !", (const char*)url.toLocal8Bit()); + emit torrentReadyToBeDownloaded(file_path, false, url, false); +} + +void HttpConnection::handleDownloadFailure(QString url, QString reason) { + std::cerr << "Could not download " << (const char*)url.toLocal8Bit() << ", reason: " << (const char*)reason.toLocal8Bit() << "\n"; +} + +void HttpConnection::read() +{ + QByteArray input = socket->readAll(); + /*qDebug(" -------"); + qDebug("|REQUEST|"); + qDebug(" -------"); */ + //qDebug("%s", input.toAscii().constData()); + if(input.size() > 100000) { + qDebug("Request too big"); + generator.setStatusLine(400, "Bad Request"); + write(); + return; + } + parser.write(input); + if(parser.isError()) + { + generator.setStatusLine(400, "Bad Request"); + write(); + } + else + if (parser.isParsable()) + respond(); +} + +void HttpConnection::write() +{ + QByteArray output = generator.toByteArray(); + /*qDebug(" --------"); + qDebug("|RESPONSE|"); + qDebug(" --------"); + qDebug()<write(output); + socket->disconnectFromHost(); +} + +QString HttpConnection::translateDocument(QString data) { + std::string contexts[] = {"TransferListFiltersWidget", "TransferListWidget", "PropertiesWidget", "MainWindow", "HttpServer", "confirmDeletionDlg", "TrackerList", "TorrentFilesModel", "options_imp", "Preferences", "TrackersAdditionDlg", "ScanFoldersModel", "PropTabBar", "TorrentModel", "downloadFromURL"}; + int i=0; + bool found = false; + do { + found = false; + static QRegExp regex(QString::fromUtf8("_\\(([\\w\\s?!:\\/\\(\\),%µ&\\-\\.]+)\\)")); + i = regex.indexIn(data, i); + if(i >= 0) { + //qDebug("Found translatable string: %s", regex.cap(1).toUtf8().data()); + QString word = regex.cap(1); + QString translation = word; + int context_index= 0; + do { + translation = qApp->translate(contexts[context_index].c_str(), word.toLocal8Bit().constData(), 0, QCoreApplication::UnicodeUTF8, 1); + ++context_index; + }while(translation == word && context_index < 15); + // Remove keyboard shortcuts + static QRegExp mnemonic("\\(?&([a-zA-Z]?\\))?"); + translation = translation.replace(mnemonic, ""); + //qDebug("Translation is %s", translation.toUtf8().data()); + data = data.replace(i, regex.matchedLength(), translation); + i += translation.length(); + found = true; + } + }while(found && i < data.size()); + return data; +} + +void HttpConnection::respond() { + if((socket->peerAddress() != QHostAddress::LocalHost && socket->peerAddress() != QHostAddress::LocalHostIPv6) + || httpserver->isLocalAuthEnabled()) { + // Authentication + const QString peer_ip = socket->peerAddress().toString(); + const int nb_fail = httpserver->NbFailedAttemptsForIp(peer_ip); + if(nb_fail >= MAX_AUTH_FAILED_ATTEMPTS) { + generator.setStatusLine(403, "Forbidden"); + generator.setMessage(tr("Your IP address has been banned after too many failed authentication attempts.")); + write(); + return; + } + QString auth = parser.value("Authorization"); + if(auth.isEmpty()) { + // Return unauthorized header + qDebug("Auth is Empty..."); + generator.setStatusLine(401, "Unauthorized"); + generator.setValue("WWW-Authenticate", "Digest realm=\""+QString(QBT_REALM)+"\", nonce=\""+httpserver->generateNonce()+"\", opaque=\""+httpserver->generateNonce()+"\", stale=\"false\", algorithm=\"MD5\", qop=\"auth\""); + write(); + return; + } + //qDebug("Auth: %s", qPrintable(auth.split(" ").first())); + if (QString::compare(auth.split(" ").first(), "Digest", Qt::CaseInsensitive) != 0 || !httpserver->isAuthorized(auth.toLocal8Bit(), parser.method())) { + // Update failed attempt counter + httpserver->increaseNbFailedAttemptsForIp(peer_ip); + qDebug("client IP: %s (%d failed attempts)", qPrintable(peer_ip), nb_fail+1); + // Return unauthorized header + generator.setStatusLine(401, "Unauthorized"); + generator.setValue("WWW-Authenticate", "Digest realm=\""+QString(QBT_REALM)+"\", nonce=\""+httpserver->generateNonce()+"\", opaque=\""+httpserver->generateNonce()+"\", stale=\"false\", algorithm=\"MD5\", qop=\"auth\""); + write(); + return; + } + // Client successfully authenticated, reset number of failed attempts + httpserver->resetNbFailedAttemptsForIp(peer_ip); + } + QString url = parser.url(); + // Favicon + if(url.endsWith("favicon.ico")) { + qDebug("Returning favicon"); + QFile favicon(":/Icons/skin/qbittorrent16.png"); + if(favicon.open(QIODevice::ReadOnly)) { + QByteArray data = favicon.readAll(); + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt("png"); + generator.setMessage(data); + write(); + } else { + respondNotFound(); + } + return; + } + QStringList list = url.split('/', QString::SkipEmptyParts); + if (list.contains(".") || list.contains("..")) + { + respondNotFound(); + return; + } + if (list.size() == 0) + list.append("index.html"); + if (list.size() >= 2) + { + if (list[0] == "json") + { + if (list[1] == "events") + { + respondJson(); + return; + } + if(list.size() > 2) { + if(list[1] == "propertiesGeneral") { + QString hash = list[2]; + respondGenPropertiesJson(hash); + return; + } + if(list[1] == "propertiesTrackers") { + QString hash = list[2]; + respondTrackersPropertiesJson(hash); + return; + } + if(list[1] == "propertiesFiles") { + QString hash = list[2]; + respondFilesPropertiesJson(hash); + return; + } + } else { + if(list[1] == "preferences") { + respondPreferencesJson(); + return; + } else { + if(list[1] == "transferInfo") { + respondGlobalTransferInfoJson(); + return; + } + } + } + } + if (list[0] == "command") + { + QString command = list[1]; + respondCommand(command); + generator.setStatusLine(200, "OK"); + write(); + return; + } + } + // Icons from theme + qDebug() << "list[0]" << list[0]; + if(list[0] == "theme" && list.size() == 2) { +#ifdef DISABLE_GUI + url = ":/Icons/oxygen/"+list[1]+".png"; +#else + url = IconProvider::instance()->getIconPath(list[1]); +#endif + qDebug() << "There icon:" << url; + } else { + if (list[0] == "images") { + list[0] = "Icons"; + } else { + if(list.last().endsWith(".html")) + list.prepend("html"); + list.prepend("webui"); + } + url = ":/" + list.join("/"); + } + QFile file(url); + if(!file.open(QIODevice::ReadOnly)) + { + qDebug("File %s was not found!", qPrintable(url)); + respondNotFound(); + return; + } + QString ext = list.last(); + int index = ext.lastIndexOf('.') + 1; + if (index > 0) + ext.remove(0, index); + else + ext.clear(); + QByteArray data = file.readAll(); + // Translate the page + if(ext == "html" || (ext == "js" && !list.last().startsWith("excanvas"))) { + data = translateDocument(QString::fromUtf8(data.data())).toUtf8(); + } + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt(ext); + generator.setMessage(data); + write(); +} + +void HttpConnection::respondNotFound() +{ + generator.setStatusLine(404, "File not found"); + write(); +} + +void HttpConnection::respondJson() +{ + EventManager* manager = httpserver->eventManager(); + QString string = json::toJson(manager->getEventList()); + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt("js"); + generator.setMessage(string); + write(); +} + +void HttpConnection::respondGenPropertiesJson(QString hash) { + EventManager* manager = httpserver->eventManager(); + QString string = json::toJson(manager->getPropGeneralInfo(hash)); + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt("js"); + generator.setMessage(string); + write(); +} + +void HttpConnection::respondTrackersPropertiesJson(QString hash) { + EventManager* manager = httpserver->eventManager(); + QString string = json::toJson(manager->getPropTrackersInfo(hash)); + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt("js"); + generator.setMessage(string); + write(); +} + +void HttpConnection::respondFilesPropertiesJson(QString hash) { + EventManager* manager = httpserver->eventManager(); + QString string = json::toJson(manager->getPropFilesInfo(hash)); + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt("js"); + generator.setMessage(string); + write(); +} + +void HttpConnection::respondPreferencesJson() { + EventManager* manager = httpserver->eventManager(); + QString string = json::toJson(manager->getGlobalPreferences()); + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt("js"); + generator.setMessage(string); + write(); +} + +void HttpConnection::respondGlobalTransferInfoJson() { + QVariantMap info; + session_status sessionStatus = QBtSession::instance()->getSessionStatus(); + info["DlInfos"] = tr("D: %1/s - T: %2", "Download speed: x KiB/s - Transferred: x MiB").arg(misc::friendlyUnit(sessionStatus.payload_download_rate)).arg(misc::friendlyUnit(sessionStatus.total_payload_download)); + info["UpInfos"] = tr("U: %1/s - T: %2", "Upload speed: x KiB/s - Transferred: x MiB").arg(misc::friendlyUnit(sessionStatus.payload_upload_rate)).arg(misc::friendlyUnit(sessionStatus.total_payload_upload)); + QString string = json::toJson(info); + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt("js"); + generator.setMessage(string); + write(); +} + +void HttpConnection::respondCommand(QString command) +{ + if(command == "download") + { + QString urls = parser.post("urls"); + QStringList list = urls.split('\n'); + foreach(QString url, list){ + url = url.trimmed(); + if(!url.isEmpty()){ + if(url.startsWith("bc://bt/", Qt::CaseInsensitive)) { + qDebug("Converting bc link to magnet link"); + url = misc::bcLinkToMagnet(url); + } + if(url.startsWith("magnet:", Qt::CaseInsensitive)) { + emit MagnetReadyToBeDownloaded(url); + } else { + qDebug("Downloading url: %s", (const char*)url.toLocal8Bit()); + emit UrlReadyToBeDownloaded(url); + } + } + } + return; + } + if(command == "addTrackers") { + QString hash = parser.post("hash"); + if(!hash.isEmpty()) { + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(h.is_valid() && h.has_metadata()) { + QString urls = parser.post("urls"); + QStringList list = urls.split('\n'); + foreach(QString url, list) { + announce_entry e(url.toStdString()); + h.add_tracker(e); + } + } + } + } + if(command == "upload") + { + QByteArray torrentfile = parser.torrent(); + // Get a unique filename + QString filePath; + // XXX: We need to use a QTemporaryFile pointer here + // and it fails on Windows + QTemporaryFile *tmpfile = new QTemporaryFile; + tmpfile->setAutoRemove(false); + if (tmpfile->open()) { + filePath = tmpfile->fileName(); + } else { + std::cerr << "I/O Error: Could not create temporary file" << std::endl; + return; + } + tmpfile->close(); + // Now temporary file is created but closed so that it can be used. + // write torrent to temporary file + QFile torrent(filePath); + if(torrent.open(QIODevice::WriteOnly)) { + torrent.write(torrentfile); + torrent.close(); + } else { + std::cerr << "I/O Error: Could not create temporary file" << std::endl; + return; + } + emit torrentReadyToBeDownloaded(filePath, false, QString(), false); + delete tmpfile; + // Prepare response + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt("html"); + generator.setMessage(QString("")); + write(); + return; + } + if(command == "resumeall") { + emit resumeAllTorrents(); + return; + } + if(command == "pauseall") { + emit pauseAllTorrents(); + return; + } + if(command == "resume") { + emit resumeTorrent(parser.post("hash")); + return; + } + if(command == "setPreferences") { + QString json_str = parser.post("json"); + EventManager* manager = httpserver->eventManager(); + manager->setGlobalPreferences(json::fromJson(json_str)); + } + if(command == "setFilePrio") { + QString hash = parser.post("hash"); + int file_id = parser.post("id").toInt(); + int priority = parser.post("priority").toInt(); + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(h.is_valid() && h.has_metadata()) { + h.file_priority(file_id, priority); + } + } + if(command == "getGlobalUpLimit") { + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt("html"); +#if LIBTORRENT_VERSION_MINOR > 15 + generator.setMessage(QString::number(QBtSession::instance()->getSession()->settings().upload_rate_limit)); +#else + generator.setMessage(QString::number(QBtSession::instance()->getSession()->upload_rate_limit())); +#endif + write(); + } + if(command == "getGlobalDlLimit") { + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt("html"); +#if LIBTORRENT_VERSION_MINOR > 15 + generator.setMessage(QString::number(QBtSession::instance()->getSession()->settings().download_rate_limit)); +#else + generator.setMessage(QString::number(QBtSession::instance()->getSession()->download_rate_limit())); +#endif + write(); + } + if(command == "getTorrentUpLimit") { + QString hash = parser.post("hash"); + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(h.is_valid()) { + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt("html"); + generator.setMessage(QString::number(h.upload_limit())); + write(); + } + } + if(command == "getTorrentDlLimit") { + QString hash = parser.post("hash"); + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(h.is_valid()) { + generator.setStatusLine(200, "OK"); + generator.setContentTypeByExt("html"); + generator.setMessage(QString::number(h.download_limit())); + write(); + } + } + if(command == "setTorrentUpLimit") { + QString hash = parser.post("hash"); + qlonglong limit = parser.post("limit").toLongLong(); + if(limit == 0) limit = -1; + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(h.is_valid()) { + h.set_upload_limit(limit); + } + } + if(command == "setTorrentDlLimit") { + QString hash = parser.post("hash"); + qlonglong limit = parser.post("limit").toLongLong(); + if(limit == 0) limit = -1; + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(h.is_valid()) { + h.set_download_limit(limit); + } + } + if(command == "setGlobalUpLimit") { + qlonglong limit = parser.post("limit").toLongLong(); + if(limit == 0) limit = -1; + QBtSession::instance()->setUploadRateLimit(limit); + Preferences().setGlobalUploadLimit(limit/1024.); + } + if(command == "setGlobalDlLimit") { + qlonglong limit = parser.post("limit").toLongLong(); + if(limit == 0) limit = -1; + QBtSession::instance()->setDownloadRateLimit(limit); + Preferences().setGlobalDownloadLimit(limit/1024.); + } + if(command == "pause") { + emit pauseTorrent(parser.post("hash")); + return; + } + if(command == "delete") { + QStringList hashes = parser.post("hashes").split("|"); + foreach(const QString &hash, hashes) { + emit deleteTorrent(hash, false); + } + return; + } + if(command == "deletePerm") { + QStringList hashes = parser.post("hashes").split("|"); + foreach(const QString &hash, hashes) { + emit deleteTorrent(hash, true); + } + return; + } + if(command == "increasePrio") { + increaseTorrentsPriority(parser.post("hashes").split("|")); + return; + } + if(command == "decreasePrio") { + decreaseTorrentsPriority(parser.post("hashes").split("|")); + return; + } + if(command == "topPrio") { + foreach(const QString &hash, parser.post("hashes").split("|")) { + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(h.is_valid()) h.queue_position_top(); + } + return; + } + if(command == "bottomPrio") { + foreach(const QString &hash, parser.post("hashes").split("|")) { + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(h.is_valid()) h.queue_position_bottom(); + } + return; + } + if(command == "recheck"){ + recheckTorrent(parser.post("hash")); + return; + } + if(command == "recheckall"){ + recheckAllTorrents(); + return; + } +} + +void HttpConnection::recheckTorrent(QString hash) { + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(h.is_valid()){ + QBtSession::instance()->recheckTorrent(h.hash()); + } +} + +void HttpConnection::recheckAllTorrents() { + std::vector torrents = QBtSession::instance()->getTorrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if(h.is_valid()) + QBtSession::instance()->recheckTorrent(h.hash()); + } +} + +void HttpConnection::decreaseTorrentsPriority(const QStringList &hashes) +{ + qDebug() << Q_FUNC_INFO << hashes; + std::priority_queue, std::vector >, std::less > > torrent_queue; + // Sort torrents by priority + foreach(const QString &hash, hashes) { + try { + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(!h.is_seed()) { + torrent_queue.push(qMakePair(h.queue_position(), h)); + } + }catch(invalid_handle&){} + } + // Decrease torrents priority (starting with the ones with lowest priority) + while(!torrent_queue.empty()) { + QTorrentHandle h = torrent_queue.top().second; + try { + h.queue_position_down(); + } catch(invalid_handle& h) {} + torrent_queue.pop(); + } +} + +void HttpConnection::increaseTorrentsPriority(const QStringList &hashes) +{ + qDebug() << Q_FUNC_INFO << hashes; + std::priority_queue, std::vector >, std::greater > > torrent_queue; + // Sort torrents by priority + foreach(const QString &hash, hashes) { + try { + QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); + if(!h.is_seed()) { + torrent_queue.push(qMakePair(h.queue_position(), h)); + } + }catch(invalid_handle&){} + } + // Increase torrents priority (starting with the ones with highest priority) + while(!torrent_queue.empty()) { + QTorrentHandle h = torrent_queue.top().second; + try { + h.queue_position_up(); + } catch(invalid_handle& h) {} + torrent_queue.pop(); + } +} diff --git a/src/webui/httpconnection.h b/src/webui/httpconnection.h new file mode 100644 index 000000000..8c1f34dba --- /dev/null +++ b/src/webui/httpconnection.h @@ -0,0 +1,98 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Ishan Arora and Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + + +#ifndef HTTPCONNECTION_H +#define HTTPCONNECTION_H + +#include "httprequestparser.h" +#include "httpresponsegenerator.h" +#include + +class HttpServer; + +QT_BEGIN_NAMESPACE +class QTcpSocket; +QT_END_NAMESPACE + +class HttpConnection : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(HttpConnection) + +private: + QTcpSocket *socket; + HttpServer *httpserver; + +protected: + HttpRequestParser parser; + HttpResponseGenerator generator; + +protected slots: + void write(); + void respond(); + void respondJson(); + void respondGenPropertiesJson(QString hash); + void respondTrackersPropertiesJson(QString hash); + void respondFilesPropertiesJson(QString hash); + void respondPreferencesJson(); + void respondGlobalTransferInfoJson(); + void respondCommand(QString command); + void respondNotFound(); + void processDownloadedFile(QString, QString); + void handleDownloadFailure(QString, QString); + void recheckTorrent(QString hash); + void recheckAllTorrents(); + void decreaseTorrentsPriority(const QStringList& hashes); + void increaseTorrentsPriority(const QStringList& hashes); + + +public: + HttpConnection(QTcpSocket *socket, HttpServer *httpserver); + ~HttpConnection(); + QString translateDocument(QString data); + +private slots: + void read(); + +signals: + void UrlReadyToBeDownloaded(QString url); + void MagnetReadyToBeDownloaded(QString uri); + void torrentReadyToBeDownloaded(QString, bool, QString, bool); + void deleteTorrent(QString hash, bool permanently); + void resumeTorrent(QString hash); + void pauseTorrent(QString hash); + void increasePrioTorrent(QString hash); + void decreasePrioTorrent(QString hash); + void resumeAllTorrents(); + void pauseAllTorrents(); +}; + +#endif diff --git a/src/webui/httprequestparser.cpp b/src/webui/httprequestparser.cpp new file mode 100644 index 000000000..b3cc9f74d --- /dev/null +++ b/src/webui/httprequestparser.cpp @@ -0,0 +1,148 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Ishan Arora and Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + + +#include "httprequestparser.h" +#include +#include + +HttpRequestParser::HttpRequestParser() +{ + headerDone = false; + messageDone = false; + error = false; +} + +HttpRequestParser::~HttpRequestParser() +{ +} + +bool HttpRequestParser::isParsable() const +{ + return !error && headerDone && isValid() && (messageDone || !hasContentLength() || contentLength() == 0); +} + +bool HttpRequestParser::isError() const +{ + return error; +} + +QString HttpRequestParser::url() const +{ + return path; +} + +QByteArray HttpRequestParser::message() const +{ + if(isParsable()) + return data; + return QByteArray(); +} + +QString HttpRequestParser::get(const QString key) const +{ + return getMap.value(key); +} + +QString HttpRequestParser::post(const QString key) const +{ + return postMap.value(key); +} + +QByteArray HttpRequestParser::torrent() const +{ + return torrent_content; +} + +void HttpRequestParser::write(QByteArray str) +{ + while (!headerDone && str.size()>0) + { + int index = str.indexOf('\n') + 1; + if(index == 0) + { + data += str; + str.clear(); + } + else + { + data += str.left(index); + str.remove(0, index); + if(data.right(4) == "\r\n\r\n") + { + QHttpRequestHeader::operator=(QHttpRequestHeader(data)); + headerDone = true; + data.clear(); + QUrl url = QUrl::fromEncoded(QHttpRequestHeader::path().toAscii()); + path = url.path(); + //() << path; + QListIterator > i(url.queryItems()); + while (i.hasNext()) + { + QPair pair = i.next(); + getMap[pair.first] = pair.second; + //qDebug() << pair.first << "=" << get(pair.first); + } + } + } + } + if(!messageDone && str.size()>0) + { + if(hasContentLength()) + { + data += str; + if(data.size() >= (int) contentLength()) + { + data.resize(contentLength()); + messageDone = true; + //parse POST data + if(contentType() == "application/x-www-form-urlencoded") + { + QUrl url; + url.setEncodedQuery(data); + QListIterator > i(url.queryItems()); + while (i.hasNext()) + { + QPair pair = i.next(); + postMap[pair.first] = pair.second; + //qDebug() << pair.first << "=" << post(pair.first); + } + } + if(contentType() == "multipart/form-data") + { + //qDebug() << data.right(data.size()-data.indexOf("\r\n\r\n")-QByteArray("\r\n\r\n").size()); + torrent_content = data.right(data.size()-data.indexOf("\r\n\r\n")-QByteArray("\r\n\r\n").size()); + } + } + } + else + error = true; + } +} diff --git a/src/webui/httprequestparser.h b/src/webui/httprequestparser.h new file mode 100644 index 000000000..ba93415c9 --- /dev/null +++ b/src/webui/httprequestparser.h @@ -0,0 +1,62 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Ishan Arora and Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + + +#ifndef HTTPREQUESTPARSER_H +#define HTTPREQUESTPARSER_H + +#include + +class HttpRequestParser : public QHttpRequestHeader +{ + private: + bool headerDone; + bool messageDone; + bool error; + QByteArray data; + QString path; + QMap postMap; + QMap getMap; + QByteArray torrent_content; + + public: + HttpRequestParser(); + ~HttpRequestParser(); + bool isParsable() const; + bool isError() const; + QString url() const; + QByteArray message() const; + QString get(const QString key) const; + QString post(const QString key) const; + QByteArray torrent() const; + void write(QByteArray str); +}; + +#endif diff --git a/src/webui/httpresponsegenerator.cpp b/src/webui/httpresponsegenerator.cpp new file mode 100644 index 000000000..cb9ba6c86 --- /dev/null +++ b/src/webui/httpresponsegenerator.cpp @@ -0,0 +1,78 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Ishan Arora and Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + + +#include "httpresponsegenerator.h" + +void HttpResponseGenerator::setMessage(const QByteArray message) +{ + HttpResponseGenerator::message = message; + setContentLength(message.size()); +} + +void HttpResponseGenerator::setMessage(const QString message) +{ + // This must be UTF-8! + setMessage(message.toUtf8()); +} + +void HttpResponseGenerator::stripMessage() +{ + message.clear(); +} + +void HttpResponseGenerator::setContentTypeByExt(const QString ext) +{ + if(ext == "css") + { + setContentType("text/css"); + return; + } + if(ext == "gif") + { + setContentType("image/gif"); + return; + } + if(ext == "htm" || ext == "html") + { + setContentType("text/html"); + return; + } + if(ext == "js") + { + setContentType("text/javascript"); + return; + } + if(ext == "png") + { + setContentType("image/x-png"); + return; + } +} diff --git a/src/webui/httpresponsegenerator.h b/src/webui/httpresponsegenerator.h new file mode 100644 index 000000000..5d6f8ea0b --- /dev/null +++ b/src/webui/httpresponsegenerator.h @@ -0,0 +1,52 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Ishan Arora and Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + + +#ifndef HTTPRESPONSEGENERATOR_H +#define HTTPRESPONSEGENERATOR_H + +#include + +class HttpResponseGenerator : public QHttpResponseHeader +{ + + public: + void setMessage(const QByteArray message); + void setMessage(const QString message); + void stripMessage(); + void setContentTypeByExt(const QString ext); + inline QByteArray toByteArray() const { return QHttpResponseHeader::toString().toLocal8Bit() + message; } + +private: + QByteArray message; + +}; + +#endif diff --git a/src/webui/httpserver.cpp b/src/webui/httpserver.cpp new file mode 100644 index 000000000..f6052ea0a --- /dev/null +++ b/src/webui/httpserver.cpp @@ -0,0 +1,335 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Ishan Arora and Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + + +#include "httpserver.h" +#include "httpconnection.h" +#include "eventmanager.h" +#include "qbtsession.h" +#include +#include +#include +#include +#include + +#ifndef QT_NO_OPENSSL +#include +#else +#include +#endif + +using namespace libtorrent; + +const int BAN_TIME = 3600000; // 1 hour + +class UnbanTimer: public QTimer { +public: + UnbanTimer(QObject *parent, QString peer_ip): QTimer(parent), peer_ip(peer_ip){ + setSingleShot(true); + setInterval(BAN_TIME); + } + ~UnbanTimer() { + qDebug("||||||||||||Deleting ban timer|||||||||||||||"); + } + QString peer_ip; +}; + +void HttpServer::UnbanTimerEvent() { + UnbanTimer* ubantimer = static_cast(sender()); + qDebug("Ban period has expired for %s", qPrintable(ubantimer->peer_ip)); + client_failed_attempts.remove(ubantimer->peer_ip); + ubantimer->deleteLater(); +} + +int HttpServer::NbFailedAttemptsForIp(QString ip) const { + return client_failed_attempts.value(ip, 0); +} + +void HttpServer::increaseNbFailedAttemptsForIp(QString ip) { + const int nb_fail = client_failed_attempts.value(ip, 0); + client_failed_attempts.insert(ip, nb_fail+1); + if(nb_fail == MAX_AUTH_FAILED_ATTEMPTS-1) { + // Max number of failed attempts reached + // Start ban period + UnbanTimer* ubantimer = new UnbanTimer(this, ip); + connect(ubantimer, SIGNAL(timeout()), this, SLOT(UnbanTimerEvent())); + ubantimer->start(); + } +} + +void HttpServer::resetNbFailedAttemptsForIp(QString ip) { + client_failed_attempts.remove(ip); +} + +HttpServer::HttpServer(int msec, QObject* parent) : QTcpServer(parent) { + const Preferences pref; + username = pref.getWebUiUsername().toLocal8Bit(); + password_ha1 = pref.getWebUiPassword().toLocal8Bit(); + m_localAuth = pref.isWebUiLocalAuthEnabled(); +#ifndef QT_NO_OPENSSL + m_https = pref.isWebUiHttpsEnabled(); + if (m_https) { + m_certificate = QSslCertificate(pref.getWebUiHttpsCertificate()); + m_key = QSslKey(pref.getWebUiHttpsKey(), QSsl::Rsa); + } +#endif + manager = new EventManager(this); + //add torrents + std::vector torrents = QBtSession::instance()->getTorrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if(h.is_valid()) + manager->addedTorrent(h); + } + //connect QBtSession::instance() to manager + connect(QBtSession::instance(), SIGNAL(addedTorrent(QTorrentHandle)), manager, SLOT(addedTorrent(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(deletedTorrent(QString)), manager, SLOT(deletedTorrent(QString))); + //set timer + timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(onTimer())); + timer->start(msec); + // Additional translations for Web UI + QString a = tr("File"); + a = tr("Edit"); + a = tr("Help"); + a = tr("Download Torrents from their URL or Magnet link"); + a = tr("Only one link per line"); + a = tr("Download local torrent"); + a = tr("Torrent files were correctly added to download list."); + a = tr("Point to torrent file"); + a = tr("Download"); + a = tr("Are you sure you want to delete the selected torrents from the transfer list and hard disk?"); + a = tr("Download rate limit must be greater than 0 or disabled."); + a = tr("Upload rate limit must be greater than 0 or disabled."); + a = tr("Maximum number of connections limit must be greater than 0 or disabled."); + a = tr("Maximum number of connections per torrent limit must be greater than 0 or disabled."); + a = tr("Maximum number of upload slots per torrent limit must be greater than 0 or disabled."); + a = tr("Unable to save program preferences, qBittorrent is probably unreachable."); + a = tr("Language"); + a = tr("Downloaded", "Is the file downloaded or not?"); + a = tr("The port used for incoming connections must be greater than 1024 and less than 65535."); + a = tr("The port used for the Web UI must be greater than 1024 and less than 65535."); + a = tr("The Web UI username must be at least 3 characters long."); + a = tr("The Web UI password must be at least 3 characters long."); + a = tr("Save"); + a = tr("qBittorrent client is not reachable"); + a = tr("HTTP Server"); + a = tr("The following parameters are supported:"); + a = tr("Torrent path"); + a = tr("Torrent name"); +} + +HttpServer::~HttpServer() +{ + delete timer; + delete manager; +} + +#ifndef QT_NO_OPENSSL +void HttpServer::enableHttps(const QSslCertificate &certificate, const QSslKey &key) +{ + m_certificate = certificate; + m_key = key; + m_https = true; +} + +void HttpServer::disableHttps() +{ + m_https = false; + m_certificate.clear(); + m_key.clear(); +} +#endif + +void HttpServer::incomingConnection(int socketDescriptor) +{ + QTcpSocket *serverSocket; +#ifndef QT_NO_OPENSSL + if (m_https) + serverSocket = new QSslSocket(this); + else +#endif + serverSocket = new QTcpSocket(this); + if (serverSocket->setSocketDescriptor(socketDescriptor)) { +#ifndef QT_NO_OPENSSL + if (m_https) { + static_cast(serverSocket)->setProtocol(QSsl::AnyProtocol); + static_cast(serverSocket)->setPrivateKey(m_key); + static_cast(serverSocket)->setLocalCertificate(m_certificate); + static_cast(serverSocket)->startServerEncryption(); + } +#endif + handleNewConnection(serverSocket); + } else { + serverSocket->deleteLater(); + } +} + +void HttpServer::handleNewConnection(QTcpSocket *socket) +{ + HttpConnection *connection = new HttpConnection(socket, this); + //connect connection to QBtSession::instance() + connect(connection, SIGNAL(UrlReadyToBeDownloaded(QString)), QBtSession::instance(), SLOT(downloadUrlAndSkipDialog(QString))); + connect(connection, SIGNAL(MagnetReadyToBeDownloaded(QString)), QBtSession::instance(), SLOT(addMagnetSkipAddDlg(QString))); + connect(connection, SIGNAL(torrentReadyToBeDownloaded(QString, bool, QString, bool)), QBtSession::instance(), SLOT(addTorrent(QString, bool, QString, bool))); + connect(connection, SIGNAL(deleteTorrent(QString, bool)), QBtSession::instance(), SLOT(deleteTorrent(QString, bool))); + connect(connection, SIGNAL(pauseTorrent(QString)), QBtSession::instance(), SLOT(pauseTorrent(QString))); + connect(connection, SIGNAL(resumeTorrent(QString)), QBtSession::instance(), SLOT(resumeTorrent(QString))); + connect(connection, SIGNAL(pauseAllTorrents()), QBtSession::instance(), SLOT(pauseAllTorrents())); + connect(connection, SIGNAL(resumeAllTorrents()), QBtSession::instance(), SLOT(resumeAllTorrents())); +} + +void HttpServer::onTimer() { + std::vector torrents = QBtSession::instance()->getTorrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if(h.is_valid()) + manager->modifiedTorrent(h); + } +} + +QString HttpServer::generateNonce() const { + QCryptographicHash md5(QCryptographicHash::Md5); + md5.addData(QTime::currentTime().toString("hhmmsszzz").toLocal8Bit()); + md5.addData(":"); + md5.addData(QBT_REALM); + return md5.result().toHex(); +} + +void HttpServer::setAuthorization(QString _username, QString _password_ha1) { + username = _username.toLocal8Bit(); + password_ha1 = _password_ha1.toLocal8Bit(); +} + +// Parse HTTP AUTH string +// http://tools.ietf.org/html/rfc2617 +bool HttpServer::isAuthorized(QByteArray auth, QString method) const { + //qDebug("AUTH string is %s", auth.data()); + // Get user name + QRegExp regex_user(".*username=\"([^\"]+)\".*"); // Must be a quoted string + if(regex_user.indexIn(auth) < 0) return false; + QString prop_user = regex_user.cap(1); + //qDebug("AUTH: Proposed username is %s, real username is %s", prop_user.toLocal8Bit().data(), username.data()); + if(prop_user != username) { + // User name is invalid, we can reject already + qDebug("AUTH-PROB: Username is invalid"); + return false; + } + // Get realm + QRegExp regex_realm(".*realm=\"([^\"]+)\".*"); // Must be a quoted string + if(regex_realm.indexIn(auth) < 0) { + qDebug("AUTH-PROB: Missing realm"); + return false; + } + QByteArray prop_realm = regex_realm.cap(1).toLocal8Bit(); + if(prop_realm != QBT_REALM) { + qDebug("AUTH-PROB: Wrong realm"); + return false; + } + // get nonce + QRegExp regex_nonce(".*nonce=[\"]?([\\w=]+)[\"]?.*"); + if(regex_nonce.indexIn(auth) < 0) { + qDebug("AUTH-PROB: missing nonce"); + return false; + } + QByteArray prop_nonce = regex_nonce.cap(1).toLocal8Bit(); + //qDebug("prop nonce is: %s", prop_nonce.data()); + // get uri + QRegExp regex_uri(".*uri=\"([^\"]+)\".*"); + if(regex_uri.indexIn(auth) < 0) { + qDebug("AUTH-PROB: Missing uri"); + return false; + } + QByteArray prop_uri = regex_uri.cap(1).toLocal8Bit(); + //qDebug("prop uri is: %s", prop_uri.data()); + // get response + QRegExp regex_response(".*response=[\"]?([\\w=]+)[\"]?.*"); + if(regex_response.indexIn(auth) < 0) { + qDebug("AUTH-PROB: Missing response"); + return false; + } + QByteArray prop_response = regex_response.cap(1).toLocal8Bit(); + //qDebug("prop response is: %s", prop_response.data()); + // Compute correct reponse + QCryptographicHash md5_ha2(QCryptographicHash::Md5); + md5_ha2.addData(method.toLocal8Bit() + ":" + prop_uri); + QByteArray ha2 = md5_ha2.result().toHex(); + QByteArray response = ""; + if(auth.contains("qop=")) { + QCryptographicHash md5_ha(QCryptographicHash::Md5); + // Get nc + QRegExp regex_nc(".*nc=[\"]?([\\w=]+)[\"]?.*"); + if(regex_nc.indexIn(auth) < 0) { + qDebug("AUTH-PROB: qop but missing nc"); + return false; + } + QByteArray prop_nc = regex_nc.cap(1).toLocal8Bit(); + //qDebug("prop nc is: %s", prop_nc.data()); + QRegExp regex_cnonce(".*cnonce=[\"]?([\\w=]+)[\"]?.*"); + if(regex_cnonce.indexIn(auth) < 0) { + qDebug("AUTH-PROB: qop but missing cnonce"); + return false; + } + QByteArray prop_cnonce = regex_cnonce.cap(1).toLocal8Bit(); + //qDebug("prop cnonce is: %s", prop_cnonce.data()); + QRegExp regex_qop(".*qop=[\"]?(\\w+)[\"]?.*"); + if(regex_qop.indexIn(auth) < 0) { + qDebug("AUTH-PROB: missing qop"); + return false; + } + QByteArray prop_qop = regex_qop.cap(1).toLocal8Bit(); + //qDebug("prop qop is: %s", prop_qop.data()); + md5_ha.addData(password_ha1+":"+prop_nonce+":"+prop_nc+":"+prop_cnonce+":"+prop_qop+":"+ha2); + response = md5_ha.result().toHex(); + } else { + QCryptographicHash md5_ha(QCryptographicHash::Md5); + md5_ha.addData(password_ha1+":"+prop_nonce+":"+ha2); + response = md5_ha.result().toHex(); + } + //qDebug("AUTH: comparing reponses: (%d)", static_cast(prop_response == response)); + return prop_response == response; +} + +EventManager* HttpServer::eventManager() const +{ + return manager; +} + +void HttpServer::setlocalAuthEnabled(bool enabled) +{ + m_localAuth = enabled; +} + +bool HttpServer::isLocalAuthEnabled() const +{ + return m_localAuth; +} diff --git a/src/webui/httpserver.h b/src/webui/httpserver.h new file mode 100644 index 000000000..a0936df6e --- /dev/null +++ b/src/webui/httpserver.h @@ -0,0 +1,101 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Ishan Arora and Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + + +#ifndef HTTPSERVER_H +#define HTTPSERVER_H + +#include +#include +#include +#include + +#ifndef QT_NO_OPENSSL +#include +#include +#endif + +#include "preferences.h" + +class EventManager; + +QT_BEGIN_NAMESPACE +class QTimer; +QT_END_NAMESPACE + +const int MAX_AUTH_FAILED_ATTEMPTS = 5; + +class HttpServer : public QTcpServer { + Q_OBJECT + Q_DISABLE_COPY(HttpServer) + +public: + HttpServer(int msec, QObject* parent = 0); + ~HttpServer(); + void setAuthorization(QString username, QString password_ha1); + bool isAuthorized(QByteArray auth, QString method) const; + void setlocalAuthEnabled(bool enabled); + bool isLocalAuthEnabled() const; + EventManager *eventManager() const; + QString generateNonce() const; + int NbFailedAttemptsForIp(QString ip) const; + void increaseNbFailedAttemptsForIp(QString ip); + void resetNbFailedAttemptsForIp(QString ip); + +#ifndef QT_NO_OPENSSL + void enableHttps(const QSslCertificate &certificate, const QSslKey &key); + void disableHttps(); +#endif + +private: + void incomingConnection(int socketDescriptor); + +private slots: + void onTimer(); + void UnbanTimerEvent(); + +private: + void handleNewConnection(QTcpSocket *socket); + +private: + QByteArray username; + QByteArray password_ha1; + EventManager *manager; + QTimer *timer; + QHash client_failed_attempts; + bool m_localAuth; +#ifndef QT_NO_OPENSSL + bool m_https; + QSslCertificate m_certificate; + QSslKey m_key; +#endif +}; + +#endif diff --git a/src/webui/json.h b/src/webui/json.h new file mode 100644 index 000000000..077be49ff --- /dev/null +++ b/src/webui/json.h @@ -0,0 +1,186 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Ishan Arora and Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + + +#ifndef JSON_H +#define JSON_H + +#include + +namespace json { + + QString toJson(QVariant v) { + if (v.isNull()) + return "null"; + switch(v.type()) + { + case QVariant::Bool: + case QVariant::Double: + case QVariant::Int: + case QVariant::LongLong: + case QVariant::UInt: + case QVariant::ULongLong: + return v.value(); + case QVariant::StringList: + case QVariant::List: { + QStringList strList; + foreach(const QVariant &var, v.toList()) { + strList << toJson(var); + } + return "["+strList.join(",")+"]"; + } + case QVariant::String: { + QString s = v.value(); + QString result = "\""; + for(int i=0; i v) { + QStringList res; + foreach(QVariantMap m, v) { + QStringList vlist; + QVariantMap::ConstIterator it; + for(it = m.constBegin(); it != m.constEnd(); it++) { + vlist << toJson(it.key())+":"+toJson(it.value()); + } + res << "{"+vlist.join(",")+"}"; + } + return "["+res.join(",")+"]"; + } +} + +#endif diff --git a/src/webui/scripts/client.js b/src/webui/scripts/client.js new file mode 100644 index 000000000..cf068411f --- /dev/null +++ b/src/webui/scripts/client.js @@ -0,0 +1,366 @@ +/* + * MIT License + * Copyright (c) 2008 Ishan Arora , + * Christophe Dumez + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Debug +//alert(navigator.userAgent); + +// From http://www.quirksmode.org/js/detect.html +var BrowserDetect = { + init: function () { + this.browser = this.searchString(this.dataBrowser) || "An unknown browser"; + //this.version = this.searchVersion(navigator.userAgent) + // || this.searchVersion(navigator.appVersion) + // || "an unknown version"; + //this.OS = this.searchString(this.dataOS) || "an unknown OS"; + }, + searchString: function (data) { + for (var i=0;i + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +window.addEvent('domready', function(){ + $('urls').focus(); + $('downButton').addEvent('click', function(e){ + new Event(e).stop(); + new Request({url: '/command/download', method: 'post', data: {urls: $('urls').value}, + onComplete: function() { + window.parent.document.getElementById('downloadPage').parentNode.removeChild(window.parent.document.getElementById('downloadPage')); + } + }).send(); + }); +}); diff --git a/src/webui/scripts/dynamicTable.js b/src/webui/scripts/dynamicTable.js new file mode 100644 index 000000000..265598c73 --- /dev/null +++ b/src/webui/scripts/dynamicTable.js @@ -0,0 +1,435 @@ +/* + * MIT License + * Copyright (c) 2008 Ishan Arora & Christophe Dumez + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/************************************************************** + + Script : Dynamic Table + Version : 0.5 + Authors : Ishan Arora & Christophe Dumez + Desc : Programable sortable table + Licence : Open Source MIT Licence + +**************************************************************/ + +var dynamicTable = new Class ({ + + initialize: function(){ + }, + + setup: function(table, progressIndex, context_menu){ + this.table = $(table); + this.rows = new Hash(); + this.cur = new Array(); + this.priority_hidden = false; + this.progressIndex = progressIndex; + this.filter = Cookie.read('selected_filter'); + if(!$defined(this.filter)) { + this.filter = 'all'; + } + this.context_menu = context_menu; + this.table.sortedIndex = 1; // Default is NAME + this.table.reverseSort = false; + }, + + sortfunction: function(tr1, tr2) { + var i = tr2.getParent().sortedIndex; + var reverseSort = tr2.getParent().reverseSort; + switch(i) { + case 1: // Name + if(!reverseSort) { + if(tr1.getElements('td')[i].get('html') > tr2.getElements('td')[i].get('html')) + return 1; + return -1; + } else { + if(tr1.getElements('td')[i].get('html') < tr2.getElements('td')[i].get('html')) + return 1; + return -1; + } + case 2: // Prio + var prio1 = tr1.getElements('td')[i].get('html'); + if(prio1 == '*') prio1 = '-1'; + var prio2 = tr2.getElements('td')[i].get('html'); + if(prio2 == '*') prio2 = '-1'; + if(!reverseSort) + return (prio1.toInt() - prio2.toInt()); + else + return (prio2.toInt() - prio1.toInt()); + case 3: // Size + case 7: // Up Speed + case 8: // Down Speed + var sizeStrToFloat = function(mystr) { + var val1 = mystr.split(' '); + var val1num = val1[0].toFloat() + var unit = val1[1].capitalize(); + switch(unit[0]) { + case 'G': + return val1num*1073741824; + case 'M': + return val1num*1048576; + case 'K': + return val1num*1024; + default: + return val1num; + } + }; + if(!reverseSort) + return (sizeStrToFloat(tr1.getElements('td')[i].get('html')) - sizeStrToFloat(tr2.getElements('td')[i].get('html'))); + else + return (sizeStrToFloat(tr2.getElements('td')[i].get('html')) - sizeStrToFloat(tr1.getElements('td')[i].get('html'))); + case 4: // Progress + if(!reverseSort) + return (tr1.getElements('td')[i].getChildren()[0].getValue() - tr2.getElements('td')[i].getChildren()[0].getValue()); + else + return (tr2.getElements('td')[i].getChildren()[0].getValue() - tr1.getElements('td')[i].getChildren()[0].getValue()); + case 5: // Seeds + case 6: // Peers + if(!reverseSort) + return (tr1.getElements('td')[i].get('html').split(' ')[0].toInt() - tr2.getElements('td')[i].get('html').split(' ')[0].toInt()); + else + return (tr2.getElements('td')[i].get('html').split(' ')[0].toInt() - tr1.getElements('td')[i].get('html').split(' ')[0].toInt()); + default: // Ratio + var ratio1 = tr1.getElements('td')[i].get('html'); + if(ratio1 == '∞') + ratio1 = '101.0'; + var ratio2 = tr2.getElements('td')[i].get('html'); + if(ratio2 == '∞') + ratio2 = '101.0'; + if(!reverseSort) + return (ratio1.toFloat() - ratio2.toFloat()); + else + return (ratio2.toFloat() - ratio1.toFloat()); + } + }, + + updateSort: function() { + var trs = this.table.getChildren('tr'); + trs.sort(this.sortfunction); + this.table.set('html', ''); + this.table.adopt(trs); + }, + + setSortedColumn: function(index) { + if(index != this.table.sortedIndex) { + this.table.sortedIndex = index; + this.table.reverseSort = false; + } else { + // Toggle sort order + this.table.reverseSort = !this.table.reverseSort; + } + this.updateSort(); + this.altRow(); + }, + + getCurrentTorrentHash: function() { + if(this.cur.length > 0) + return this.cur[0]; + return ''; + }, + + altRow: function() + { + var trs = this.table.getElements('tr'); + trs.each(function(el,i){ + if(i % 2){ + el.addClass('alt'); + }else{ + el.removeClass('alt'); + } + }.bind(this)); + }, + + hidePriority: function(){ + if(this.priority_hidden) return; + $('prioHeader').addClass('invisible'); + var trs = this.table.getElements('tr'); + trs.each(function(tr,i){ + var tds = tr.getElements('td'); + tds[2].addClass('invisible'); + }.bind(this)); + this.priority_hidden = true; + }, + + setFilter: function(f) { + this.filter = f; + }, + + showPriority: function(){ + if(!this.priority_hidden) return; + $('prioHeader').removeClass('invisible'); + var trs = this.table.getElements('tr'); + trs.each(function(tr,i){ + var tds = tr.getElements('td'); + tds[2].removeClass('invisible'); + }.bind(this)); + this.priority_hidden = false; + }, + + applyFilterOnRow: function(tr, status) { + switch(this.filter) { + case 'all': + tr.removeClass("invisible"); + break; + case 'downloading': + if(status == "downloading" || status == "stalledDL" || status == "checkingDL" || status == "pausedDL" || status == "queuedDL") { + tr.removeClass("invisible"); + } else { + tr.addClass("invisible"); + } + break; + case 'completed': + if(status == "uploading" || status == "stalledUP" || status == "checkingUP" || status == "pausedUP" || status == "queuedUP") { + tr.removeClass("invisible"); + } else { + tr.addClass("invisible"); + } + break; + case 'paused': + if(status == "pausedDL" || status == "pausedUP") { + tr.removeClass("invisible"); + } else { + tr.addClass("invisible"); + } + break; + case 'active': + if(status == "downloading" || status == "uploading") { + tr.removeClass("invisible"); + } else { + tr.addClass("invisible"); + } + break; + case 'inactive': + if(status != "downloading" && status != "uploading") { + tr.removeClass("invisible"); + } else { + tr.addClass("invisible"); + } + } + return !tr.hasClass('invisible'); + }, + + insertRow: function(id, row, status){ + if(this.rows.has(id)) { + return; + } + var tr = new Element('tr'); + tr.addClass("menu-target"); + this.rows.set(id, tr); + for(var i=0; i index_first_tr) && (index <= index_last_tr); + else + return (index < index_first_tr) && (index >= index_last_tr); + }); + trs_to_select.each(function(item, index){ + // Add to selection + this.cur[this.cur.length] = this.getRowId(item); + // Select it visually + item.addClass('selected'); + }.bind(this)); + } else { + // Simple selection + // Remove selected style from previous ones + for(i=0; i 0) { + i++; + } + if(i==trs.length) { + tr.inject(this.table); + } else { + tr.inject(trs[i], 'before'); + } + //tr.injectInside(this.table); + this.altRow(); + // Update context menu + this.context_menu.addTarget(tr); + }, + + selectAll: function() { + this.cur.empty(); + this.rows.each(function(tr, id){ + this.cur[this.cur.length] = id; + if(!tr.hasClass('selected')) { + tr.addClass('selected'); + } + }, this); + }, + + updateRow: function(id, row, status){ + if(!this.rows.has(id)) { + return false; + } + var tr = this.rows.get(id); + // Apply filter + if(this.applyFilterOnRow(tr, status)) { + var tds = tr.getElements('td'); + for(var i=0; i elements as element.getContext(). + * @this {HTMLElement} + * @return {CanvasRenderingContext2D_} + */ + function getContext() { + return this.context_ || + (this.context_ = new CanvasRenderingContext2D_(this)); + } + + var slice = Array.prototype.slice; + + /** + * Binds a function to an object. The returned function will always use the + * passed in {@code obj} as {@code this}. + * + * Example: + * + * g = bind(f, obj, a, b) + * g(c, d) // will do f.call(obj, a, b, c, d) + * + * @param {Function} f The function to bind the object to + * @param {Object} obj The object that should act as this when the function + * is called + * @param {*} var_args Rest arguments that will be used as the initial + * arguments when the function is called + * @return {Function} A new function that has bound this + */ + function bind(f, obj, var_args) { + var a = slice.call(arguments, 2); + return function() { + return f.apply(obj, a.concat(slice.call(arguments))); + }; + } + + var G_vmlCanvasManager_ = { + init: function(opt_doc) { + if (/MSIE/.test(navigator.userAgent) && !window.opera) { + var doc = opt_doc || document; + // Create a dummy element so that IE will allow canvas elements to be + // recognized. + doc.createElement('canvas'); + doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); + } + }, + + init_: function(doc) { + // create xmlns + if (!doc.namespaces['g_vml_']) { + doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml', + '#default#VML'); + + } + if (!doc.namespaces['g_o_']) { + doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office', + '#default#VML'); + } + + // Setup default CSS. Only add one style sheet per document + if (!doc.styleSheets['ex_canvas_']) { + var ss = doc.createStyleSheet(); + ss.owningElement.id = 'ex_canvas_'; + ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + + // default size is 300x150 in Gecko and Opera + 'text-align:left;width:300px;height:150px}' + + 'g_vml_\\:*{behavior:url(#default#VML)}' + + 'g_o_\\:*{behavior:url(#default#VML)}'; + + } + + // find all canvas elements + var els = doc.getElementsByTagName('canvas'); + for (var i = 0; i < els.length; i++) { + this.initElement(els[i]); + } + }, + + /** + * Public initializes a canvas element so that it can be used as canvas + * element from now on. This is called automatically before the page is + * loaded but if you are creating elements using createElement you need to + * make sure this is called on the element. + * @param {HTMLElement} el The canvas element to initialize. + * @return {HTMLElement} the element that was created. + */ + initElement: function(el) { + if (!el.getContext) { + + el.getContext = getContext; + + // do not use inline function because that will leak memory + el.attachEvent('onpropertychange', onPropertyChange); + el.attachEvent('onresize', onResize); + + var attrs = el.attributes; + if (attrs.width && attrs.width.specified) { + // TODO: use runtimeStyle and coordsize + // el.getContext().setWidth_(attrs.width.nodeValue); + el.style.width = attrs.width.nodeValue + 'px'; + } else { + el.width = el.clientWidth; + } + if (attrs.height && attrs.height.specified) { + // TODO: use runtimeStyle and coordsize + // el.getContext().setHeight_(attrs.height.nodeValue); + el.style.height = attrs.height.nodeValue + 'px'; + } else { + el.height = el.clientHeight; + } + //el.getContext().setCoordsize_() + } + return el; + } + }; + + function onPropertyChange(e) { + var el = e.srcElement; + + switch (e.propertyName) { + case 'width': + el.style.width = el.attributes.width.nodeValue + 'px'; + el.getContext().clearRect(); + break; + case 'height': + el.style.height = el.attributes.height.nodeValue + 'px'; + el.getContext().clearRect(); + break; + } + } + + function onResize(e) { + var el = e.srcElement; + if (el.firstChild) { + el.firstChild.style.width = el.clientWidth + 'px'; + el.firstChild.style.height = el.clientHeight + 'px'; + } + } + + G_vmlCanvasManager_.init(); + + // precompute "00" to "FF" + var dec2hex = []; + for (var i = 0; i < 16; i++) { + for (var j = 0; j < 16; j++) { + dec2hex[i * 16 + j] = i.toString(16) + j.toString(16); + } + } + + function createMatrixIdentity() { + return [ + [1, 0, 0], + [0, 1, 0], + [0, 0, 1] + ]; + } + + function matrixMultiply(m1, m2) { + var result = createMatrixIdentity(); + + for (var x = 0; x < 3; x++) { + for (var y = 0; y < 3; y++) { + var sum = 0; + + for (var z = 0; z < 3; z++) { + sum += m1[x][z] * m2[z][y]; + } + + result[x][y] = sum; + } + } + return result; + } + + function copyState(o1, o2) { + o2.fillStyle = o1.fillStyle; + o2.lineCap = o1.lineCap; + o2.lineJoin = o1.lineJoin; + o2.lineWidth = o1.lineWidth; + o2.miterLimit = o1.miterLimit; + o2.shadowBlur = o1.shadowBlur; + o2.shadowColor = o1.shadowColor; + o2.shadowOffsetX = o1.shadowOffsetX; + o2.shadowOffsetY = o1.shadowOffsetY; + o2.strokeStyle = o1.strokeStyle; + o2.globalAlpha = o1.globalAlpha; + o2.arcScaleX_ = o1.arcScaleX_; + o2.arcScaleY_ = o1.arcScaleY_; + o2.lineScale_ = o1.lineScale_; + } + + function processStyle(styleString) { + var str, alpha = 1; + + styleString = String(styleString); + if (styleString.substring(0, 3) == 'rgb') { + var start = styleString.indexOf('(', 3); + var end = styleString.indexOf(')', start + 1); + var guts = styleString.substring(start + 1, end).split(','); + + str = '#'; + for (var i = 0; i < 3; i++) { + str += dec2hex[Number(guts[i])]; + } + + if (guts.length == 4 && styleString.substr(3, 1) == 'a') { + alpha = guts[3]; + } + } else { + str = styleString; + } + + return {color: str, alpha: alpha}; + } + + function processLineCap(lineCap) { + switch (lineCap) { + case 'butt': + return 'flat'; + case 'round': + return 'round'; + case 'square': + default: + return 'square'; + } + } + + /** + * This class implements CanvasRenderingContext2D interface as described by + * the WHATWG. + * @param {HTMLElement} surfaceElement The element that the 2D context should + * be associated with + */ + function CanvasRenderingContext2D_(surfaceElement) { + this.m_ = createMatrixIdentity(); + + this.mStack_ = []; + this.aStack_ = []; + this.currentPath_ = []; + + // Canvas context properties + this.strokeStyle = '#000'; + this.fillStyle = '#000'; + + this.lineWidth = 1; + this.lineJoin = 'miter'; + this.lineCap = 'butt'; + this.miterLimit = Z * 1; + this.globalAlpha = 1; + this.canvas = surfaceElement; + + var el = surfaceElement.ownerDocument.createElement('div'); + el.style.width = surfaceElement.clientWidth + 'px'; + el.style.height = surfaceElement.clientHeight + 'px'; + el.style.overflow = 'hidden'; + el.style.position = 'absolute'; + surfaceElement.appendChild(el); + + this.element_ = el; + this.arcScaleX_ = 1; + this.arcScaleY_ = 1; + this.lineScale_ = 1; + } + + var contextPrototype = CanvasRenderingContext2D_.prototype; + contextPrototype.clearRect = function() { + this.element_.innerHTML = ''; + this.currentPath_ = []; + }; + + contextPrototype.beginPath = function() { + // TODO: Branch current matrix so that save/restore has no effect + // as per safari docs. + this.currentPath_ = []; + }; + + contextPrototype.moveTo = function(aX, aY) { + var p = this.getCoords_(aX, aY); + this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y}); + this.currentX_ = p.x; + this.currentY_ = p.y; + }; + + contextPrototype.lineTo = function(aX, aY) { + var p = this.getCoords_(aX, aY); + this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y}); + + this.currentX_ = p.x; + this.currentY_ = p.y; + }; + + contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, + aCP2x, aCP2y, + aX, aY) { + var p = this.getCoords_(aX, aY); + var cp1 = this.getCoords_(aCP1x, aCP1y); + var cp2 = this.getCoords_(aCP2x, aCP2y); + bezierCurveTo(this, cp1, cp2, p); + }; + + // Helper function that takes the already fixed cordinates. + function bezierCurveTo(self, cp1, cp2, p) { + self.currentPath_.push({ + type: 'bezierCurveTo', + cp1x: cp1.x, + cp1y: cp1.y, + cp2x: cp2.x, + cp2y: cp2.y, + x: p.x, + y: p.y + }); + self.currentX_ = p.x; + self.currentY_ = p.y; + } + + contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { + // the following is lifted almost directly from + // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes + + var cp = this.getCoords_(aCPx, aCPy); + var p = this.getCoords_(aX, aY); + + var cp1 = { + x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), + y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) + }; + var cp2 = { + x: cp1.x + (p.x - this.currentX_) / 3.0, + y: cp1.y + (p.y - this.currentY_) / 3.0 + }; + + bezierCurveTo(this, cp1, cp2, p); + }; + + contextPrototype.arc = function(aX, aY, aRadius, + aStartAngle, aEndAngle, aClockwise) { + aRadius *= Z; + var arcType = aClockwise ? 'at' : 'wa'; + + var xStart = aX + mc(aStartAngle) * aRadius - Z2; + var yStart = aY + ms(aStartAngle) * aRadius - Z2; + + var xEnd = aX + mc(aEndAngle) * aRadius - Z2; + var yEnd = aY + ms(aEndAngle) * aRadius - Z2; + + // IE won't render arches drawn counter clockwise if xStart == xEnd. + if (xStart == xEnd && !aClockwise) { + xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something + // that can be represented in binary + } + + var p = this.getCoords_(aX, aY); + var pStart = this.getCoords_(xStart, yStart); + var pEnd = this.getCoords_(xEnd, yEnd); + + this.currentPath_.push({type: arcType, + x: p.x, + y: p.y, + radius: aRadius, + xStart: pStart.x, + yStart: pStart.y, + xEnd: pEnd.x, + yEnd: pEnd.y}); + + }; + + contextPrototype.rect = function(aX, aY, aWidth, aHeight) { + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + }; + + contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { + // Will destroy any existing path (same as FF behaviour) + this.beginPath(); + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + this.stroke(); + this.currentPath_ = []; + }; + + contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { + // Will destroy any existing path (same as FF behaviour) + this.beginPath(); + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + this.fill(); + this.currentPath_ = []; + }; + + contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { + var gradient = new CanvasGradient_('gradient'); + gradient.x0_ = aX0; + gradient.y0_ = aY0; + gradient.x1_ = aX1; + gradient.y1_ = aY1; + return gradient; + }; + + contextPrototype.createRadialGradient = function(aX0, aY0, aR0, + aX1, aY1, aR1) { + var gradient = new CanvasGradient_('gradientradial'); + gradient.x0_ = aX0; + gradient.y0_ = aY0; + gradient.r0_ = aR0; + gradient.x1_ = aX1; + gradient.y1_ = aY1; + gradient.r1_ = aR1; + return gradient; + }; + + contextPrototype.drawImage = function(image, var_args) { + var dx, dy, dw, dh, sx, sy, sw, sh; + + // to find the original width we overide the width and height + var oldRuntimeWidth = image.runtimeStyle.width; + var oldRuntimeHeight = image.runtimeStyle.height; + image.runtimeStyle.width = 'auto'; + image.runtimeStyle.height = 'auto'; + + // get the original size + var w = image.width; + var h = image.height; + + // and remove overides + image.runtimeStyle.width = oldRuntimeWidth; + image.runtimeStyle.height = oldRuntimeHeight; + + if (arguments.length == 3) { + dx = arguments[1]; + dy = arguments[2]; + sx = sy = 0; + sw = dw = w; + sh = dh = h; + } else if (arguments.length == 5) { + dx = arguments[1]; + dy = arguments[2]; + dw = arguments[3]; + dh = arguments[4]; + sx = sy = 0; + sw = w; + sh = h; + } else if (arguments.length == 9) { + sx = arguments[1]; + sy = arguments[2]; + sw = arguments[3]; + sh = arguments[4]; + dx = arguments[5]; + dy = arguments[6]; + dw = arguments[7]; + dh = arguments[8]; + } else { + throw Error('Invalid number of arguments'); + } + + var d = this.getCoords_(dx, dy); + + var w2 = sw / 2; + var h2 = sh / 2; + + var vmlStr = []; + + var W = 10; + var H = 10; + + // For some reason that I've now forgotten, using divs didn't work + vmlStr.push(' ' , + '', + ''); + + this.element_.insertAdjacentHTML('BeforeEnd', + vmlStr.join('')); + }; + + contextPrototype.stroke = function(aFill) { + var lineStr = []; + var lineOpen = false; + var a = processStyle(aFill ? this.fillStyle : this.strokeStyle); + var color = a.color; + var opacity = a.alpha * this.globalAlpha; + + var W = 10; + var H = 10; + + lineStr.push(''); + + if (!aFill) { + var lineWidth = this.lineScale_ * this.lineWidth; + + // VML cannot correctly render a line if the width is less than 1px. + // In that case, we dilute the color to make the line look thinner. + if (lineWidth < 1) { + opacity *= lineWidth; + } + + lineStr.push( + '' + ); + } else if (typeof this.fillStyle == 'object') { + var fillStyle = this.fillStyle; + var angle = 0; + var focus = {x: 0, y: 0}; + + // additional offset + var shift = 0; + // scale factor for offset + var expansion = 1; + + if (fillStyle.type_ == 'gradient') { + var x0 = fillStyle.x0_ / this.arcScaleX_; + var y0 = fillStyle.y0_ / this.arcScaleY_; + var x1 = fillStyle.x1_ / this.arcScaleX_; + var y1 = fillStyle.y1_ / this.arcScaleY_; + var p0 = this.getCoords_(x0, y0); + var p1 = this.getCoords_(x1, y1); + var dx = p1.x - p0.x; + var dy = p1.y - p0.y; + angle = Math.atan2(dx, dy) * 180 / Math.PI; + + // The angle should be a non-negative number. + if (angle < 0) { + angle += 360; + } + + // Very small angles produce an unexpected result because they are + // converted to a scientific notation string. + if (angle < 1e-6) { + angle = 0; + } + } else { + var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_); + var width = max.x - min.x; + var height = max.y - min.y; + focus = { + x: (p0.x - min.x) / width, + y: (p0.y - min.y) / height + }; + + width /= this.arcScaleX_ * Z; + height /= this.arcScaleY_ * Z; + var dimension = m.max(width, height); + shift = 2 * fillStyle.r0_ / dimension; + expansion = 2 * fillStyle.r1_ / dimension - shift; + } + + // We need to sort the color stops in ascending order by offset, + // otherwise IE won't interpret it correctly. + var stops = fillStyle.colors_; + stops.sort(function(cs1, cs2) { + return cs1.offset - cs2.offset; + }); + + var length = stops.length; + var color1 = stops[0].color; + var color2 = stops[length - 1].color; + var opacity1 = stops[0].alpha * this.globalAlpha; + var opacity2 = stops[length - 1].alpha * this.globalAlpha; + + var colors = []; + for (var i = 0; i < length; i++) { + var stop = stops[i]; + colors.push(stop.offset * expansion + shift + ' ' + stop.color); + } + + // When colors attribute is used, the meanings of opacity and o:opacity2 + // are reversed. + lineStr.push(''); + } else { + lineStr.push(''); + } + + lineStr.push(''); + + this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); + }; + + contextPrototype.fill = function() { + this.stroke(true); + } + + contextPrototype.closePath = function() { + this.currentPath_.push({type: 'close'}); + }; + + /** + * @private + */ + contextPrototype.getCoords_ = function(aX, aY) { + var m = this.m_; + return { + x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, + y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2 + } + }; + + contextPrototype.save = function() { + var o = {}; + copyState(this, o); + this.aStack_.push(o); + this.mStack_.push(this.m_); + this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); + }; + + contextPrototype.restore = function() { + copyState(this.aStack_.pop(), this); + this.m_ = this.mStack_.pop(); + }; + + contextPrototype.translate = function(aX, aY) { + var m1 = [ + [1, 0, 0], + [0, 1, 0], + [aX, aY, 1] + ]; + + this.m_ = matrixMultiply(m1, this.m_); + }; + + contextPrototype.rotate = function(aRot) { + var c = mc(aRot); + var s = ms(aRot); + + var m1 = [ + [c, s, 0], + [-s, c, 0], + [0, 0, 1] + ]; + + this.m_ = matrixMultiply(m1, this.m_); + }; + + contextPrototype.scale = function(aX, aY) { + this.arcScaleX_ *= aX; + this.arcScaleY_ *= aY; + var m1 = [ + [aX, 0, 0], + [0, aY, 0], + [0, 0, 1] + ]; + + var m = this.m_ = matrixMultiply(m1, this.m_); + + // Get the line scale. + // Determinant of this.m_ means how much the area is enlarged by the + // transformation. So its square root can be used as a scale factor + // for width. + var det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; + this.lineScale_ = sqrt(abs(det)); + }; + + /******** STUBS ********/ + contextPrototype.clip = function() { + // TODO: Implement + }; + + contextPrototype.arcTo = function() { + // TODO: Implement + }; + + contextPrototype.createPattern = function() { + return new CanvasPattern_; + }; + + // Gradient / Pattern Stubs + function CanvasGradient_(aType) { + this.type_ = aType; + this.x0_ = 0; + this.y0_ = 0; + this.r0_ = 0; + this.x1_ = 0; + this.y1_ = 0; + this.r1_ = 0; + this.colors_ = []; + } + + CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { + aColor = processStyle(aColor); + this.colors_.push({offset: aOffset, + color: aColor.color, + alpha: aColor.alpha}); + }; + + function CanvasPattern_() {} + + // set up externs + G_vmlCanvasManager = G_vmlCanvasManager_; + CanvasRenderingContext2D = CanvasRenderingContext2D_; + CanvasGradient = CanvasGradient_; + CanvasPattern = CanvasPattern_; + +})(); + +} // if diff --git a/src/webui/scripts/mocha-init.js b/src/webui/scripts/mocha-init.js new file mode 100644 index 000000000..18b1a0001 --- /dev/null +++ b/src/webui/scripts/mocha-init.js @@ -0,0 +1,292 @@ +/* ----------------------------------------------------------------- + + ATTACH MOCHA LINK EVENTS + Notes: Here is where you define your windows and the events that open them. + If you are not using links to run Mocha methods you can remove this function. + + If you need to add link events to links within windows you are creating, do + it in the onContentLoaded function of the new window. + + ----------------------------------------------------------------- */ + +initializeWindows = function(){ + + function addClickEvent(el, fn){ + ['Link','Button'].each(function(item) { + if ($(el+item)){ + $(el+item).addEvent('click', fn); + } + }); + } + + addClickEvent('download', function(e){ + new Event(e).stop(); + new MochaUI.Window({ + id: 'downloadPage', + title: "_(Download from urls)", + loadMethod: 'iframe', + contentURL:'download.html', + scrollbars: true, + resizable: false, + maximizable: false, + closable: true, + paddingVertical: 0, + paddingHorizontal: 0, + width: 500, + height: 300 + }); + }); + + addClickEvent('preferences', function(e) { + new Event(e).stop(); + new MochaUI.Window({ + id: 'preferencesPage', + title: "_(Options)", + loadMethod: 'xhr', + toolbar: true, + contentURL: 'preferences_content.html', + require: { + css: ['css/Tabs.css'] + }, + toolbarURL: 'preferences.html', + resizable: true, + maximizable: false, + closable: true, + paddingVertical: 0, + paddingHorizontal: 0, + width: 700, + height: 300 + }); + }); + + addClickEvent('upload', function(e){ + new Event(e).stop(); + new MochaUI.Window({ + id: 'uploadPage', + title: "_(Download local torrent)", + loadMethod: 'iframe', + contentURL:'upload.html', + scrollbars: true, + resizable: false, + maximizable: false, + paddingVertical: 0, + paddingHorizontal: 0, + width: 500, + height: 150 + }); + }); + + globalUploadLimitFN = function() { + new MochaUI.Window({ + id: 'uploadLimitPage', + title: "_(Global Upload Speed Limiting)", + loadMethod: 'iframe', + contentURL:'uploadlimit.html?hash=global', + scrollbars: false, + resizable: false, + maximizable: false, + paddingVertical: 0, + paddingHorizontal: 0, + width: 424, + height: 80 + }); + } + + uploadLimitFN = function() { + var h = myTable.selectedIds(); + if(h.length){ + var hash = h[0]; + new MochaUI.Window({ + id: 'uploadLimitPage', + title: "_(Torrent Upload Speed Limiting)", + loadMethod: 'iframe', + contentURL:'uploadlimit.html?hash='+hash, + scrollbars: false, + resizable: false, + maximizable: false, + paddingVertical: 0, + paddingHorizontal: 0, + width: 424, + height: 80 + }); + } + }; + + globalDownloadLimitFN = function() { + new MochaUI.Window({ + id: 'downloadLimitPage', + title: "_(Global Download Speed Limiting)", + loadMethod: 'iframe', + contentURL:'downloadlimit.html?hash=global', + scrollbars: false, + resizable: false, + maximizable: false, + paddingVertical: 0, + paddingHorizontal: 0, + width: 424, + height: 80 + }); + } + + downloadLimitFN = function() { + var h = myTable.selectedIds(); + if(h.length){ + var hash = h[0]; + new MochaUI.Window({ + id: 'downloadLimitPage', + title: "_(Torrent Download Speed Limiting)", + loadMethod: 'iframe', + contentURL:'downloadlimit.html?hash='+hash, + scrollbars: false, + resizable: false, + maximizable: false, + paddingVertical: 0, + paddingHorizontal: 0, + width: 424, + height: 80 + }); + } + }; + + deleteFN = function() { + var h = myTable.selectedIds(); + /*if(h.length && confirm('_(Are you sure you want to delete the selected torrents from the transfer list?)')) { + h.each(function(item, index){ + new Request({url: '/command/delete', method: 'post', data: {hash: item}}).send(); + }); + }*/ + if(h.length) { + new MochaUI.Window({ + id: 'confirmDeletionPage', + title: "_(Deletion confirmation - qBittorrent)", + loadMethod: 'iframe', + contentURL:'confirmdeletion.html?hashes='+JSON.encode(h), + scrollbars: false, + resizable: false, + maximizable: false, + padding: 10, + width: 424, + height: 140 + }); + } + }; + + addClickEvent('delete', function(e){ + new Event(e).stop(); + deleteFN(); + }); + + pauseFN = function() { + var h = myTable.selectedIds(); + if(h.length){ + h.each(function(hash, index){ + new Request({url: '/command/pause', method: 'post', data: {hash: hash}}).send(); + }); + } + }; + + startFN = function() { + var h = myTable.selectedIds(); + if(h.length){ + h.each(function(hash, index){ + new Request({url: '/command/resume', method: 'post', data: {hash: hash}}).send(); + }); + } + }; + + recheckFN = function() { + var h = myTable.selectedIds(); + if(h.length){ + h.each(function(hash, index){ + new Request({url: '/command/recheck', method: 'post', data: {hash: hash}}).send(); + }); + } + }; + + ['pause','resume', 'recheck'].each(function(item) { + addClickEvent(item, function(e){ + new Event(e).stop(); + var h = myTable.selectedIds(); + if(h.length){ + h.each(function(hash, index){ + new Request({url: '/command/'+item, method: 'post', data: {hash: hash}}).send(); + }); + } + }); + + addClickEvent(item+'All', function(e){ + new Event(e).stop(); + new Request({url: '/command/'+item+'all'}).send(); + }); + }); + + ['decreasePrio','increasePrio', 'topPrio', 'bottomPrio'].each(function(item) { + addClickEvent(item, function(e){ + new Event(e).stop(); + setPriorityFN(item); + }); + }); + + setPriorityFN = function(cmd) { + var h = myTable.selectedIds(); + if(h.length) { + new Request({url: '/command/'+cmd, method: 'post', data: {hashes: h.join("|")}}).send(); + } + } + + addClickEvent('bug', function(e){ + new Event(e).stop(); + new MochaUI.Window({ + id: 'bugPage', + title: '_(Report a bug)', + loadMethod: 'iframe', + contentURL: 'http://bugs.qbittorrent.org/', + width: 650, + height: 400 + }); + }); + + addClickEvent('site', function(e){ + new Event(e).stop(); + new MochaUI.Window({ + id: 'sitePage', + title: 'qBittorrent Website', + loadMethod: 'iframe', + contentURL: 'http://www.qbittorrent.org/', + width: 650, + height: 400 + }); + }); + + addClickEvent('docs', function(e){ + new Event(e).stop(); + new MochaUI.Window({ + id: 'docsPage', + title: 'qBittorrent official wiki', + loadMethod: 'iframe', + contentURL: 'http://wiki.qbittorrent.org/', + width: 650, + height: 400 + }); + }); + + addClickEvent('about', function(e){ + new Event(e).stop(); + new MochaUI.Window({ + id: 'aboutpage', + title: 'About', + loadMethod: 'iframe', + contentURL: 'about.html', + width: 650, + height: 400, + padding: 10 + }); + }); + + // Deactivate menu header links + $$('a.returnFalse').each(function(el){ + el.addEvent('click', function(e){ + new Event(e).stop(); + }); + }); +} diff --git a/src/webui/scripts/mocha-yc.js b/src/webui/scripts/mocha-yc.js new file mode 100644 index 000000000..ebc98b4ae --- /dev/null +++ b/src/webui/scripts/mocha-yc.js @@ -0,0 +1 @@ +var MUI=MochaUI=new Hash({version:"0.9.6 development",options:new Hash({theme:"default",advancedEffects:false,standardEffects:true}),path:{source:"scripts/source/",themes:"themes/",plugins:"plugins/"},themePath:function(){return MUI.path.themes+MUI.options.theme+"/"},files:new Hash()});MUI.files[MUI.path.source+"Core/Core.js"]="loaded";MUI.extend({Windows:{instances:new Hash()},ieSupport:"excanvas",updateContent:function(c){var c=$extend({element:null,childElement:null,method:null,data:null,title:null,content:null,loadMethod:null,url:null,scrollbars:null,padding:null,require:{},onContentLoaded:$empty},c);c.require=$extend({css:[],images:[],js:[],onload:null},c.require);var b={};if(!c.element){return}var d=c.element;if(MUI.Windows.instances.get(d.id)){b.recipient="window"}else{b.recipient="panel"}var a=d.retrieve("instance");if(c.title){a.titleEl.set("html",c.title)}var e=a.contentEl;b.contentContainer=c.childElement!=null?c.childElement:a.contentEl;var g=a.contentWrapperEl;if(!c.loadMethod){if(!a.options.loadMethod){if(!c.url){c.loadMethod="html"}else{c.loadMethod="xhr"}}else{c.loadMethod=a.options.loadMethod}}var f=c.scrollbars||a.options.scrollbars;if(b.contentContainer==a.contentEl){g.setStyles({overflow:f!=false&&c.loadMethod!="iframe"?"auto":"hidden"})}if(c.padding!=null){e.setStyles({"padding-top":c.padding.top,"padding-bottom":c.padding.bottom,"padding-left":c.padding.left,"padding-right":c.padding.right})}if(b.contentContainer==e){e.empty().show();e.getAllNext(".column").destroy();e.getAllNext(".columnHandle").destroy()}b.onContentLoaded=function(){if(c.require.js.length||typeof c.require.onload=="function"){new MUI.Require({js:c.require.js,onload:function(){if(Browser.Engine.presto){c.require.onload.delay(100)}else{c.require.onload()}c.onContentLoaded?c.onContentLoaded():a.fireEvent("onContentLoaded",d)}.bind(this)})}else{c.onContentLoaded?c.onContentLoaded():a.fireEvent("onContentLoaded",d)}};if(c.require.css.length||c.require.images.length){new MUI.Require({css:c.require.css,images:c.require.images,onload:function(){this.loadSelect(a,c,b)}.bind(this)})}else{this.loadSelect(a,c,b)}},loadSelect:function(a,c,b){switch(c.loadMethod){case"xhr":this.updateContentXHR(a,c,b);break;case"iframe":this.updateContentIframe(a,c,b);break;case"html":default:this.updateContentHTML(a,c,b);break}},updateContentXHR:function(a,c,b){var f=a.contentEl;var e=b.contentContainer;var d=b.onContentLoaded;new Request.HTML({url:c.url,update:e,method:c.method!=null?c.method:"get",data:c.data!=null?new Hash(c.data).toQueryString():"",evalScripts:a.options.evalScripts,evalResponse:a.options.evalResponse,onRequest:function(){if(b.recipient=="window"&&e==f){a.showSpinner()}else{if(b.recipient=="panel"&&e==f&&$("spinner")){$("spinner").show()}}}.bind(this),onFailure:function(g){if(e==f){var j=new RegExp("[\n\rs]*(.*)[\n\rs]*","gmi");var h=j.exec(g.responseText);if(!h){h="Unknown"}e.set("html","

Error: "+h[1]+"

");if(b.recipient=="window"){a.hideSpinner()}else{if(b.recipient=="panel"&&$("spinner")){$("spinner").hide()}}}}.bind(this),onSuccess:function(){if(e==f){if(b.recipient=="window"){a.hideSpinner()}else{if(b.recipient=="panel"&&$("spinner")){$("spinner").hide()}}}Browser.Engine.trident4?d.delay(750):d()}.bind(this),onComplete:function(){}.bind(this)}).send()},updateContentIframe:function(a,c,b){var f=a.contentEl;var e=b.contentContainer;var g=a.contentWrapperEl;var d=b.onContentLoaded;if(a.options.contentURL==""||e!=f){return}a.iframeEl=new Element("iframe",{id:a.options.id+"_iframe",name:a.options.id+"_iframe","class":"mochaIframe",src:c.url,marginwidth:0,marginheight:0,frameBorder:0,scrolling:"auto",styles:{height:g.offsetHeight-g.getStyle("border-top").toInt()-g.getStyle("border-bottom").toInt(),width:a.panelEl?g.offsetWidth-g.getStyle("border-left").toInt()-g.getStyle("border-right").toInt():"100%"}}).injectInside(f);a.iframeEl.addEvent("load",function(h){if(b.recipient=="window"){a.hideSpinner()}else{if(b.recipient=="panel"&&e==f&&$("spinner")){$("spinner").hide()}}Browser.Engine.trident4?d.delay(50):d()}.bind(this));if(b.recipient=="window"){a.showSpinner()}else{if(b.recipient=="panel"&&e==f&&$("spinner")){$("spinner").show()}}},updateContentHTML:function(a,c,b){var f=a.contentEl;var e=b.contentContainer;var d=b.onContentLoaded;var g=new Array("element","textnode","whitespace","collection");if(g.contains($type(c.content))){c.content.inject(e)}else{e.set("html",c.content)}if(e==f){if(b.recipient=="window"){a.hideSpinner()}else{if(b.recipient=="panel"&&$("spinner")){$("spinner").hide()}}}Browser.Engine.trident4?d.delay(50):d()},reloadIframe:function(a){Browser.Engine.gecko?$(a).src=$(a).src:top.frames[a].location.reload(true)},roundedRect:function(f,d,j,h,c,b,g,e){f.fillStyle="rgba("+g.join(",")+","+e+")";f.beginPath();f.moveTo(d,j+b);f.lineTo(d,j+c-b);f.quadraticCurveTo(d,j+c,d+b,j+c);f.lineTo(d+h-b,j+c);f.quadraticCurveTo(d+h,j+c,d+h,j+c-b);f.lineTo(d+h,j+b);f.quadraticCurveTo(d+h,j,d+h-b,j);f.lineTo(d+b,j);f.quadraticCurveTo(d,j,d,j+b);f.fill()},triangle:function(e,c,h,g,b,f,d){e.beginPath();e.moveTo(c+g,h);e.lineTo(c,h+b);e.lineTo(c+g,h+b);e.closePath();e.fillStyle="rgba("+f.join(",")+","+d+")";e.fill()},circle:function(d,b,g,f,e,c){d.beginPath();d.arc(b,g,f,0,Math.PI*2,true);d.fillStyle="rgba("+e.join(",")+","+c+")";d.fill()},notification:function(a){new MUI.Window({loadMethod:"html",closeAfter:1500,type:"notification",addClass:"notification",content:a,width:220,height:40,y:53,padding:{top:10,right:12,bottom:10,left:12},shadowBlur:5})},toggleAdvancedEffects:function(a){if(MUI.options.advancedEffects==false){MUI.options.advancedEffects=true;if(a){this.toggleAdvancedEffectsLink=new Element("div",{"class":"check",id:"toggleAdvancedEffects_check"}).inject(a)}}else{MUI.options.advancedEffects=false;if(this.toggleAdvancedEffectsLink){this.toggleAdvancedEffectsLink.destroy()}}},toggleStandardEffects:function(a){if(MUI.options.standardEffects==false){MUI.options.standardEffects=true;if(a){this.toggleStandardEffectsLink=new Element("div",{"class":"check",id:"toggleStandardEffects_check"}).inject(a)}}else{MUI.options.standardEffects=false;if(this.toggleStandardEffectsLink){this.toggleStandardEffectsLink.destroy()}}},underlayInitialize:function(){var a=new Element("div",{id:"windowUnderlay",styles:{height:parent.getCoordinates().height,opacity:0.01,display:"none"}}).inject(document.body)},setUnderlaySize:function(){$("windowUnderlay").setStyle("height",parent.getCoordinates().height)}});function fixPNG(e){if(Browser.Engine.trident4&&document.body.filters){var b=(e.id)?"id='"+e.id+"' ":"";var d=(e.className)?"class='"+e.className+"' ":"";var f=(e.title)?"title='"+e.title+"' ":"title='"+e.alt+"' ";var c="display:inline-block;"+e.style.cssText;var a="";e.outerHTML=a}}document.addEvent("mousedown",function(a){MUI.blurAll.delay(50)});window.addEvent("domready",function(){MUI.underlayInitialize()});window.addEvent("resize",function(){if($("windowUnderlay")){MUI.setUnderlaySize()}else{MUI.underlayInitialize()}});Element.implement({hide:function(){this.setStyle("display","none");return this},show:function(){this.setStyle("display","block");return this}});Element.implement({shake:function(b,h){b=b||3;h=h||500;h=(h/50).toInt()-1;var e=this.getParent();if(e!=$(document.body)&&e.getStyle("position")=="static"){e.setStyle("position","relative")}var a=this.getStyle("position");if(a=="static"){this.setStyle("position","relative");a="relative"}if(Browser.Engine.trident){e.setStyle("height",e.getStyle("height"))}var g=this.getPosition(e);if(a=="relative"&&!Browser.Engine.presto){g.x-=e.getStyle("paddingLeft").toInt();g.y-=e.getStyle("paddingTop").toInt()}var f=this.retrieve("morph");if(f){f.cancel();var c=f.options}var f=this.get("morph",{duration:50,link:"chain"});for(var d=0;d]*>([\s\S]*?)<\/body>/i);c=(b)?b[1]:c;var a=new Element("div");return a.set("html",c)}});MUI.getCSSRule=function(b){for(var c=0;c=200)&&(a<300))}});Browser.Request=function(){return $try(function(){return new ActiveXObject("MSXML2.XMLHTTP")},function(){return new XMLHttpRequest()})}}MUI.Require=new Class({Implements:[Options],options:{css:[],images:[],js:[],onload:$empty},initialize:function(a){this.setOptions(a);var a=this.options;this.assetsToLoad=a.css.length+a.images.length+a.js.length;this.assetsLoaded=0;var b=0;if(a.css.length){a.css.each(function(c){this.getAsset(c,function(){if(b==a.css.length-1){if(this.assetsLoaded==this.assetsToLoad-1){this.requireOnload()}else{this.assetsLoaded++;this.requireContinue.delay(50,this)}}else{b++;this.assetsLoaded++}}.bind(this))}.bind(this))}else{if(!a.js.length&&!a.images.length){this.options.onload();return true}else{this.requireContinue.delay(50,this)}}},requireOnload:function(){this.assetsLoaded++;if(this.assetsLoaded==this.assetsToLoad){this.options.onload();return true}},requireContinue:function(){var a=this.options;if(a.images.length){a.images.each(function(b){this.getAsset(b,this.requireOnload.bind(this))}.bind(this))}if(a.js.length){a.js.each(function(b){this.getAsset(b,this.requireOnload.bind(this))}.bind(this))}},getAsset:function(b,c){if(MUI.files[b]=="loaded"){if(typeof c=="function"){c()}return true}else{if(MUI.files[b]=="loading"){var d=0;var a=(function(){d++;if(MUI.files[b]=="loading"&&d<"100"){return}$clear(a);if(typeof c=="function"){c()}}).periodical(50)}else{MUI.files[b]="loading";properties={onload:c!="undefined"?c:$empty};var e=properties.onload;properties.onload=function(){MUI.files[b]="loaded";if(e){e()}}.bind(this);switch(b.match(/\.\w+$/)[0]){case".js":return Asset.javascript(b,properties);case".css":return Asset.css(b,properties);case".jpg":case".png":case".gif":return Asset.image(b,properties)}alert('The required file "'+b+'" could not be loaded')}}}});$extend(Asset,{javascript:function(f,d){d=$extend({onload:$empty,document:document,check:$lambda(true)},d);if($(d.id)){d.onload();return $(d.id)}var b=new Element("script",{src:f,type:"text/javascript"});var e=d.onload.bind(b),a=d.check,g=d.document;delete d.onload;delete d.check;delete d.document;if(!Browser.Engine.webkit419&&!Browser.Engine.presto){b.addEvents({load:e,readystatechange:function(){if(Browser.Engine.trident&&["loaded","complete"].contains(this.readyState)){e()}}}).setProperties(d)}else{var c=(function(){if(!$try(a)){return}$clear(c);Browser.Engine.presto?e.delay(500):e()}).periodical(50)}return b.inject(g.head)},css:function(b,a){a=$extend({id:null,media:"screen",onload:$empty},a);new Request({method:"get",url:b,onComplete:function(c){var d=new Element("link",{id:a.id,rel:"stylesheet",media:a.media,type:"text/css",href:b}).inject(document.head);a.onload()}.bind(this),onFailure:function(c){},onSuccess:function(){}.bind(this)}).send()}});MUI.extend({newWindowsFromJSON:function(a){new MUI.Require({js:[MUI.path.source+"Window/Windows-from-json.js"],onload:function(){new MUI.newWindowsFromJSON(a)}})},arrangeCascade:function(){new MUI.Require({js:[MUI.path.source+"Window/Arrange-cascade.js"],onload:function(){new MUI.arrangeCascade()}})},arrangeTile:function(){new MUI.Require({js:[MUI.path.source+"Window/Arrange-tile.js"],onload:function(){new MUI.arrangeTile()}})},saveWorkspace:function(){new MUI.Require({js:[MUI.path.source+"Layout/Workspaces.js"],onload:function(){new MUI.saveWorkspace()}})},loadWorkspace:function(){new MUI.Require({js:[MUI.path.source+"Layout/Workspaces.js"],onload:function(){new MUI.loadWorkspace()}})},Themes:{init:function(a){new MUI.Require({js:[MUI.path.source+"Utilities/Themes.js"],onload:function(){MUI.Themes.init(a)}})}}});MUI.files[MUI.path.source+"Utilities/Themes.js"]=1;MUI.Themes={init:function(a){this.newTheme=a.toLowerCase();if(!this.newTheme||this.newTheme==null||this.newTheme==MUI.options.theme.toLowerCase()){return}if($("spinner")){$("spinner").show()}this.oldURIs=[];this.oldSheets=[];$$("link").each(function(c){var b=c.get("href");if(b.contains(MUI.path.themes+MUI.options.theme)){this.oldURIs.push(b);this.oldSheets.push(c)}}.bind(this));this.newSheetURLs=this.oldURIs.map(function(c,b){return c.replace("/"+MUI.options.theme+"/","/"+MUI.Themes.newTheme+"/")}.bind(this));this.sheetsToLoad=this.oldURIs.length;this.sheetsLoaded=0;this.newSheets=[];this.newSheetURLs.each(function(d){var b=d;var c=new Request({method:"get",url:b,onComplete:function(e){var f=new Element("link",{rel:"stylesheet",media:"screen",type:"text/css",href:b});this.newSheets.push(f)}.bind(this),onFailure:function(e){this.themeLoadSuccess=false;if($("spinner")){$("spinner").hide()}MUI.notification("Stylesheets did not load.")},onSuccess:function(){this.sheetsLoaded++;if(this.sheetsLoaded==this.sheetsToLoad){this.updateThemeStylesheets();this.themeLoadSuccess=true}}.bind(this)});c.send()}.bind(this))},updateThemeStylesheets:function(){this.oldSheets.each(function(a){a.destroy()});this.newSheets.each(function(a){MUI.files[a.get("href")]=1;a.inject(document.head)});if(Browser.Engine.trident){this.redraw.delay(1250,this)}else{this.redraw.delay(250,this)}},redraw:function(){$$(".replaced").removeClass("replaced");$$(".mocha").each(function(c){var b=c.retrieve("instance");b.setColors();b.drawWindow()});if(MUI.Dock){if(MUI.Dock.options.useControls){MUI.Dock.setDockColors();MUI.Dock.renderDockControls()}}if(MUI.Desktop.desktop){var a=(function(){if(MUI.Desktop.desktop.getStyle("overflow")!="hidden"){return}$clear(a);MUI.Desktop.setDesktopSize()}).periodical(50)}if($("spinner")){$("spinner").hide()}MUI.options.theme=this.newTheme}};window.addEvent("load",function(){if($("themeControl")){$("themeControl").getElements("option").setProperty("selected","false");if($("chooseTheme")){$("chooseTheme").setProperty("selected","true")}}});MUI.files[MUI.path.source+"Window/Window.js"]="loading";MUI.extend({Windows:{instances:new Hash(),indexLevel:100,windowIDCount:0,windowsVisible:true,focusingWindow:false}});MUI.Windows.windowOptions={id:null,title:"New Window",icon:false,type:"window",require:{css:[],images:[],js:[],onload:null},loadMethod:null,method:"get",contentURL:null,data:null,closeAfter:false,evalScripts:true,evalResponse:false,content:"Window content",toolbar:false,toolbarPosition:"top",toolbarHeight:29,toolbarURL:"pages/lipsum.html",toolbarData:null,toolbarContent:"",toolbarOnload:$empty,toolbar2:false,toolbar2Position:"bottom",toolbar2Height:29,toolbar2URL:"pages/lipsum.html",toolbar2Data:null,toolbar2Content:"",toolbar2Onload:$empty,container:null,restrict:true,shape:"box",collapsible:true,minimizable:true,maximizable:true,closable:true,storeOnClose:false,modalOverlayClose:true,draggable:null,draggableGrid:false,draggableLimit:false,draggableSnap:false,resizable:null,resizeLimit:{x:[250,2500],y:[125,2000]},addClass:"",width:300,height:125,headerHeight:25,footerHeight:25,cornerRadius:8,x:null,y:null,scrollbars:true,padding:{top:10,right:12,bottom:10,left:12},shadowBlur:5,shadowOffset:{x:0,y:1},controlsOffset:{right:6,top:6},useCanvas:true,useCanvasControls:true,useSpinner:true,headerStartColor:[250,250,250],headerStopColor:[229,229,229],bodyBgColor:[229,229,229],minimizeBgColor:[255,255,255],minimizeColor:[0,0,0],maximizeBgColor:[255,255,255],maximizeColor:[0,0,0],closeBgColor:[255,255,255],closeColor:[0,0,0],resizableColor:[254,254,254],onBeforeBuild:$empty,onContentLoaded:$empty,onFocus:$empty,onBlur:$empty,onResize:$empty,onMinimize:$empty,onMaximize:$empty,onRestore:$empty,onClose:$empty,onCloseComplete:$empty};MUI.Windows.windowOptionsOriginal=$merge(MUI.Windows.windowOptions);MUI.Window=new Class({Implements:[Events,Options],options:MUI.Windows.windowOptions,initialize:function(a){this.setOptions(a);var a=this.options;$extend(this,{mochaControlsWidth:0,minimizebuttonX:0,maximizebuttonX:0,closebuttonX:0,headerFooterShadow:a.headerHeight+a.footerHeight+(a.shadowBlur*2),oldTop:0,oldLeft:0,isMaximized:false,isMinimized:false,isCollapsed:false,timestamp:$time()});if(a.type!="window"){a.container=document.body;a.minimizable=false}if(!a.container){a.container=MUI.Desktop&&MUI.Desktop.desktop?MUI.Desktop.desktop:document.body}if(a.resizable==null){if(a.type!="window"||a.shape=="gauge"){a.resizable=false}else{a.resizable=true}}if(a.draggable==null){a.draggable=a.type!="window"?false:true}if(a.shape=="gauge"||a.type=="notification"){a.collapsible=false;a.maximizable=false;a.contentBgColor="transparent";a.scrollbars=false;a.footerHeight=0}if(a.type=="notification"){a.closable=false;a.headerHeight=0}if(MUI.Dock&&$(MUI.options.dock)){if(MUI.Dock.dock&&a.type!="modal"&&a.type!="modal2"){a.minimizable=a.minimizable}}else{a.minimizable=false}a.maximizable=MUI.Desktop&&MUI.Desktop.desktop&&a.maximizable&&a.type!="modal"&&a.type!="modal2";if(this.options.type=="modal2"){this.options.shadowBlur=0;this.options.shadowOffset={x:0,y:0};this.options.useSpinner=false;this.options.useCanvas=false;this.options.footerHeight=0;this.options.headerHeight=0}a.id=a.id||"win"+(++MUI.Windows.windowIDCount);this.windowEl=$(a.id);if(a.require.css.length||a.require.images.length){new MUI.Require({css:a.require.css,images:a.require.images,onload:function(){this.newWindow()}.bind(this)})}else{this.newWindow()}return this},saveValues:function(){var a=this.windowEl.getCoordinates();this.options.x=a.left.toInt();this.options.y=a.top.toInt()},newWindow:function(d){var b=MUI.Windows.instances;var k=MUI.Windows.instances.get(this.options.id);var l=this.options;if(k){var j=k}if(this.windowEl&&!this.isClosing){if(j.isMinimized){MUI.Dock.restoreMinimized(this.windowEl)}else{if(j.isCollapsed){MUI.collapseToggle(this.windowEl);setTimeout(MUI.focusWindow.pass(this.windowEl,this),10)}else{if(this.windowEl.hasClass("windowClosed")){if(j.check){j.check.show()}this.windowEl.removeClass("windowClosed");this.windowEl.setStyle("opacity",0);this.windowEl.addClass("mocha");if(MUI.Dock&&$(MUI.options.dock)&&j.options.type=="window"){var g=$(j.options.id+"_dockTab");if(g!=null){g.show()}MUI.Desktop.setDesktopSize()}j.displayNewWindow()}else{var h=document.getCoordinates();if(this.windowEl.getStyle("left").toInt()>h.width||this.windowEl.getStyle("top").toInt()>h.height){MUI.centerWindow(this.windowEl)}setTimeout(MUI.focusWindow.pass(this.windowEl,this),10);if(MUI.options.standardEffects==true){this.windowEl.shake()}}}}return}else{b.set(l.id,this)}this.isClosing=false;this.fireEvent("onBeforeBuild");MUI.Windows.indexLevel++;this.windowEl=new Element("div",{"class":"mocha",id:l.id,styles:{position:"absolute",width:l.width,height:l.height,display:"block",opacity:0,zIndex:MUI.Windows.indexLevel+=2}});this.windowEl.store("instance",this);this.windowEl.addClass(l.addClass);if(l.type=="modal2"){this.windowEl.addClass("modal2")}if(Browser.Engine.trident&&l.shape=="gauge"){this.windowEl.setStyle("backgroundImage","url(../images/spacer.gif)")}if((this.options.type=="modal"||l.type=="modal2")&&Browser.Platform.mac&&Browser.Engine.gecko){if(/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)){var c=new Number(RegExp.$1);if(c<3){this.windowEl.setStyle("position","fixed")}}}if(l.loadMethod=="iframe"){l.padding={top:0,right:0,bottom:0,left:0}}this.insertWindowElements();this.titleEl.set("html",l.title);this.contentWrapperEl.setStyle("overflow","hidden");this.contentEl.setStyles({"padding-top":l.padding.top,"padding-bottom":l.padding.bottom,"padding-left":l.padding.left,"padding-right":l.padding.right});if(l.shape=="gauge"){if(l.useCanvasControls){this.canvasControlsEl.setStyle("visibility","hidden")}else{this.controlsEl.setStyle("visibility","hidden")}this.windowEl.addEvent("mouseover",function(){this.mouseover=true;var m=function(){if(this.mouseover!=false){if(l.useCanvasControls){this.canvasControlsEl.setStyle("visibility","visible")}else{this.controlsEl.setStyle("visibility","visible")}this.canvasHeaderEl.setStyle("visibility","visible");this.titleEl.show()}};m.delay(0,this)}.bind(this));this.windowEl.addEvent("mouseleave",function(){this.mouseover=false;if(this.options.useCanvasControls){this.canvasControlsEl.setStyle("visibility","hidden")}else{this.controlsEl.setStyle("visibility","hidden")}this.canvasHeaderEl.setStyle("visibility","hidden");this.titleEl.hide()}.bind(this))}this.windowEl.inject(l.container);this.setColors();if(l.type!="notification"){this.setMochaControlsWidth()}MUI.updateContent({element:this.windowEl,content:l.content,method:l.method,url:l.contentURL,data:l.data,onContentLoaded:null,require:{js:l.require.js,onload:l.require.onload}});if(this.options.toolbar==true){MUI.updateContent({element:this.windowEl,childElement:this.toolbarEl,content:l.toolbarContent,loadMethod:"xhr",method:l.method,url:l.toolbarURL,data:l.toolbarData,onContentLoaded:l.toolbarOnload})}if(this.options.toolbar2==true){MUI.updateContent({element:this.windowEl,childElement:this.toolbar2El,content:l.toolbar2Content,loadMethod:"xhr",method:l.method,url:l.toolbar2URL,data:l.toolbar2Data,onContentLoaded:l.toolbar2Onload})}this.drawWindow();this.attachDraggable();this.attachResizable();this.setupEvents();if(l.resizable){this.adjustHandles()}if(l.container==document.body||l.container==MUI.Desktop.desktop){var a=window.getSize()}else{var a=$(this.options.container).getSize()}if(!l.y){if(MUI.Desktop&&MUI.Desktop.desktop){var e=(a.y*0.5)-(this.windowEl.offsetHeight*0.5);if(e<-l.shadowBlur){e=-l.shadowBlur}}else{var e=window.getScroll().y+(window.getSize().y*0.5)-(this.windowEl.offsetHeight*0.5);if(e<-l.shadowBlur){e=-l.shadowBlur}}}else{var e=l.y-l.shadowBlur}if(!this.options.x){var f=(a.x*0.5)-(this.windowEl.offsetWidth*0.5);if(f<-l.shadowBlur){f=-l.shadowBlur}}else{var f=l.x-l.shadowBlur}this.windowEl.setStyles({top:e,left:f});this.opacityMorph=new Fx.Morph(this.windowEl,{duration:350,transition:Fx.Transitions.Sine.easeInOut,onComplete:function(){if(Browser.Engine.trident){this.drawWindow()}}.bind(this)});this.displayNewWindow();this.morph=new Fx.Morph(this.windowEl,{duration:200});this.windowEl.store("morph",this.morph);this.resizeMorph=new Fx.Elements([this.contentWrapperEl,this.windowEl],{duration:400,transition:Fx.Transitions.Sine.easeInOut,onStart:function(){this.resizeAnimation=this.drawWindow.periodical(20,this)}.bind(this),onComplete:function(){$clear(this.resizeAnimation);this.drawWindow();if(this.iframeEl){this.iframeEl.setStyle("visibility","visible")}}.bind(this)});this.windowEl.store("resizeMorph",this.resizeMorph);if($(this.windowEl.id+"LinkCheck")){this.check=new Element("div",{"class":"check",id:this.options.id+"_check"}).inject(this.windowEl.id+"LinkCheck")}if(this.options.closeAfter!=false){MUI.closeWindow.delay(this.options.closeAfter,this,this.windowEl)}if(MUI.Dock&&$(MUI.options.dock)&&this.options.type=="window"){MUI.Dock.createDockTab(this.windowEl)}},displayNewWindow:function(){options=this.options;if(options.type=="modal"||options.type=="modal2"){MUI.currentModal=this.windowEl;if(Browser.Engine.trident4){$("modalFix").show()}$("modalOverlay").show();if(MUI.options.advancedEffects==false){$("modalOverlay").setStyle("opacity",0.6);this.windowEl.setStyles({zIndex:11000,opacity:1})}else{MUI.Modal.modalOverlayCloseMorph.cancel();MUI.Modal.modalOverlayOpenMorph.start({opacity:0.6});this.windowEl.setStyles({zIndex:11000});this.opacityMorph.start({opacity:1})}$$(".dockTab").removeClass("activeDockTab");$$(".mocha").removeClass("isFocused");this.windowEl.addClass("isFocused")}else{if(MUI.options.advancedEffects==false){this.windowEl.setStyle("opacity",1);setTimeout(MUI.focusWindow.pass(this.windowEl,this),10)}else{if(Browser.Engine.trident){this.drawWindow(false)}this.opacityMorph.start({opacity:1});setTimeout(MUI.focusWindow.pass(this.windowEl,this),10)}}},setupEvents:function(){var a=this.windowEl;if(this.closeButtonEl){this.closeButtonEl.addEvent("click",function(b){new Event(b).stop();MUI.closeWindow(a)}.bind(this))}if(this.options.type=="window"){a.addEvent("mousedown",function(b){if(Browser.Engine.trident){new Event(b).stop()}MUI.focusWindow(a);if(a.getStyle("top").toInt()<-this.options.shadowBlur){a.setStyle("top",-this.options.shadowBlur)}}.bind(this))}if(this.minimizeButtonEl){this.minimizeButtonEl.addEvent("click",function(b){new Event(b).stop();MUI.Dock.minimizeWindow(a)}.bind(this))}if(this.maximizeButtonEl){this.maximizeButtonEl.addEvent("click",function(b){new Event(b).stop();if(this.isMaximized){MUI.Desktop.restoreWindow(a)}else{MUI.Desktop.maximizeWindow(a)}}.bind(this))}if(this.options.collapsible==true){this.titleEl.addEvent("selectstart",function(b){b=new Event(b).stop()}.bind(this));if(Browser.Engine.trident){this.titleBarEl.addEvent("mousedown",function(b){this.titleEl.setCapture()}.bind(this));this.titleBarEl.addEvent("mouseup",function(b){this.titleEl.releaseCapture()}.bind(this))}this.titleBarEl.addEvent("dblclick",function(b){b=new Event(b).stop();MUI.collapseToggle(this.windowEl)}.bind(this))}},attachDraggable:function(){var a=this.windowEl;if(!this.options.draggable){return}this.windowDrag=new Drag.Move(a,{handle:this.titleBarEl,container:this.options.restrict==true?$(this.options.container):false,grid:this.options.draggableGrid,limit:this.options.draggableLimit,snap:this.options.draggableSnap,onStart:function(){if(this.options.type!="modal"&&this.options.type!="modal2"){MUI.focusWindow(a);$("windowUnderlay").show()}if(this.iframeEl){if(!Browser.Engine.trident){this.iframeEl.setStyle("visibility","hidden")}else{this.iframeEl.hide()}}}.bind(this),onComplete:function(){if(this.options.type!="modal"&&this.options.type!="modal2"){$("windowUnderlay").hide()}if(this.iframeEl){if(!Browser.Engine.trident){this.iframeEl.setStyle("visibility","visible")}else{this.iframeEl.show()}}this.saveValues()}.bind(this)})},attachResizable:function(){var a=this.windowEl;if(!this.options.resizable){return}this.resizable1=this.windowEl.makeResizable({handle:[this.n,this.ne,this.nw],limit:{y:[function(){return this.windowEl.getStyle("top").toInt()+this.windowEl.getStyle("height").toInt()-this.options.resizeLimit.y[1]}.bind(this),function(){return this.windowEl.getStyle("top").toInt()+this.windowEl.getStyle("height").toInt()-this.options.resizeLimit.y[0]}.bind(this)]},modifiers:{x:false,y:"top"},onStart:function(){this.resizeOnStart();this.coords=this.contentWrapperEl.getCoordinates();this.y2=this.coords.top.toInt()+this.contentWrapperEl.offsetHeight}.bind(this),onDrag:function(){this.coords=this.contentWrapperEl.getCoordinates();this.contentWrapperEl.setStyle("height",this.y2-this.coords.top.toInt());this.resizeOnDrag()}.bind(this),onComplete:function(){this.resizeOnComplete()}.bind(this)});this.resizable2=this.contentWrapperEl.makeResizable({handle:[this.e,this.ne],limit:{x:[this.options.resizeLimit.x[0]-(this.options.shadowBlur*2),this.options.resizeLimit.x[1]-(this.options.shadowBlur*2)]},modifiers:{x:"width",y:false},onStart:function(){this.resizeOnStart()}.bind(this),onDrag:function(){this.resizeOnDrag()}.bind(this),onComplete:function(){this.resizeOnComplete()}.bind(this)});this.resizable3=this.contentWrapperEl.makeResizable({container:this.options.restrict==true?$(this.options.container):false,handle:this.se,limit:{x:[this.options.resizeLimit.x[0]-(this.options.shadowBlur*2),this.options.resizeLimit.x[1]-(this.options.shadowBlur*2)],y:[this.options.resizeLimit.y[0]-this.headerFooterShadow,this.options.resizeLimit.y[1]-this.headerFooterShadow]},modifiers:{x:"width",y:"height"},onStart:function(){this.resizeOnStart()}.bind(this),onDrag:function(){this.resizeOnDrag()}.bind(this),onComplete:function(){this.resizeOnComplete()}.bind(this)});this.resizable4=this.contentWrapperEl.makeResizable({handle:[this.s,this.sw],limit:{y:[this.options.resizeLimit.y[0]-this.headerFooterShadow,this.options.resizeLimit.y[1]-this.headerFooterShadow]},modifiers:{x:false,y:"height"},onStart:function(){this.resizeOnStart()}.bind(this),onDrag:function(){this.resizeOnDrag()}.bind(this),onComplete:function(){this.resizeOnComplete()}.bind(this)});this.resizable5=this.windowEl.makeResizable({handle:[this.w,this.sw,this.nw],limit:{x:[function(){return this.windowEl.getStyle("left").toInt()+this.windowEl.getStyle("width").toInt()-this.options.resizeLimit.x[1]}.bind(this),function(){return this.windowEl.getStyle("left").toInt()+this.windowEl.getStyle("width").toInt()-this.options.resizeLimit.x[0]}.bind(this)]},modifiers:{x:"left",y:false},onStart:function(){this.resizeOnStart();this.coords=this.contentWrapperEl.getCoordinates();this.x2=this.coords.left.toInt()+this.contentWrapperEl.offsetWidth}.bind(this),onDrag:function(){this.coords=this.contentWrapperEl.getCoordinates();this.contentWrapperEl.setStyle("width",this.x2-this.coords.left.toInt());this.resizeOnDrag()}.bind(this),onComplete:function(){this.resizeOnComplete()}.bind(this)})},resizeOnStart:function(){$("windowUnderlay").show();if(this.iframeEl){if(!Browser.Engine.trident){this.iframeEl.setStyle("visibility","hidden")}else{this.iframeEl.hide()}}},resizeOnDrag:function(){if(Browser.Engine.gecko){this.windowEl.getElements(".panel").each(function(a){a.store("oldOverflow",a.getStyle("overflow"));a.setStyle("overflow","visible")})}this.drawWindow();this.adjustHandles();if(Browser.Engine.gecko){this.windowEl.getElements(".panel").each(function(a){a.setStyle("overflow",a.retrieve("oldOverflow"))})}},resizeOnComplete:function(){$("windowUnderlay").hide();if(this.iframeEl){if(!Browser.Engine.trident){this.iframeEl.setStyle("visibility","visible")}else{this.iframeEl.show();this.iframeEl.setStyle("width","99%");this.iframeEl.setStyle("height",this.contentWrapperEl.offsetHeight);this.iframeEl.setStyle("width","100%");this.iframeEl.setStyle("height",this.contentWrapperEl.offsetHeight)}}if(this.contentWrapperEl.getChildren(".column")!=null){MUI.rWidth(this.contentWrapperEl);this.contentWrapperEl.getChildren(".column").each(function(a){MUI.panelHeight(a)})}this.fireEvent("onResize",this.windowEl)},adjustHandles:function(){var d=this.options.shadowBlur;var j=d*2;var k=this.options.shadowOffset;var e=d-k.y-1;var g=d+k.x-1;var a=d+k.y-1;var c=d-k.x-1;var f=this.windowEl.getCoordinates();var b=f.width-j+2;var h=f.height-j+2;this.n.setStyles({top:e,left:c+10,width:b-20});this.e.setStyles({top:e+10,right:g,height:h-30});this.s.setStyles({bottom:a,left:c+10,width:b-30});this.w.setStyles({top:e+10,left:c,height:h-20});this.ne.setStyles({top:e,right:g});this.se.setStyles({bottom:a,right:g});this.sw.setStyles({bottom:a,left:c});this.nw.setStyles({top:e,left:c})},detachResizable:function(){this.resizable1.detach();this.resizable2.detach();this.resizable3.detach();this.resizable4.detach();this.resizable5.detach();this.windowEl.getElements(".handle").hide()},reattachResizable:function(){this.resizable1.attach();this.resizable2.attach();this.resizable3.attach();this.resizable4.attach();this.resizable5.attach();this.windowEl.getElements(".handle").show()},insertWindowElements:function(){var d=this.options;var a=d.height;var e=d.width;var f=d.id;var b={};if(Browser.Engine.trident4){b.zIndexFixEl=new Element("iframe",{id:f+"_zIndexFix","class":"zIndexFix",scrolling:"no",marginWidth:0,marginHeight:0,src:"",styles:{position:"absolute"}}).inject(this.windowEl)}b.overlayEl=new Element("div",{id:f+"_overlay","class":"mochaOverlay",styles:{position:"absolute",top:0,left:0}}).inject(this.windowEl);b.titleBarEl=new Element("div",{id:f+"_titleBar","class":"mochaTitlebar",styles:{cursor:d.draggable?"move":"default"}}).inject(b.overlayEl,"top");b.titleEl=new Element("h3",{id:f+"_title","class":"mochaTitle"}).inject(b.titleBarEl);if(d.icon!=false){b.titleEl.setStyles({"padding-left":28,background:"url("+d.icon+") 5px 4px no-repeat"})}b.contentBorderEl=new Element("div",{id:f+"_contentBorder","class":"mochaContentBorder"}).inject(b.overlayEl);if(d.toolbar){b.toolbarWrapperEl=new Element("div",{id:f+"_toolbarWrapper","class":"mochaToolbarWrapper",styles:{height:d.toolbarHeight}}).inject(b.contentBorderEl,d.toolbarPosition=="bottom"?"after":"before");if(d.toolbarPosition=="bottom"){b.toolbarWrapperEl.addClass("bottom")}b.toolbarEl=new Element("div",{id:f+"_toolbar","class":"mochaToolbar",styles:{height:d.toolbarHeight}}).inject(b.toolbarWrapperEl)}if(d.toolbar2){b.toolbar2WrapperEl=new Element("div",{id:f+"_toolbar2Wrapper","class":"mochaToolbarWrapper",styles:{height:d.toolbar2Height}}).inject(b.contentBorderEl,d.toolbar2Position=="bottom"?"after":"before");if(d.toolbar2Position=="bottom"){b.toolbar2WrapperEl.addClass("bottom")}b.toolbar2El=new Element("div",{id:f+"_toolbar2","class":"mochaToolbar",styles:{height:d.toolbar2Height}}).inject(b.toolbar2WrapperEl)}b.contentWrapperEl=new Element("div",{id:f+"_contentWrapper","class":"mochaContentWrapper",styles:{width:e+"px",height:a+"px"}}).inject(b.contentBorderEl);if(this.options.shape=="gauge"){b.contentBorderEl.setStyle("borderWidth",0)}b.contentEl=new Element("div",{id:f+"_content","class":"mochaContent"}).inject(b.contentWrapperEl);if(this.options.useCanvas==true&&Browser.Engine.trident!=true){b.canvasEl=new Element("canvas",{id:f+"_canvas","class":"mochaCanvas",width:10,height:10}).inject(this.windowEl)}if(this.options.useCanvas==true&&Browser.Engine.trident){b.canvasEl=new Element("canvas",{id:f+"_canvas","class":"mochaCanvas",width:50000,height:20000,styles:{position:"absolute",top:0,left:0}}).inject(this.windowEl);if(MUI.ieSupport=="excanvas"){G_vmlCanvasManager.initElement(b.canvasEl);b.canvasEl=this.windowEl.getElement(".mochaCanvas")}}b.controlsEl=new Element("div",{id:f+"_controls","class":"mochaControls"}).inject(b.overlayEl,"after");if(d.useCanvasControls==true){b.canvasControlsEl=new Element("canvas",{id:f+"_canvasControls","class":"mochaCanvasControls",width:14,height:14}).inject(this.windowEl);if(Browser.Engine.trident&&MUI.ieSupport=="excanvas"){G_vmlCanvasManager.initElement(b.canvasControlsEl);b.canvasControlsEl=this.windowEl.getElement(".mochaCanvasControls")}}if(d.closable){b.closeButtonEl=new Element("div",{id:f+"_closeButton","class":"mochaCloseButton mochaWindowButton",title:"Close"}).inject(b.controlsEl)}if(d.maximizable){b.maximizeButtonEl=new Element("div",{id:f+"_maximizeButton","class":"mochaMaximizeButton mochaWindowButton",title:"Maximize"}).inject(b.controlsEl)}if(d.minimizable){b.minimizeButtonEl=new Element("div",{id:f+"_minimizeButton","class":"mochaMinimizeButton mochaWindowButton",title:"Minimize"}).inject(b.controlsEl)}if(d.useSpinner==true&&d.shape!="gauge"&&d.type!="notification"){b.spinnerEl=new Element("div",{id:f+"_spinner","class":"mochaSpinner",width:16,height:16}).inject(this.windowEl,"bottom")}if(this.options.shape=="gauge"){b.canvasHeaderEl=new Element("canvas",{id:f+"_canvasHeader","class":"mochaCanvasHeader",width:this.options.width,height:26}).inject(this.windowEl,"bottom");if(Browser.Engine.trident&&MUI.ieSupport=="excanvas"){G_vmlCanvasManager.initElement(b.canvasHeaderEl);b.canvasHeaderEl=this.windowEl.getElement(".mochaCanvasHeader")}}if(Browser.Engine.trident){b.overlayEl.setStyle("zIndex",2)}if(Browser.Platform.mac&&Browser.Engine.gecko){if(/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)){var c=new Number(RegExp.$1);if(c<3){b.overlayEl.setStyle("overflow","auto")}}}if(d.resizable){b.n=new Element("div",{id:f+"_resizeHandle_n","class":"handle",styles:{top:0,left:10,cursor:"n-resize"}}).inject(b.overlayEl,"after");b.ne=new Element("div",{id:f+"_resizeHandle_ne","class":"handle corner",styles:{top:0,right:0,cursor:"ne-resize"}}).inject(b.overlayEl,"after");b.e=new Element("div",{id:f+"_resizeHandle_e","class":"handle",styles:{top:10,right:0,cursor:"e-resize"}}).inject(b.overlayEl,"after");b.se=new Element("div",{id:f+"_resizeHandle_se","class":"handle cornerSE",styles:{bottom:0,right:0,cursor:"se-resize"}}).inject(b.overlayEl,"after");b.s=new Element("div",{id:f+"_resizeHandle_s","class":"handle",styles:{bottom:0,left:10,cursor:"s-resize"}}).inject(b.overlayEl,"after");b.sw=new Element("div",{id:f+"_resizeHandle_sw","class":"handle corner",styles:{bottom:0,left:0,cursor:"sw-resize"}}).inject(b.overlayEl,"after");b.w=new Element("div",{id:f+"_resizeHandle_w","class":"handle",styles:{top:10,left:0,cursor:"w-resize"}}).inject(b.overlayEl,"after");b.nw=new Element("div",{id:f+"_resizeHandle_nw","class":"handle corner",styles:{top:0,left:0,cursor:"nw-resize"}}).inject(b.overlayEl,"after")}$extend(this,b)},setColors:function(){if(this.options.useCanvas==true){var c=/\?(.*?)\)/;if(this.titleBarEl.getStyle("backgroundImage")!="none"){var d=this.titleBarEl.getStyle("backgroundImage");d=d.match(c)[1];d=d.parseQueryString();var a=d.from;var b=d.to.replace(/\"/,"");this.options.headerStartColor=new Color(a);this.options.headerStopColor=new Color(b);this.titleBarEl.addClass("replaced")}else{if(this.titleBarEl.getStyle("background-color")!==""&&this.titleBarEl.getStyle("background-color")!=="transparent"){this.options.headerStartColor=new Color(this.titleBarEl.getStyle("background-color")).mix("#fff",20);this.options.headerStopColor=new Color(this.titleBarEl.getStyle("background-color")).mix("#000",20);this.titleBarEl.addClass("replaced")}}if(this.windowEl.getStyle("background-color")!==""&&this.windowEl.getStyle("background-color")!=="transparent"){this.options.bodyBgColor=new Color(this.windowEl.getStyle("background-color"));this.windowEl.addClass("replaced")}if(this.options.resizable&&this.se.getStyle("background-color")!==""&&this.se.getStyle("background-color")!=="transparent"){this.options.resizableColor=new Color(this.se.getStyle("background-color"));this.se.addClass("replaced")}}if(this.options.useCanvasControls==true){if(this.minimizeButtonEl){if(this.minimizeButtonEl.getStyle("color")!==""&&this.minimizeButtonEl.getStyle("color")!=="transparent"){this.options.minimizeColor=new Color(this.minimizeButtonEl.getStyle("color"))}if(this.minimizeButtonEl.getStyle("background-color")!==""&&this.minimizeButtonEl.getStyle("background-color")!=="transparent"){this.options.minimizeBgColor=new Color(this.minimizeButtonEl.getStyle("background-color"));this.minimizeButtonEl.addClass("replaced")}}if(this.maximizeButtonEl){if(this.maximizeButtonEl.getStyle("color")!==""&&this.maximizeButtonEl.getStyle("color")!=="transparent"){this.options.maximizeColor=new Color(this.maximizeButtonEl.getStyle("color"))}if(this.maximizeButtonEl.getStyle("background-color")!==""&&this.maximizeButtonEl.getStyle("background-color")!=="transparent"){this.options.maximizeBgColor=new Color(this.maximizeButtonEl.getStyle("background-color"));this.maximizeButtonEl.addClass("replaced")}}if(this.closeButtonEl){if(this.closeButtonEl.getStyle("color")!==""&&this.closeButtonEl.getStyle("color")!=="transparent"){this.options.closeColor=new Color(this.closeButtonEl.getStyle("color"))}if(this.closeButtonEl.getStyle("background-color")!==""&&this.closeButtonEl.getStyle("background-color")!=="transparent"){this.options.closeBgColor=new Color(this.closeButtonEl.getStyle("background-color"));this.closeButtonEl.addClass("replaced")}}}},drawWindow:function(b){if(this.drawingWindow==true){return}this.drawingWindow=true;if(this.isCollapsed){this.drawWindowCollapsed(b);return}var g=this.windowEl;var m=this.options;var c=m.shadowBlur;var j=c*2;var l=this.options.shadowOffset;this.overlayEl.setStyles({width:this.contentWrapperEl.offsetWidth});if(this.iframeEl){this.iframeEl.setStyle("height",this.contentWrapperEl.offsetHeight)}var d=this.contentBorderEl.getStyle("border-top").toInt()+this.contentBorderEl.getStyle("border-bottom").toInt();var f=this.toolbarWrapperEl?this.toolbarWrapperEl.getStyle("height").toInt()+this.toolbarWrapperEl.getStyle("border-top").toInt():0;var e=this.toolbar2WrapperEl?this.toolbar2WrapperEl.getStyle("height").toInt()+this.toolbar2WrapperEl.getStyle("border-top").toInt():0;this.headerFooterShadow=m.headerHeight+m.footerHeight+j;var h=this.contentWrapperEl.getStyle("height").toInt()+this.headerFooterShadow+f+e+d;var a=this.contentWrapperEl.getStyle("width").toInt()+j;this.windowEl.setStyles({height:h,width:a});this.overlayEl.setStyles({height:h,top:c-l.y,left:c-l.x});if(this.options.useCanvas==true){if(Browser.Engine.trident){this.canvasEl.height=20000;this.canvasEl.width=50000}this.canvasEl.height=h;this.canvasEl.width=a}if(Browser.Engine.trident4){this.zIndexFixEl.setStyles({width:a,height:h})}this.titleBarEl.setStyles({width:a-j,height:m.headerHeight});if(m.useSpinner==true&&m.shape!="gauge"&&m.type!="notification"){this.spinnerEl.setStyles({left:c-l.x+3,bottom:c+l.y+4})}if(this.options.useCanvas!=false){var k=this.canvasEl.getContext("2d");k.clearRect(0,0,a,h);switch(m.shape){case"box":this.drawBox(k,a,h,c,l,b);break;case"gauge":this.drawGauge(k,a,h,c,l,b);break}if(m.resizable){MUI.triangle(k,a-(c+l.x+17),h-(c+l.y+18),11,11,m.resizableColor,1)}if(Browser.Engine.trident){MUI.triangle(k,0,0,10,10,m.resizableColor,0)}}if(m.type!="notification"&&m.useCanvasControls==true){this.drawControls(a,h,b)}if(MUI.Desktop&&this.contentWrapperEl.getChildren(".column").length!=0){MUI.rWidth(this.contentWrapperEl);this.contentWrapperEl.getChildren(".column").each(function(n){MUI.panelHeight(n)})}this.drawingWindow=false;return this},drawWindowCollapsed:function(b){var e=this.windowEl;var k=this.options;var c=k.shadowBlur;var f=c*2;var j=k.shadowOffset;var d=k.headerHeight+f+2;var g=d;var a=this.contentWrapperEl.getStyle("width").toInt()+f;this.windowEl.setStyle("height",g);this.overlayEl.setStyles({height:g,top:c-j.y,left:c-j.x});if(Browser.Engine.trident4){this.zIndexFixEl.setStyles({width:a,height:g})}this.windowEl.setStyle("width",a);this.overlayEl.setStyle("width",a);this.titleBarEl.setStyles({width:a-f,height:k.headerHeight});if(this.options.useCanvas!=false){this.canvasEl.height=g;this.canvasEl.width=a;var h=this.canvasEl.getContext("2d");h.clearRect(0,0,a,g);this.drawBoxCollapsed(h,a,g,c,j,b);if(k.useCanvasControls==true){this.drawControls(a,g,b)}if(Browser.Engine.trident){MUI.triangle(h,0,0,10,10,k.resizableColor,0)}}this.drawingWindow=false;return this},drawControls:function(g,e,h){var f=this.options;var d=f.shadowBlur;var c=f.shadowOffset;var b=f.controlsOffset;this.controlsEl.setStyles({right:d+c.x+b.right,top:d-c.y+b.top});this.canvasControlsEl.setStyles({right:d+c.x+b.right,top:d-c.y+b.top});this.closebuttonX=f.closable?this.mochaControlsWidth-7:this.mochaControlsWidth+12;this.maximizebuttonX=this.closebuttonX-(f.maximizable?19:0);this.minimizebuttonX=this.maximizebuttonX-(f.minimizable?19:0);var a=this.canvasControlsEl.getContext("2d");a.clearRect(0,0,100,100);if(this.options.closable){this.closebutton(a,this.closebuttonX,7,f.closeBgColor,1,f.closeColor,1)}if(this.options.maximizable){this.maximizebutton(a,this.maximizebuttonX,7,f.maximizeBgColor,1,f.maximizeColor,1)}if(this.options.minimizable){this.minimizebutton(a,this.minimizebuttonX,7,f.minimizeBgColor,1,f.minimizeColor,1)}if(Browser.Engine.trident){MUI.circle(a,0,0,3,this.options.resizableColor,0)}},drawBox:function(h,a,g,c,j,b){var k=this.options;var f=c*2;var d=this.options.cornerRadius;if(b!=false){for(var e=0;e<=c;e++){MUI.roundedRect(h,j.x+e,j.y+e,a-(e*2)-j.x,g-(e*2)-j.y,d+(c-e),[0,0,0],e==c?0.29:0.065+(e*0.01))}}this.bodyRoundedRect(h,c-j.x,c-j.y,a-f,g-f,d,k.bodyBgColor);if(this.options.type!="notification"){this.topRoundedRect(h,c-j.x,c-j.y,a-f,k.headerHeight,d,k.headerStartColor,k.headerStopColor)}},drawBoxCollapsed:function(h,a,g,c,j,b){var k=this.options;var f=c*2;var d=k.cornerRadius;if(b!=false){for(var e=0;e<=c;e++){MUI.roundedRect(h,j.x+e,j.y+e,a-(e*2)-j.x,g-(e*2)-j.y,d+(c-e),[0,0,0],e==c?0.3:0.06+(e*0.01))}}this.topRoundedRect2(h,c-j.x,c-j.y,a-f,k.headerHeight+2,d,k.headerStartColor,k.headerStopColor)},drawGauge:function(g,a,f,c,h,b){var j=this.options;var d=(a*0.5)-(c)+16;if(b!=false){for(var e=0;e<=c;e++){MUI.circle(g,a*0.5+h.x,(f+j.headerHeight)*0.5+h.x,(a*0.5)-(e*2)-h.x,[0,0,0],e==c?0.75:0.075+(e*0.04))}}MUI.circle(g,a*0.5-h.x,(f+j.headerHeight)*0.5-h.y,(a*0.5)-c,j.bodyBgColor,1);this.canvasHeaderEl.setStyles({top:c-h.y,left:c-h.x});var g=this.canvasHeaderEl.getContext("2d");g.clearRect(0,0,a,100);g.beginPath();g.lineWidth=24;g.lineCap="round";g.moveTo(13,13);g.lineTo(a-(c*2)-13,13);g.strokeStyle="rgba(0, 0, 0, .65)";g.stroke()},bodyRoundedRect:function(d,c,g,f,b,a,e){d.fillStyle="rgba("+e.join(",")+", 1)";d.beginPath();d.moveTo(c,g+a);d.lineTo(c,g+b-a);d.quadraticCurveTo(c,g+b,c+a,g+b);d.lineTo(c+f-a,g+b);d.quadraticCurveTo(c+f,g+b,c+f,g+b-a);d.lineTo(c+f,g+a);d.quadraticCurveTo(c+f,g,c+f-a,g);d.lineTo(c+a,g);d.quadraticCurveTo(c,g,c,g+a);d.fill()},topRoundedRect:function(j,g,f,a,h,e,c,d){var b=j.createLinearGradient(0,0,0,h);b.addColorStop(0,"rgb("+c.join(",")+")");b.addColorStop(1,"rgb("+d.join(",")+")");j.fillStyle=b;j.beginPath();j.moveTo(g,f);j.lineTo(g,f+h);j.lineTo(g+a,f+h);j.lineTo(g+a,f+e);j.quadraticCurveTo(g+a,f,g+a-e,f);j.lineTo(g+e,f);j.quadraticCurveTo(g,f,g,f+e);j.fill()},topRoundedRect2:function(j,g,f,a,h,e,c,d){if(navigator.userAgent.toLowerCase().indexOf("chrome")>-1){j.fillStyle="rgba("+d.join(",")+", 1)"}else{var b=j.createLinearGradient(0,this.options.shadowBlur-1,0,h+this.options.shadowBlur+3);b.addColorStop(0,"rgb("+c.join(",")+")");b.addColorStop(1,"rgb("+d.join(",")+")");j.fillStyle=b}j.beginPath();j.moveTo(g,f+e);j.lineTo(g,f+h-e);j.quadraticCurveTo(g,f+h,g+e,f+h);j.lineTo(g+a-e,f+h);j.quadraticCurveTo(g+a,f+h,g+a,f+h-e);j.lineTo(g+a,f+e);j.quadraticCurveTo(g+a,f,g+a-e,f);j.lineTo(g+e,f);j.quadraticCurveTo(g,f,g,f+e);j.fill()},maximizebutton:function(e,c,h,b,g,f,d){e.beginPath();e.arc(c,h,7,0,Math.PI*2,true);e.fillStyle="rgba("+b.join(",")+","+g+")";e.fill();e.strokeStyle="rgba("+f.join(",")+","+d+")";e.lineWidth=2;e.beginPath();e.moveTo(c,h-3.5);e.lineTo(c,h+3.5);e.moveTo(c-3.5,h);e.lineTo(c+3.5,h);e.stroke()},closebutton:function(e,c,h,b,g,f,d){e.beginPath();e.arc(c,h,7,0,Math.PI*2,true);e.fillStyle="rgba("+b.join(",")+","+g+")";e.fill();e.strokeStyle="rgba("+f.join(",")+","+d+")";e.lineWidth=2;e.beginPath();e.moveTo(c-3,h-3);e.lineTo(c+3,h+3);e.moveTo(c+3,h-3);e.lineTo(c-3,h+3);e.stroke()},minimizebutton:function(e,c,h,b,g,f,d){e.beginPath();e.arc(c,h,7,0,Math.PI*2,true);e.fillStyle="rgba("+b.join(",")+","+g+")";e.fill();e.strokeStyle="rgba("+f.join(",")+","+d+")";e.lineWidth=2;e.beginPath();e.moveTo(c-3.5,h);e.lineTo(c+3.5,h);e.stroke()},setMochaControlsWidth:function(){this.mochaControlsWidth=0;var a=this.options;if(a.minimizable){this.mochaControlsWidth+=(this.minimizeButtonEl.getStyle("margin-left").toInt()+this.minimizeButtonEl.getStyle("width").toInt())}if(a.maximizable){this.mochaControlsWidth+=(this.maximizeButtonEl.getStyle("margin-left").toInt()+this.maximizeButtonEl.getStyle("width").toInt())}if(a.closable){this.mochaControlsWidth+=(this.closeButtonEl.getStyle("margin-left").toInt()+this.closeButtonEl.getStyle("width").toInt())}this.controlsEl.setStyle("width",this.mochaControlsWidth);if(a.useCanvasControls==true){this.canvasControlsEl.setProperty("width",this.mochaControlsWidth)}},hideSpinner:function(){if(this.spinnerEl){this.spinnerEl.hide()}return this},showSpinner:function(){if(this.spinnerEl){this.spinnerEl.show()}return this},close:function(){if(!this.isClosing){MUI.closeWindow(this.windowEl)}return this},minimize:function(){MUI.Dock.minimizeWindow(this.windowEl);return this},maximize:function(){if(this.isMinimized){MUI.Dock.restoreMinimized(this.windowEl)}MUI.Desktop.maximizeWindow(this.windowEl);return this},restore:function(){if(this.isMinimized){MUI.Dock.restoreMinimized(this.windowEl)}else{if(this.isMaximized){MUI.Desktop.restoreWindow(this.windowEl)}}return this},resize:function(a){MUI.resizeWindow(this.windowEl,a);return this},center:function(){MUI.centerWindow(this.windowEl);return this},hide:function(){this.windowEl.setStyle("display","none");return this},show:function(){this.windowEl.setStyle("display","block");return this}});MUI.extend({closeWindow:function(c){var a=c.retrieve("instance");if(c!=$(c)||a.isClosing){return}a.isClosing=true;a.fireEvent("onClose",c);if(a.options.storeOnClose){this.storeOnClose(a,c);return}if(a.check){a.check.destroy()}if((a.options.type=="modal"||a.options.type=="modal2")&&Browser.Engine.trident4){$("modalFix").hide()}if(MUI.options.advancedEffects==false){if(a.options.type=="modal"||a.options.type=="modal2"){$("modalOverlay").setStyle("opacity",0)}MUI.closingJobs(c);return true}else{if(Browser.Engine.trident){a.drawWindow(false)}if(a.options.type=="modal"||a.options.type=="modal2"){MUI.Modal.modalOverlayCloseMorph.start({opacity:0})}var b=new Fx.Morph(c,{duration:120,onComplete:function(){MUI.closingJobs(c);return true}.bind(this)});b.start({opacity:0.4})}},closingJobs:function(e){var d=MUI.Windows.instances;var a=d.get(e.id);e.setStyle("visibility","hidden");if(Browser.Engine.trident){e.dispose()}else{e.destroy()}a.fireEvent("onCloseComplete");if(a.options.type!="notification"){var c=this.getWindowWithHighestZindex();this.focusWindow(c)}d.erase(a.options.id);if(this.loadingWorkspace==true){this.windowUnload()}if(MUI.Dock&&$(MUI.options.dock)&&a.options.type=="window"){var b=$(a.options.id+"_dockTab");if(b!=null){MUI.Dock.dockSortables.removeItems(b).destroy()}MUI.Desktop.setDesktopSize()}},storeOnClose:function(a,d){if(a.check){a.check.hide()}d.setStyles({zIndex:-1});d.addClass("windowClosed");d.removeClass("mocha");if(MUI.Dock&&$(MUI.options.dock)&&a.options.type=="window"){var c=$(a.options.id+"_dockTab");if(c!=null){c.hide()}MUI.Desktop.setDesktopSize()}a.fireEvent("onCloseComplete");if(a.options.type!="notification"){var b=this.getWindowWithHighestZindex();this.focusWindow(b)}a.isClosing=false},closeAll:function(){$$(".mocha").each(function(a){this.closeWindow(a)}.bind(this))},collapseToggle:function(c){var a=c.retrieve("instance");var b=c.getElements(".handle");if(a.isMaximized==true){return}if(a.isCollapsed==false){a.isCollapsed=true;b.hide();if(a.iframeEl){a.iframeEl.setStyle("visibility","hidden")}a.contentBorderEl.setStyles({visibility:"hidden",position:"absolute",top:-10000,left:-10000});if(a.toolbarWrapperEl){a.toolbarWrapperEl.setStyles({visibility:"hidden",position:"absolute",top:-10000,left:-10000})}a.drawWindowCollapsed()}else{a.isCollapsed=false;a.drawWindow();a.contentBorderEl.setStyles({visibility:"visible",position:null,top:null,left:null});if(a.toolbarWrapperEl){a.toolbarWrapperEl.setStyles({visibility:"visible",position:null,top:null,left:null})}if(a.iframeEl){a.iframeEl.setStyle("visibility","visible")}b.show()}},toggleWindowVisibility:function(){MUI.Windows.instances.each(function(a){if(a.options.type=="modal"||a.options.type=="modal2"||a.isMinimized==true){return}var b=$(a.options.id);if(b.getStyle("visibility")=="visible"){if(a.iframe){a.iframeEl.setStyle("visibility","hidden")}if(a.toolbarEl){a.toolbarWrapperEl.setStyle("visibility","hidden")}a.contentBorderEl.setStyle("visibility","hidden");b.setStyle("visibility","hidden");MUI.Windows.windowsVisible=false}else{b.setStyle("visibility","visible");a.contentBorderEl.setStyle("visibility","visible");if(a.iframe){a.iframeEl.setStyle("visibility","visible")}if(a.toolbarEl){a.toolbarWrapperEl.setStyle("visibility","visible")}MUI.Windows.windowsVisible=true}}.bind(this))},focusWindow:function(e,c){MUI.Windows.focusingWindow=true;var b=function(){MUI.Windows.focusingWindow=false};b.delay(170,this);if($$(".mocha").length==0){return}if(e!=$(e)||e.hasClass("isFocused")){return}var d=MUI.Windows.instances;var a=d.get(e.id);if(a.options.type=="notification"){e.setStyle("zIndex",11001);return}MUI.Windows.indexLevel+=2;e.setStyle("zIndex",MUI.Windows.indexLevel);$("windowUnderlay").setStyle("zIndex",MUI.Windows.indexLevel-1).inject($(e),"after");d.each(function(f){if(f.windowEl.hasClass("isFocused")){f.fireEvent("onBlur",f.windowEl)}f.windowEl.removeClass("isFocused")});if(MUI.Dock&&$(MUI.options.dock)&&a.options.type=="window"){MUI.Dock.makeActiveTab()}e.addClass("isFocused");if(c!=false){a.fireEvent("onFocus",e)}},getWindowWithHighestZindex:function(){this.highestZindex=0;$$(".mocha").each(function(a){this.zIndex=a.getStyle("zIndex");if(this.zIndex>=this.highestZindex){this.highestZindex=this.zIndex}}.bind(this));$$(".mocha").each(function(a){if(a.getStyle("zIndex")==this.highestZindex){this.windowWithHighestZindex=a}}.bind(this));return this.windowWithHighestZindex},blurAll:function(){if(MUI.Windows.focusingWindow==false){$$(".mocha").each(function(b){var a=b.retrieve("instance");if(a.options.type!="modal"&&a.options.type!="modal2"){b.removeClass("isFocused")}});$$(".dockTab").removeClass("activeDockTab")}},centerWindow:function(f){if(!f){MUI.Windows.instances.each(function(g){if(g.windowEl.hasClass("isFocused")){f=g.windowEl}})}var a=f.retrieve("instance");var b=a.options;var d=b.container.getCoordinates();var c=window.getScroll().y+(window.getSize().y*0.5)-(f.offsetHeight*0.5);if(c<-a.options.shadowBlur){c=-a.options.shadowBlur}var e=(d.width*0.5)-(f.offsetWidth*0.5);if(e<-a.options.shadowBlur){e=-a.options.shadowBlur}if(MUI.options.advancedEffects==true){a.morph.start({top:c,left:e})}else{f.setStyles({top:c,left:e})}},resizeWindow:function(f,j){var g=f.retrieve("instance");$extend({width:null,height:null,top:null,left:null,centered:true},j);var c=f.getStyle("width").toInt();var h=f.getStyle("height").toInt();var d=f.getStyle("top").toInt();var b=f.getStyle("left").toInt();if(j.centered){var e=j.top||d-((j.height-h)*0.5);var a=j.left||b-((j.width-c)*0.5)}else{var e=j.top||d;var a=j.left||b}if(MUI.options.advancedEffects==false){f.setStyles({top:e,left:a});g.contentWrapperEl.setStyles({height:j.height,width:j.width});g.drawWindow();if(g.iframeEl){if(!Browser.Engine.trident){g.iframeEl.setStyle("visibility","visible")}else{g.iframeEl.show()}}}else{f.retrieve("resizeMorph").start({"0":{height:j.height,width:j.width},"1":{top:e,left:a}})}return g},dynamicResize:function(d){var a=d.retrieve("instance");var c=a.contentWrapperEl;var b=a.contentEl;c.setStyles({height:b.offsetHeight,width:b.offsetWidth});a.drawWindow()}});document.addEvent("keydown",function(a){if(a.key=="q"&&a.control&&a.alt){MUI.toggleWindowVisibility()}});MUI.files[MUI.path.source+"Window/Modal.js"]="loaded";MUI.Modal=new Class({Extends:MUI.Window,options:{type:"modal"},initialize:function(a){if(!$("modalOverlay")){this.modalInitialize();window.addEvent("resize",function(){this.setModalSize()}.bind(this))}this.parent(a)},modalInitialize:function(){var a=new Element("div",{id:"modalOverlay",styles:{height:document.getCoordinates().height,opacity:0.6}}).inject(document.body);a.setStyles({position:Browser.Engine.trident4?"absolute":"fixed"});a.addEvent("click",function(d){var c=MUI.Windows.instances.get(MUI.currentModal.id);if(c.options.modalOverlayClose==true){MUI.closeWindow(MUI.currentModal)}});if(Browser.Engine.trident4){var b=new Element("iframe",{id:"modalFix",scrolling:"no",marginWidth:0,marginHeight:0,src:"",styles:{height:document.getCoordinates().height}}).inject(document.body)}MUI.Modal.modalOverlayOpenMorph=new Fx.Morph($("modalOverlay"),{duration:150});MUI.Modal.modalOverlayCloseMorph=new Fx.Morph($("modalOverlay"),{duration:150,onComplete:function(){$("modalOverlay").hide();if(Browser.Engine.trident4){$("modalFix").hide()}}.bind(this)})},setModalSize:function(){$("modalOverlay").setStyle("height",document.getCoordinates().height);if(Browser.Engine.trident4){$("modalFix").setStyle("height",document.getCoordinates().height)}}});MUI.files[MUI.path.source+"Window/Windows-from-html.js"]="loaded";MUI.extend({NewWindowsFromHTML:function(){$$(".mocha").each(function(b){if(Browser.Engine.presto||Browser.Engine.trident5){b.hide()}var d=b.getElement("h3.mochaTitle");if(Browser.Engine.presto){b.show()}var c=b.getStyles("height","width");var a={id:b.getProperty("id"),height:c.height.toInt(),width:c.width.toInt(),x:b.getStyle("left").toInt(),y:b.getStyle("top").toInt()};if(d){a.title=d.innerHTML;d.destroy()}a.content=b.innerHTML;b.destroy();new MUI.Window(a,true)}.bind(this))}});MUI.files[MUI.path.source+"Window/Windows-from-json.js"]="loaded";MUI.extend({newWindowsFromJSON:function(newWindows){newWindows.each(function(options){var temp=new Hash(options);temp.each(function(value,key,hash){if($type(value)!="string"){return}if(value.substring(0,8)=="function"){eval("options."+key+" = "+value)}});new MUI.Window(options)})}});MUI.files[MUI.path.source+"Window/Arrange-cascade.js"]="loaded";MUI.extend({arrangeCascade:function(){var g=30;var a=20;var k=50;var c=40;var j=document.getCoordinates();var d=0;MUI.Windows.instances.each(function(l){if(!l.isMinimized&&l.options.draggable){d++}});if((k*(d+1))>=(j.height-g)){var e=(j.height-g)/(d+1)}else{var e=k}if((c*(d+1))>=(j.width-a-20)){var b=(j.width-a-20)/(d+1)}else{var b=c}var h=a;var f=g;$$(".mocha").each(function(n){var l=n.retrieve("instance");if(!l.isMinimized&&!l.isMaximized&&l.options.draggable){id=n.id;MUI.focusWindow(n);h+=b;f+=e;if(MUI.options.advancedEffects==false){n.setStyles({top:f,left:h})}else{var m=new Fx.Morph(n,{duration:550});m.start({top:f,left:h})}}}.bind(this))}});MUI.files[MUI.path.source+"Window/Arrange-tile.js"]="loaded";MUI.extend({arrangeTile:function(){var g=30;var b=20;var j=10;var f=80;var a=MUI.Windows.instances;var l=0;a.each(function(o){if(!o.isMinimized&&!o.isMaximized){l++}});var h=3;var n=Math.ceil(l/h);var k=document.getCoordinates();var e=((k.width-b)/h);var d=((k.height-g)/n);var m=0;var c=0;a.each(function(x){if(!x.isMinimized&&!x.isMaximized&&x.options.draggable){var t=x.contentWrapperEl;var o=t.getCoordinates();var w=x.windowEl.getCoordinates();var s=o.top-w.top;var v=w.height-o.height-s;var r=o.left-w.left;var y=w.width-o.width-r;var p=(j+(c*e));var u=(f+(m*d));x.drawWindow();MUI.focusWindow(x.windowEl);if(MUI.options.advancedEffects==false){x.windowEl.setStyles({top:u,left:p})}else{var q=new Fx.Morph(x.windowEl,{duration:550});q.start({top:u,left:p})}if(++c===h){m++;c=0}}}.bind(this))}});MUI.files[MUI.path.source+"Components/Tabs.js"]="loaded";MUI.extend({initializeTabs:function(a){$(a).setStyle("list-style","none");$(a).getElements("li").addEvent("click",function(b){MUI.selected(this,a)})},selected:function(b,a){$(a).getChildren().each(function(c){c.removeClass("selected")});b.addClass("selected")}});MUI.files[MUI.path.source+"Layout/Layout.js"]="loaded";MUI.extend({Columns:{instances:new Hash(),columnIDCount:0},Panels:{instances:new Hash(),panelIDCount:0}});MUI.Desktop={options:{desktop:"desktop",desktopHeader:"desktopHeader",desktopFooter:"desktopFooter",desktopNavBar:"desktopNavbar",pageWrapper:"pageWrapper",page:"page",desktopFooter:"desktopFooterWrapper"},initialize:function(){this.desktop=$(this.options.desktop);this.desktopHeader=$(this.options.desktopHeader);this.desktopNavBar=$(this.options.desktopNavBar);this.pageWrapper=$(this.options.pageWrapper);this.page=$(this.options.page);this.desktopFooter=$(this.options.desktopFooter);if(this.desktop){($$("body")).setStyles({overflow:"hidden",height:"100%",margin:0});($$("html")).setStyles({overflow:"hidden",height:"100%"})}if(!MUI.Dock){this.setDesktopSize()}this.menuInitialize();window.addEvent("resize",function(a){this.onBrowserResize()}.bind(this));if(MUI.myChain){MUI.myChain.callChain()}},menuInitialize:function(){if(Browser.Engine.trident4&&this.desktopNavBar){this.desktopNavBar.getElements("li").each(function(a){a.addEvent("mouseenter",function(){this.addClass("ieHover")});a.addEvent("mouseleave",function(){this.removeClass("ieHover")})})}},onBrowserResize:function(){this.setDesktopSize();setTimeout(function(){MUI.Windows.instances.each(function(a){if(a.isMaximized){if(a.iframeEl){a.iframeEl.setStyle("visibility","hidden")}var d=document.getCoordinates();var b=a.contentBorderEl.getStyle("border-top").toInt()+a.contentBorderEl.getStyle("border-bottom").toInt();var c=a.toolbarWrapperEl?a.toolbarWrapperEl.getStyle("height").toInt()+a.toolbarWrapperEl.getStyle("border-top").toInt():0;a.contentWrapperEl.setStyles({height:d.height-a.options.headerHeight-a.options.footerHeight-b-c,width:d.width});a.drawWindow();if(a.iframeEl){a.iframeEl.setStyles({height:a.contentWrapperEl.getStyle("height")});a.iframeEl.setStyle("visibility","visible")}}}.bind(this))}.bind(this),100)},setDesktopSize:function(){var d=window.getCoordinates();var b=$(MUI.options.dockWrapper);if(this.desktop){this.desktop.setStyle("height",d.height)}if(this.pageWrapper){var a=MUI.dockVisible?b.offsetHeight:0;var c=d.height;c-=this.pageWrapper.getStyle("border-top").toInt();c-=this.pageWrapper.getStyle("border-bottom").toInt();if(this.desktopHeader){c-=this.desktopHeader.offsetHeight}if(this.desktopFooter){c-=this.desktopFooter.offsetHeight}c-=a;if(c<0){c=0}this.pageWrapper.setStyle("height",c)}if(MUI.Columns.instances.getKeys().length>0){MUI.Desktop.resizePanels()}},resizePanels:function(){MUI.panelHeight();MUI.rWidth()},maximizeWindow:function(f){var g=MUI.Windows.instances.get(f.id);var j=g.options;var c=g.windowDrag;if(f!=$(f)||g.isMaximized){return}if(g.isCollapsed){MUI.collapseToggle(f)}g.isMaximized=true;if(g.options.restrict){c.detach();if(j.resizable){g.detachResizable()}g.titleBarEl.setStyle("cursor","default")}if(j.container!=this.desktop){this.desktop.grab(f);if(this.options.restrict){c.container=this.desktop}}g.oldTop=f.getStyle("top");g.oldLeft=f.getStyle("left");var d=g.contentWrapperEl;d.oldWidth=d.getStyle("width");d.oldHeight=d.getStyle("height");if(g.iframeEl){if(!Browser.Engine.trident){g.iframeEl.setStyle("visibility","hidden")}else{g.iframeEl.hide()}}var b=document.getCoordinates();var j=g.options;var e=j.shadowBlur;var h=j.shadowOffset;var a=b.height-j.headerHeight-j.footerHeight;a-=g.contentBorderEl.getStyle("border-top").toInt();a-=g.contentBorderEl.getStyle("border-bottom").toInt();a-=(g.toolbarWrapperEl?g.toolbarWrapperEl.getStyle("height").toInt()+g.toolbarWrapperEl.getStyle("border-top").toInt():0);MUI.resizeWindow(f,{width:b.width,height:a,top:h.y-e,left:h.x-e});g.fireEvent("onMaximize",f);if(g.maximizeButtonEl){g.maximizeButtonEl.setProperty("title","Restore")}MUI.focusWindow(f)},restoreWindow:function(d){var a=d.retrieve("instance");if(d!=$(d)||!a.isMaximized){return}var b=a.options;a.isMaximized=false;if(b.restrict){a.windowDrag.attach();if(b.resizable){a.reattachResizable()}a.titleBarEl.setStyle("cursor","move")}if(a.iframeEl){if(!Browser.Engine.trident){a.iframeEl.setStyle("visibility","hidden")}else{a.iframeEl.hide()}}var c=a.contentWrapperEl;MUI.resizeWindow(d,{width:c.oldWidth,height:c.oldHeight,top:a.oldTop,left:a.oldLeft});a.fireEvent("onRestore",d);if(a.maximizeButtonEl){a.maximizeButtonEl.setProperty("title","Maximize")}}};MUI.Column=new Class({Implements:[Events,Options],options:{id:null,container:null,placement:null,width:null,resizeLimit:[],sortable:true,onResize:$empty,onCollapse:$empty,onExpand:$empty},initialize:function(b){this.setOptions(b);$extend(this,{timestamp:$time(),isCollapsed:false,oldWidth:0});if(this.options.id==null){this.options.id="column"+(++MUI.Columns.columnIDCount)}var b=this.options;var g=MUI.Columns.instances;var d=g.get(b.id);if(b.container==null){b.container=MUI.Desktop.pageWrapper}else{$(b.container).setStyle("overflow","hidden")}if(typeof this.options.container=="string"){this.options.container=$(this.options.container)}if(d){var a=d}if(this.columnEl){return}else{g.set(b.id,this)}if($(b.container).getElement(".pad")!=null){$(b.container).getElement(".pad").hide()}if($(b.container).getElement(".mochaContent")!=null){$(b.container).getElement(".mochaContent").hide()}this.columnEl=new Element("div",{id:this.options.id,"class":"column expanded",styles:{width:b.placement=="main"?null:b.width}}).inject($(b.container));this.columnEl.store("instance",this);var c=this.columnEl.getParent();var f=c.getStyle("height").toInt();this.columnEl.setStyle("height",f);if(this.options.sortable){if(!this.options.container.retrieve("sortables")){var e=new Sortables(this.columnEl,{opacity:1,handle:".panel-header",constrain:false,revert:false,onSort:function(){$$(".column").each(function(h){h.getChildren(".panelWrapper").each(function(j){j.getElement(".panel").removeClass("bottomPanel")});if(h.getChildren(".panelWrapper").getLast()){h.getChildren(".panelWrapper").getLast().getElement(".panel").addClass("bottomPanel")}MUI.panelHeight()}.bind(this))}.bind(this)});this.options.container.store("sortables",e)}else{this.options.container.retrieve("sortables").addLists(this.columnEl)}}if(b.placement=="main"){this.columnEl.addClass("rWidth")}switch(this.options.placement){case"left":this.handleEl=new Element("div",{id:this.options.id+"_handle","class":"columnHandle"}).inject(this.columnEl,"after");this.handleIconEl=new Element("div",{id:b.id+"_handle_icon","class":"handleIcon"}).inject(this.handleEl);addResizeRight(this.columnEl,b.resizeLimit[0],b.resizeLimit[1]);break;case"right":this.handleEl=new Element("div",{id:this.options.id+"_handle","class":"columnHandle"}).inject(this.columnEl,"before");this.handleIconEl=new Element("div",{id:b.id+"_handle_icon","class":"handleIcon"}).inject(this.handleEl);addResizeLeft(this.columnEl,b.resizeLimit[0],b.resizeLimit[1]);break}if(this.handleEl!=null){this.handleEl.addEvent("dblclick",function(){this.columnToggle()}.bind(this))}MUI.rWidth()},columnToggle:function(){var a=this.columnEl;if(this.isCollapsed==false){this.oldWidth=a.getStyle("width").toInt();this.resize.detach();this.handleEl.removeEvents("dblclick");this.handleEl.addEvent("click",function(){this.columnToggle()}.bind(this));this.handleEl.setStyle("cursor","pointer").addClass("detached");a.setStyle("width",0);this.isCollapsed=true;a.addClass("collapsed");a.removeClass("expanded");MUI.rWidth();this.fireEvent("onCollapse")}else{a.setStyle("width",this.oldWidth);this.isCollapsed=false;a.addClass("expanded");a.removeClass("collapsed");this.handleEl.removeEvents("click");this.handleEl.addEvent("dblclick",function(){this.columnToggle()}.bind(this));this.resize.attach();this.handleEl.setStyle("cursor",Browser.Engine.webkit?"col-resize":"e-resize").addClass("attached");MUI.rWidth();this.fireEvent("onExpand")}}});MUI.Column.implement(new Options,new Events);MUI.Panel=new Class({Implements:[Events,Options],options:{id:null,title:"New Panel",column:null,require:{css:[],images:[],js:[],onload:null},loadMethod:null,contentURL:null,method:"get",data:null,evalScripts:true,evalResponse:false,content:"Panel content",tabsURL:null,tabsData:null,tabsOnload:$empty,header:true,headerToolbox:false,headerToolboxURL:"pages/lipsum.html",headerToolboxOnload:$empty,height:125,addClass:"",scrollbars:true,padding:{top:8,right:8,bottom:8,left:8},collapsible:true,onBeforeBuild:$empty,onContentLoaded:$empty,onResize:$empty,onCollapse:$empty,onExpand:$empty},initialize:function(b){this.setOptions(b);$extend(this,{timestamp:$time(),isCollapsed:false,oldHeight:0,partner:null});if(this.options.id==null){this.options.id="panel"+(++MUI.Panels.panelIDCount)}var f=MUI.Panels.instances;var c=f.get(this.options.id);var b=this.options;if(c){var a=c}if(this.panelEl){return}else{f.set(this.options.id,this)}this.fireEvent("onBeforeBuild");if(b.loadMethod=="iframe"){b.padding={top:0,right:0,bottom:0,left:0}}this.showHandle=true;if($(b.column).getChildren().length==0){this.showHandle=false}this.panelWrapperEl=new Element("div",{id:this.options.id+"_wrapper","class":"panelWrapper expanded"}).inject($(b.column));this.panelEl=new Element("div",{id:this.options.id,"class":"panel expanded",styles:{height:b.height}}).inject(this.panelWrapperEl);this.panelEl.store("instance",this);this.panelEl.addClass(b.addClass);this.contentEl=new Element("div",{id:b.id+"_pad","class":"pad"}).inject(this.panelEl);this.contentWrapperEl=this.panelEl;this.contentEl.setStyles({"padding-top":b.padding.top,"padding-bottom":b.padding.bottom,"padding-left":b.padding.left,"padding-right":b.padding.right});this.panelHeaderEl=new Element("div",{id:this.options.id+"_header","class":"panel-header",styles:{display:b.header?"block":"none"}}).inject(this.panelEl,"before");var d=MUI.Columns.instances;var e=d.get(this.options.column);if(e.options.sortable){this.panelHeaderEl.setStyle("cursor","move");e.options.container.retrieve("sortables").addItems(this.panelWrapperEl)}if(this.options.collapsible){this.collapseToggleInit()}if(this.options.headerToolbox){this.panelHeaderToolboxEl=new Element("div",{id:b.id+"_headerToolbox","class":"panel-header-toolbox"}).inject(this.panelHeaderEl)}this.panelHeaderContentEl=new Element("div",{id:b.id+"_headerContent","class":"panel-headerContent"}).inject(this.panelHeaderEl);this.titleEl=new Element("h2",{id:b.id+"_title"}).inject(this.panelHeaderContentEl);this.handleEl=new Element("div",{id:b.id+"_handle","class":"horizontalHandle",styles:{display:this.showHandle==true?"block":"none"}}).inject(this.panelEl,"after");this.handleIconEl=new Element("div",{id:b.id+"_handle_icon","class":"handleIcon"}).inject(this.handleEl);addResizeBottom(b.id);if(b.require.css.length||b.require.images.length){new MUI.Require({css:b.require.css,images:b.require.images,onload:function(){this.newPanel()}.bind(this)})}else{this.newPanel()}},newPanel:function(){options=this.options;if(this.options.headerToolbox){MUI.updateContent({element:this.panelEl,childElement:this.panelHeaderToolboxEl,loadMethod:"xhr",url:options.headerToolboxURL,onContentLoaded:options.headerToolboxOnload})}if(options.tabsURL==null){this.titleEl.set("html",options.title)}else{this.panelHeaderContentEl.addClass("tabs");MUI.updateContent({element:this.panelEl,childElement:this.panelHeaderContentEl,loadMethod:"xhr",url:options.tabsURL,data:options.tabsData,onContentLoaded:options.tabsOnload})}MUI.updateContent({element:this.panelEl,content:options.content,method:options.method,data:options.data,url:options.contentURL,onContentLoaded:null,require:{js:options.require.js,onload:options.require.onload}});$(options.column).getChildren(".panelWrapper").each(function(a){a.getElement(".panel").removeClass("bottomPanel")});$(options.column).getChildren(".panelWrapper").getLast().getElement(".panel").addClass("bottomPanel");MUI.panelHeight(options.column,this.panelEl,"new")},collapseToggleInit:function(a){var a=this.options;this.panelHeaderCollapseBoxEl=new Element("div",{id:a.id+"_headerCollapseBox","class":"toolbox"}).inject(this.panelHeaderEl);if(a.headerToolbox){this.panelHeaderCollapseBoxEl.addClass("divider")}this.collapseToggleEl=new Element("div",{id:a.id+"_collapseToggle","class":"panel-collapse icon16",styles:{width:16,height:16},title:"Collapse Panel"}).inject(this.panelHeaderCollapseBoxEl);this.collapseToggleEl.addEvent("click",function(f){var b=this.panelEl;var c=this.panelWrapperEl;var g=MUI.Panels.instances;var e=[];c.getAllPrevious(".panelWrapper").each(function(j){var h=g.get(j.getElement(".panel").id);if(h.isCollapsed==false){e.push(j.getElement(".panel").id)}});c.getAllNext(".panelWrapper").each(function(j){var h=g.get(j.getElement(".panel").id);if(h.isCollapsed==false){e.push(j.getElement(".panel").id)}});if(this.isCollapsed==false){var d=MUI.Columns.instances.get($(a.column).id);if(e.length==0&&d.options.placement!="main"){var d=MUI.Columns.instances.get($(a.column).id);d.columnToggle();return}else{if(e.length==0&&d.options.placement=="main"){return}}this.oldHeight=b.getStyle("height").toInt();if(this.oldHeight<10){this.oldHeight=20}this.contentEl.setStyle("position","absolute");b.setStyle("height",0);this.isCollapsed=true;c.addClass("collapsed");c.removeClass("expanded");MUI.panelHeight(a.column,b,"collapsing");MUI.panelHeight();this.collapseToggleEl.removeClass("panel-collapsed");this.collapseToggleEl.addClass("panel-expand");this.collapseToggleEl.setProperty("title","Expand Panel");this.fireEvent("onCollapse")}else{this.contentEl.setStyle("position",null);b.setStyle("height",this.oldHeight);this.isCollapsed=false;c.addClass("expanded");c.removeClass("collapsed");MUI.panelHeight(this.options.column,b,"expanding");MUI.panelHeight();this.collapseToggleEl.removeClass("panel-expand");this.collapseToggleEl.addClass("panel-collapsed");this.collapseToggleEl.setProperty("title","Collapse Panel");this.fireEvent("onExpand")}}.bind(this))}});MUI.Panel.implement(new Options,new Events);MUI.extend({panelHeight:function(a,c,b){if(a!=null){MUI.panelHeight2($(a),c,b)}else{$$(".column").each(function(d){MUI.panelHeight2(d)}.bind(this))}},panelHeight2:function(e,m,f){var b=MUI.Panels.instances;var j=e.getParent();var h=j.getStyle("height").toInt();if(Browser.Engine.trident4&&j==MUI.Desktop.pageWrapper){h-=1}e.setStyle("height",h);var g=[];e.getChildren(".panelWrapper").each(function(n){g.push(n.getElement(".panel"))}.bind(this));var k=[];e.getChildren(".expanded").each(function(n){k.push(n.getElement(".panel"))}.bind(this));var c=[];var d;var a=0;this.panelsTotalHeight=0;this.height=0;g.each(function(n){instance=b.get(n.id);if(n.getParent().hasClass("expanded")&&n.getParent().getNext(".expanded")){instance.partner=n.getParent().getNext(".expanded").getElement(".panel");instance.resize.attach();instance.handleEl.setStyles({display:"block",cursor:Browser.Engine.webkit?"row-resize":"n-resize"}).removeClass("detached")}else{instance.resize.detach();instance.handleEl.setStyles({display:"none",cursor:null}).addClass("detached")}if(n.getParent().getNext(".panelWrapper")==null){instance.handleEl.hide()}}.bind(this));e.getChildren().each(function(n){n.getChildren().each(function(p){if(p.hasClass("panel")){var o=b.get(p.id);anyNextSiblingsExpanded=function(q){var r;q.getParent().getAllNext(".panelWrapper").each(function(s){var t=b.get(s.getElement(".panel").id);if(t.isCollapsed==false){r=true}}.bind(this));return r}.bind(this);anyExpandingNextSiblingsExpanded=function(q){var r;m.getParent().getAllNext(".panelWrapper").each(function(s){var t=b.get(s.getElement(".panel").id);if(t.isCollapsed==false){r=true}}.bind(this));return r}.bind(this);anyNextContainsChanging=function(r){var q=[];r.getParent().getAllNext(".panelWrapper").each(function(t){q.push(t.getElement(".panel"))}.bind(this));var s=q.contains(m);return s}.bind(this);nextExpandedChanging=function(q){var r;if(q.getParent().getNext(".expanded")){if(q.getParent().getNext(".expanded").getElement(".panel")==m){r=true}}return r};if(f=="new"){if(!o.isCollapsed&&p!=m){c.push(p);this.panelsTotalHeight+=p.offsetHeight.toInt()}}else{if(f==null||f=="collapsing"){if(!o.isCollapsed&&(!anyNextContainsChanging(p)||!anyNextSiblingsExpanded(p))){c.push(p);this.panelsTotalHeight+=p.offsetHeight.toInt()}}else{if(f=="expanding"&&!o.isCollapsed&&p!=m){if(!anyNextContainsChanging(p)||(!anyExpandingNextSiblingsExpanded(p)&&nextExpandedChanging(p))){c.push(p);this.panelsTotalHeight+=p.offsetHeight.toInt()}}}}if(p.style.height){this.height+=p.getStyle("height").toInt()}}else{this.height+=p.offsetHeight.toInt()}}.bind(this))}.bind(this));var l=e.offsetHeight.toInt()-this.height;this.height=0;e.getChildren().each(function(n){this.height+=n.offsetHeight.toInt()}.bind(this));var l=e.offsetHeight.toInt()-this.height;c.each(function(n){var p=this.panelsTotalHeight/n.offsetHeight.toInt();var o=n.getStyle("height").toInt()+(l/p);if(o<1){o=0}n.setStyle("height",o)}.bind(this));this.height=0;e.getChildren().each(function(n){n.getChildren().each(function(o){this.height+=o.offsetHeight.toInt();if(o.hasClass("panel")&&o.getStyle("height").toInt()>a){d=o;a=o.getStyle("height").toInt()}}.bind(this))}.bind(this));var l=e.offsetHeight.toInt()-this.height;if(l!=0&&a>0){d.setStyle("height",d.getStyle("height").toInt()+l);if(d.getStyle("height")<1){d.setStyle("height",0)}}j.getChildren(".columnHandle").each(function(p){var o=p.getParent();if(o.getStyle("height").toInt()<1){return}var n=o.getStyle("height").toInt()-p.getStyle("border-top").toInt()-p.getStyle("border-bottom").toInt();if(Browser.Engine.trident4&&o==MUI.Desktop.pageWrapper){n-=1}p.setStyle("height",n)});k.each(function(n){MUI.resizeChildren(n)}.bind(this))},resizeChildren:function(b){var d=MUI.Panels.instances;var a=d.get(b.id);var c=a.contentWrapperEl;if(a.iframeEl){if(!Browser.Engine.trident){a.iframeEl.setStyles({height:c.getStyle("height"),width:c.offsetWidth-c.getStyle("border-left").toInt()-c.getStyle("border-right").toInt()})}else{a.iframeEl.setStyles({height:c.getStyle("height"),width:c.offsetWidth-c.getStyle("border-left").toInt()-c.getStyle("border-right").toInt()-1});a.iframeEl.setStyles({width:c.offsetWidth-c.getStyle("border-left").toInt()-c.getStyle("border-right").toInt()})}}},rWidth:function(a){if(a==null){var a=MUI.Desktop.desktop}a.getElements(".rWidth").each(function(e){var b=e.offsetWidth.toInt();b-=e.getStyle("border-left").toInt();b-=e.getStyle("border-right").toInt();var d=e.getParent();this.width=0;d.getChildren().each(function(g){if(g.hasClass("mocha")!=true){this.width+=g.offsetWidth.toInt()}}.bind(this));var c=d.offsetWidth.toInt()-this.width;var f=b+c;if(f<1){f=0}e.setStyle("width",f);e.getChildren(".panel").each(function(g){g.setStyle("width",f-g.getStyle("border-left").toInt()-g.getStyle("border-right").toInt());MUI.resizeChildren(g)}.bind(this))})}});function addResizeRight(d,c,b){if(!$(d)){return}d=$(d);var f=MUI.Columns.instances;var a=f.get(d.id);var e=d.getNext(".columnHandle");e.setStyle("cursor",Browser.Engine.webkit?"col-resize":"e-resize");if(!c){c=50}if(!b){b=250}if(Browser.Engine.trident){e.addEvents({mousedown:function(){e.setCapture()},mouseup:function(){e.releaseCapture()}})}a.resize=d.makeResizable({handle:e,modifiers:{x:"width",y:false},limit:{x:[c,b]},onStart:function(){d.getElements("iframe").setStyle("visibility","hidden");d.getNext(".column").getElements("iframe").setStyle("visibility","hidden")}.bind(this),onDrag:function(){if(Browser.Engine.gecko){$$(".panel").each(function(g){if(g.getElements(".mochaIframe").length==0){g.hide()}})}MUI.rWidth(d.getParent());if(Browser.Engine.gecko){$$(".panel").show()}if(Browser.Engine.trident4){d.getChildren().each(function(h){var g=$(d).getStyle("width").toInt();g-=h.getStyle("border-right").toInt();g-=h.getStyle("border-left").toInt();g-=h.getStyle("padding-right").toInt();g-=h.getStyle("padding-left").toInt();h.setStyle("width",g)}.bind(this))}}.bind(this),onComplete:function(){MUI.rWidth(d.getParent());d.getElements("iframe").setStyle("visibility","visible");d.getNext(".column").getElements("iframe").setStyle("visibility","visible");a.fireEvent("onResize")}.bind(this)})}function addResizeLeft(d,c,b){if(!$(d)){return}d=$(d);var g=MUI.Columns.instances;var a=g.get(d.id);var f=d.getPrevious(".columnHandle");f.setStyle("cursor",Browser.Engine.webkit?"col-resize":"e-resize");var e=d.getPrevious(".column");if(!c){c=50}if(!b){b=250}if(Browser.Engine.trident){f.addEvents({mousedown:function(){f.setCapture()},mouseup:function(){f.releaseCapture()}})}a.resize=d.makeResizable({handle:f,modifiers:{x:"width",y:false},invert:true,limit:{x:[c,b]},onStart:function(){$(d).getElements("iframe").setStyle("visibility","hidden");e.getElements("iframe").setStyle("visibility","hidden")}.bind(this),onDrag:function(){MUI.rWidth(d.getParent())}.bind(this),onComplete:function(){MUI.rWidth(d.getParent());$(d).getElements("iframe").setStyle("visibility","visible");e.getElements("iframe").setStyle("visibility","visible");a.fireEvent("onResize")}.bind(this)})}function addResizeBottom(b){if(!$(b)){return}var b=$(b);var d=MUI.Panels.instances;var a=d.get(b.id);var c=a.handleEl;c.setStyle("cursor",Browser.Engine.webkit?"row-resize":"n-resize");partner=a.partner;min=0;max=function(){return b.getStyle("height").toInt()+partner.getStyle("height").toInt()}.bind(this);if(Browser.Engine.trident){c.addEvents({mousedown:function(){c.setCapture()},mouseup:function(){c.releaseCapture()}})}a.resize=b.makeResizable({handle:c,modifiers:{x:false,y:"height"},limit:{y:[min,max]},invert:false,onBeforeStart:function(){partner=a.partner;this.originalHeight=b.getStyle("height").toInt();this.partnerOriginalHeight=partner.getStyle("height").toInt()}.bind(this),onStart:function(){if(a.iframeEl){if(!Browser.Engine.trident){a.iframeEl.setStyle("visibility","hidden");partner.getElements("iframe").setStyle("visibility","hidden")}else{a.iframeEl.hide();partner.getElements("iframe").hide()}}}.bind(this),onDrag:function(){partnerHeight=partnerOriginalHeight;partnerHeight+=(this.originalHeight-b.getStyle("height").toInt());partner.setStyle("height",partnerHeight);MUI.resizeChildren(b,b.getStyle("height").toInt());MUI.resizeChildren(partner,partnerHeight);b.getChildren(".column").each(function(e){MUI.panelHeight(e)});partner.getChildren(".column").each(function(e){MUI.panelHeight(e)})}.bind(this),onComplete:function(){partnerHeight=partnerOriginalHeight;partnerHeight+=(this.originalHeight-b.getStyle("height").toInt());partner.setStyle("height",partnerHeight);MUI.resizeChildren(b,b.getStyle("height").toInt());MUI.resizeChildren(partner,partnerHeight);b.getChildren(".column").each(function(f){MUI.panelHeight(f)});partner.getChildren(".column").each(function(f){MUI.panelHeight(f)});if(a.iframeEl){if(!Browser.Engine.trident){a.iframeEl.setStyle("visibility","visible");partner.getElements("iframe").setStyle("visibility","visible")}else{a.iframeEl.show();partner.getElements("iframe").show();var e=a.iframeEl.getStyle("width").toInt();a.iframeEl.setStyle("width",e-1);MUI.rWidth();a.iframeEl.setStyle("width",e)}}a.fireEvent("onResize")}.bind(this)})}MUI.extend({closeColumn:function(b){var d=MUI.Columns.instances;var a=d.get(b.id);if(b!=$(b)||a.isClosing){return}a.isClosing=true;if(a.options.sortable){a.container.retrieve("sortables").removeLists(this.columnEl)}var c=b.getChildren(".panel");c.each(function(e){MUI.closePanel($(e.id))}.bind(this));if(Browser.Engine.trident){b.dispose();if(a.handleEl!=null){a.handleEl.dispose()}}else{b.destroy();if(a.handleEl!=null){a.handleEl.destroy()}}if(MUI.Desktop){MUI.Desktop.resizePanels()}d.erase(a.options.id);return true},closePanel:function(f){var e=MUI.Panels.instances;var a=e.get(f.id);if(f!=$(f)||a.isClosing){return}var b=a.options.column;a.isClosing=true;var c=MUI.Columns.instances;var d=c.get(b);if(d.options.sortable){d.options.container.retrieve("sortables").removeItems(a.panelWrapperEl)}a.panelWrapperEl.destroy();if(MUI.Desktop){MUI.Desktop.resizePanels()}$(b).getChildren(".panelWrapper").each(function(g){g.getElement(".panel").removeClass("bottomPanel")});$(b).getChildren(".panelWrapper").getLast().getElement(".panel").addClass("bottomPanel");e.erase(a.options.id);return true}});MUI.files[MUI.path.source+"Layout/Dock.js"]="loaded";MUI.options.extend({dockWrapper:"dockWrapper",dock:"dock"});MUI.extend({minimizeAll:function(){$$(".mocha").each(function(b){var a=b.retrieve("instance");if(!a.isMinimized&&a.options.minimizable==true){MUI.Dock.minimizeWindow(b)}}.bind(this))}});MUI.Dock={options:{useControls:true,dockPosition:"bottom",trueButtonColor:[70,245,70],enabledButtonColor:[115,153,191],disabledButtonColor:[170,170,170]},initialize:function(a){if(!MUI.Desktop){return}MUI.dockVisible=true;this.dockWrapper=$(MUI.options.dockWrapper);this.dock=$(MUI.options.dock);this.autoHideEvent=null;this.dockAutoHide=false;if(!this.dockWrapper){return}if(!this.options.useControls){if($("dockPlacement")){$("dockPlacement").setStyle("cursor","default")}if($("dockAutoHide")){$("dockAutoHide").setStyle("cursor","default")}}this.dockWrapper.setStyles({display:"block",position:"absolute",top:null,bottom:MUI.Desktop.desktopFooter?MUI.Desktop.desktopFooter.offsetHeight:0,left:0});if(this.options.useControls){this.initializeDockControls()}if($("dockLinkCheck")){this.sidebarCheck=new Element("div",{"class":"check",id:"dock_check"}).inject($("dockLinkCheck"))}this.dockSortables=new Sortables("#dockSort",{opacity:1,constrain:true,clone:false,revert:false});MUI.Desktop.setDesktopSize();if(MUI.myChain){MUI.myChain.callChain()}},initializeDockControls:function(){this.setDockColors();if(this.options.useControls){var b=new Element("canvas",{id:"dockCanvas",width:"15",height:"18"}).inject(this.dock);if(Browser.Engine.trident&&MUI.ieSupport=="excanvas"){G_vmlCanvasManager.initElement(b)}}var a=$("dockPlacement");var c=$("dockAutoHide");a.setProperty("title","Position Dock Top");a.addEvent("click",function(){this.moveDock()}.bind(this));c.setProperty("title","Turn Auto Hide On");c.addEvent("click",function(e){if(this.dockWrapper.getProperty("dockPosition")=="top"){return false}var d=$("dockCanvas").getContext("2d");this.dockAutoHide=!this.dockAutoHide;if(this.dockAutoHide){$("dockAutoHide").setProperty("title","Turn Auto Hide Off");MUI.circle(d,5,14,3,this.options.trueButtonColor,1);this.autoHideEvent=function(g){if(!this.dockAutoHide){return}if(!MUI.Desktop.desktopFooter){var f=this.dockWrapper.offsetHeight;if(f<25){f=25}}else{if(MUI.Desktop.desktopFooter){var f=this.dockWrapper.offsetHeight+MUI.Desktop.desktopFooter.offsetHeight;if(f<25){f=25}}}if(!MUI.Desktop.desktopFooter&&g.client.y>(document.getCoordinates().height-f)){if(!MUI.dockVisible){this.dockWrapper.show();MUI.dockVisible=true;MUI.Desktop.setDesktopSize()}}else{if(MUI.Desktop.desktopFooter&&g.client.y>(document.getCoordinates().height-f)){if(!MUI.dockVisible){this.dockWrapper.show();MUI.dockVisible=true;MUI.Desktop.setDesktopSize()}}else{if(MUI.dockVisible){this.dockWrapper.hide();MUI.dockVisible=false;MUI.Desktop.setDesktopSize()}}}}.bind(this);document.addEvent("mousemove",this.autoHideEvent)}else{$("dockAutoHide").setProperty("title","Turn Auto Hide On");MUI.circle(d,5,14,3,this.options.enabledButtonColor,1);document.removeEvent("mousemove",this.autoHideEvent)}}.bind(this));this.renderDockControls();if(this.options.dockPosition=="top"){this.moveDock()}},setDockColors:function(){var c=MUI.getCSSRule(".dockButtonEnabled");if(c&&c.style.backgroundColor){this.options.enabledButtonColor=new Color(c.style.backgroundColor)}var a=MUI.getCSSRule(".dockButtonDisabled");if(a&&a.style.backgroundColor){this.options.disabledButtonColor=new Color(a.style.backgroundColor)}var b=MUI.getCSSRule(".dockButtonTrue");if(b&&b.style.backgroundColor){this.options.trueButtonColor=new Color(b.style.backgroundColor)}},renderDockControls:function(){var a=$("dockCanvas").getContext("2d");a.clearRect(0,0,100,100);MUI.circle(a,5,4,3,this.options.enabledButtonColor,1);if(this.dockWrapper.getProperty("dockPosition")=="top"){MUI.circle(a,5,14,3,this.options.disabledButtonColor,1)}else{if(this.dockAutoHide){MUI.circle(a,5,14,3,this.options.trueButtonColor,1)}else{MUI.circle(a,5,14,3,this.options.enabledButtonColor,1)}}},moveDock:function(){var a=$("dockCanvas").getContext("2d");if(this.dockWrapper.getStyle("position")!="relative"){this.dockWrapper.setStyles({position:"relative",bottom:null});this.dockWrapper.addClass("top");MUI.Desktop.setDesktopSize();this.dockWrapper.setProperty("dockPosition","top");a.clearRect(0,0,100,100);MUI.circle(a,5,4,3,this.options.enabledButtonColor,1);MUI.circle(a,5,14,3,this.options.disabledButtonColor,1);$("dockPlacement").setProperty("title","Position Dock Bottom");$("dockAutoHide").setProperty("title","Auto Hide Disabled in Top Dock Position");this.dockAutoHide=false}else{this.dockWrapper.setStyles({position:"absolute",bottom:MUI.Desktop.desktopFooter?MUI.Desktop.desktopFooter.offsetHeight:0});this.dockWrapper.removeClass("top");MUI.Desktop.setDesktopSize();this.dockWrapper.setProperty("dockPosition","bottom");a.clearRect(0,0,100,100);MUI.circle(a,5,4,3,this.options.enabledButtonColor,1);MUI.circle(a,5,14,3,this.options.enabledButtonColor,1);$("dockPlacement").setProperty("title","Position Dock Top");$("dockAutoHide").setProperty("title","Turn Auto Hide On")}},createDockTab:function(e){var a=e.retrieve("instance");var d=new Element("div",{id:a.options.id+"_dockTab","class":"dockTab",title:b}).inject($("dockClear"),"before");d.addEvent("mousedown",function(f){new Event(f).stop();this.timeDown=$time()});d.addEvent("mouseup",function(f){this.timeUp=$time();if((this.timeUp-this.timeDown)<275){if(MUI.Windows.windowsVisible==false){MUI.toggleWindowVisibility();if(a.isMinimized==true){MUI.Dock.restoreMinimized.delay(25,MUI.Dock,e)}else{MUI.focusWindow(e)}return}if(a.isMinimized==true){MUI.Dock.restoreMinimized.delay(25,MUI.Dock,e)}else{if(a.windowEl.hasClass("isFocused")&&a.options.minimizable==true){MUI.Dock.minimizeWindow(e)}else{MUI.focusWindow(e)}var g=document.getCoordinates();if(e.getStyle("left").toInt()>g.width||e.getStyle("top").toInt()>g.height){MUI.centerWindow(e)}}}});this.dockSortables.addItems(d);var b=a.titleEl.innerHTML;var c=new Element("div",{id:a.options.id+"_dockTabText","class":"dockText"}).set("html",b.substring(0,19)+(b.length>19?"...":"")).inject($(d));if(a.options.icon!=false){}MUI.Desktop.setDesktopSize()},makeActiveTab:function(){var c=MUI.getWindowWithHighestZindex();var a=c.retrieve("instance");$$(".dockTab").removeClass("activeDockTab");if(a.isMinimized!=true){a.windowEl.addClass("isFocused");var b=$(a.options.id+"_dockTab");if(b!=null){b.addClass("activeDockTab")}}else{a.windowEl.removeClass("isFocused")}},minimizeWindow:function(c){if(c!=$(c)){return}var a=c.retrieve("instance");a.isMinimized=true;if(a.iframeEl){if(!Browser.Engine.trident){a.iframeEl.setStyle("visibility","hidden")}else{a.iframeEl.hide()}}a.contentBorderEl.setStyle("visibility","hidden");if(a.toolbarWrapperEl){a.toolbarWrapperEl.hide()}c.setStyle("visibility","hidden");if(Browser.Platform.mac&&Browser.Engine.gecko){if(/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)){var b=new Number(RegExp.$1);if(b<3){a.contentWrapperEl.setStyle("overflow","hidden")}}}MUI.Desktop.setDesktopSize();setTimeout(function(){c.setStyle("zIndex",1);c.removeClass("isFocused");this.makeActiveTab()}.bind(this),100);a.fireEvent("onMinimize",c)},restoreMinimized:function(b){var a=b.retrieve("instance");if(a.isMinimized==false){return}if(MUI.Windows.windowsVisible==false){MUI.toggleWindowVisibility()}MUI.Desktop.setDesktopSize();if(a.options.scrollbars==true&&!a.iframeEl){a.contentWrapperEl.setStyle("overflow","auto")}if(a.isCollapsed){MUI.collapseToggle(b)}b.setStyle("visibility","visible");a.contentBorderEl.setStyle("visibility","visible");if(a.toolbarWrapperEl){a.toolbarWrapperEl.show()}if(a.iframeEl){if(!Browser.Engine.trident){a.iframeEl.setStyle("visibility","visible")}else{a.iframeEl.show()}}a.isMinimized=false;MUI.focusWindow(b);a.fireEvent("onRestore",b)}};MUI.files[MUI.path.source+"Layout/Workspaces.js"]="loaded";MUI.extend({saveWorkspace:function(){this.cookie=new Hash.Cookie("mochaUIworkspaceCookie",{duration:3600});this.cookie.empty();MUI.Windows.instances.each(function(a){a.saveValues();this.cookie.set(a.options.id,{id:a.options.id,top:a.options.y,left:a.options.x,width:a.contentWrapperEl.getStyle("width").toInt(),height:a.contentWrapperEl.getStyle("height").toInt()})}.bind(this));this.cookie.save();new MUI.Window({loadMethod:"html",type:"notification",addClass:"notification",content:"Workspace saved.",closeAfter:"1400",width:200,height:40,y:53,padding:{top:10,right:12,bottom:10,left:12},shadowBlur:5,bodyBgColor:[255,255,255]})},windowUnload:function(){if($$(".mocha").length==0&&this.myChain){this.myChain.callChain()}},loadWorkspace2:function(workspaceWindows){workspaceWindows.each(function(workspaceWindow){windowFunction=eval("MUI."+workspaceWindow.id+"Window");if(windowFunction){eval("MUI."+workspaceWindow.id+"Window({width:"+workspaceWindow.width+",height:"+workspaceWindow.height+"});");var windowEl=$(workspaceWindow.id);windowEl.setStyles({top:workspaceWindow.top,left:workspaceWindow.left});var instance=windowEl.retrieve("instance");instance.contentWrapperEl.setStyles({width:workspaceWindow.width,height:workspaceWindow.height});instance.drawWindow()}}.bind(this));this.loadingWorkspace=false},loadWorkspace:function(){cookie=new Hash.Cookie("mochaUIworkspaceCookie",{duration:3600});workspaceWindows=cookie.load();if(!cookie.getKeys().length){new MUI.Window({loadMethod:"html",type:"notification",addClass:"notification",content:"You have no saved workspace.",closeAfter:"1400",width:220,height:40,y:25,padding:{top:10,right:12,bottom:10,left:12},shadowBlur:5,bodyBgColor:[255,255,255]});return}if($$(".mocha").length!=0){this.loadingWorkspace=true;this.myChain=new Chain();this.myChain.chain(function(){$$(".mocha").each(function(a){this.closeWindow(a)}.bind(this))}.bind(this),function(){this.loadWorkspace2(workspaceWindows)}.bind(this));this.myChain.callChain()}else{this.loadWorkspace2(workspaceWindows)}}}); \ No newline at end of file diff --git a/src/webui/scripts/mocha.js b/src/webui/scripts/mocha.js new file mode 100644 index 000000000..1fbe3a0f1 --- /dev/null +++ b/src/webui/scripts/mocha.js @@ -0,0 +1,6279 @@ +/* + +Script: Core.js + MUI - A Web Applications User Interface Framework. + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Contributors: + - Scott F. Frederick + - Joel Lindau + +Note: + This documentation is taken directly from the javascript source files. It is built using Natural Docs. + +*/ + +var MUI = MochaUI = new Hash({ + + version: '0.9.6 development', + + options: new Hash({ + theme: 'default', + advancedEffects: false, // Effects that require fast browsers and are cpu intensive. + standardEffects: true // Basic effects that tend to run smoothly. + }), + + path: { + source: 'scripts/source/', // Path to MochaUI source JavaScript + themes: 'themes/', // Path to MochaUI Themes + plugins: 'plugins/' // Path to Plugins + }, + + // Returns the path to the current theme directory + themePath: function(){ + return MUI.path.themes + MUI.options.theme + '/'; + }, + + files: new Hash() + +}); + +MUI.files[MUI.path.source + 'Core/Core.js'] = 'loaded'; + +MUI.extend({ + + Windows: { + instances: new Hash() + }, + + ieSupport: 'excanvas', // Makes it easier to switch between Excanvas and Moocanvas for testing + + /* + + Function: updateContent + Replace the content of a window or panel. + + Arguments: + updateOptions - (object) + + updateOptions: + element - The parent window or panel. + childElement - The child element of the window or panel recieving the content. + method - ('get', or 'post') The way data is transmitted. + data - (hash) Data to be transmitted + title - (string) Change this if you want to change the title of the window or panel. + content - (string or element) An html loadMethod option. + loadMethod - ('html', 'xhr', or 'iframe') + url - Used if loadMethod is set to 'xhr' or 'iframe'. + scrollbars - (boolean) + padding - (object) + onContentLoaded - (function) + + */ + updateContent: function(options){ + + var options = $extend({ + element: null, + childElement: null, + method: null, + data: null, + title: null, + content: null, + loadMethod: null, + url: null, + scrollbars: null, + padding: null, + require: {}, + onContentLoaded: $empty + }, options); + + options.require = $extend({ + css: [], images: [], js: [], onload: null + }, options.require); + + var args = {}; + + if (!options.element) return; + var element = options.element; + + if (MUI.Windows.instances.get(element.id)){ + args.recipient = 'window'; + } + else { + args.recipient = 'panel'; + } + + var instance = element.retrieve('instance'); + if (options.title) instance.titleEl.set('html', options.title); + + var contentEl = instance.contentEl; + args.contentContainer = options.childElement != null ? options.childElement : instance.contentEl; + var contentWrapperEl = instance.contentWrapperEl; + + if (!options.loadMethod){ + if (!instance.options.loadMethod){ + if (!options.url){ + options.loadMethod = 'html'; + } + else { + options.loadMethod = 'xhr'; + } + } + else { + options.loadMethod = instance.options.loadMethod; + } + } + + // Set scrollbars if loading content in main content container. + // Always use 'hidden' for iframe windows + var scrollbars = options.scrollbars || instance.options.scrollbars; + if (args.contentContainer == instance.contentEl) { + contentWrapperEl.setStyles({ + 'overflow': scrollbars != false && options.loadMethod != 'iframe' ? 'auto' : 'hidden' + }); + } + + if (options.padding != null) { + contentEl.setStyles({ + 'padding-top': options.padding.top, + 'padding-bottom': options.padding.bottom, + 'padding-left': options.padding.left, + 'padding-right': options.padding.right + }); + } + + // Remove old content. + if (args.contentContainer == contentEl) { + contentEl.empty().show(); + // Panels are not loaded into the padding div, so we remove them separately. + contentEl.getAllNext('.column').destroy(); + contentEl.getAllNext('.columnHandle').destroy(); + } + + args.onContentLoaded = function(){ + + if (options.require.js.length || typeof options.require.onload == 'function'){ + new MUI.Require({ + js: options.require.js, + onload: function(){ + if (Browser.Engine.presto){ + options.require.onload.delay(100); + } + else { + options.require.onload(); + } + options.onContentLoaded ? options.onContentLoaded() : instance.fireEvent('onContentLoaded', element); + }.bind(this) + }); + } + else { + options.onContentLoaded ? options.onContentLoaded() : instance.fireEvent('onContentLoaded', element); + } + + }; + + if (options.require.css.length || options.require.images.length){ + new MUI.Require({ + css: options.require.css, + images: options.require.images, + onload: function(){ + this.loadSelect(instance, options, args); + }.bind(this) + }); + } + else { + this.loadSelect(instance, options, args); + } + }, + + loadSelect: function(instance, options, args){ + + // Load new content. + switch(options.loadMethod){ + case 'xhr': + this.updateContentXHR(instance, options, args); + break; + case 'iframe': + this.updateContentIframe(instance, options, args); + break; + case 'html': + default: + this.updateContentHTML(instance, options, args); + break; + } + + }, + + updateContentXHR: function(instance, options, args){ + var contentEl = instance.contentEl; + var contentContainer = args.contentContainer; + var onContentLoaded = args.onContentLoaded; + new Request.HTML({ + url: options.url, + update: contentContainer, + method: options.method != null ? options.method : 'get', + data: options.data != null ? new Hash(options.data).toQueryString() : '', + evalScripts: instance.options.evalScripts, + evalResponse: instance.options.evalResponse, + onRequest: function(){ + if (args.recipient == 'window' && contentContainer == contentEl){ + instance.showSpinner(); + } + else if (args.recipient == 'panel' && contentContainer == contentEl && $('spinner')){ + $('spinner').show(); + } + }.bind(this), + onFailure: function(response){ + if (contentContainer == contentEl){ + var getTitle = new RegExp("[\n\r\s]*(.*)[\n\r\s]*", "gmi"); + var error = getTitle.exec(response.responseText); + if (!error) error = 'Unknown'; + contentContainer.set('html', '

Error: ' + error[1] + '

'); + if (args.recipient == 'window'){ + instance.hideSpinner(); + } + else if (args.recipient == 'panel' && $('spinner')){ + $('spinner').hide(); + } + } + }.bind(this), + onSuccess: function(){ + if (contentContainer == contentEl){ + if (args.recipient == 'window') instance.hideSpinner(); + else if (args.recipient == 'panel' && $('spinner')) $('spinner').hide(); + } + Browser.Engine.trident4 ? onContentLoaded.delay(750) : onContentLoaded(); + }.bind(this), + onComplete: function(){}.bind(this) + }).send(); + }, + + updateContentIframe: function(instance, options, args){ + var contentEl = instance.contentEl; + var contentContainer = args.contentContainer; + var contentWrapperEl = instance.contentWrapperEl; + var onContentLoaded = args.onContentLoaded; + if ( instance.options.contentURL == '' || contentContainer != contentEl) { + return; + } + instance.iframeEl = new Element('iframe', { + 'id': instance.options.id + '_iframe', + 'name': instance.options.id + '_iframe', + 'class': 'mochaIframe', + 'src': options.url, + 'marginwidth': 0, + 'marginheight': 0, + 'frameBorder': 0, + 'scrolling': 'auto', + 'styles': { + 'height': contentWrapperEl.offsetHeight - contentWrapperEl.getStyle('border-top').toInt() - contentWrapperEl.getStyle('border-bottom').toInt(), + 'width': instance.panelEl ? contentWrapperEl.offsetWidth - contentWrapperEl.getStyle('border-left').toInt() - contentWrapperEl.getStyle('border-right').toInt() : '100%' + } + }).injectInside(contentEl); + + // Add onload event to iframe so we can hide the spinner and run onContentLoaded() + instance.iframeEl.addEvent('load', function(e) { + if (args.recipient == 'window') instance.hideSpinner(); + else if (args.recipient == 'panel' && contentContainer == contentEl && $('spinner')) $('spinner').hide(); + Browser.Engine.trident4 ? onContentLoaded.delay(50) : onContentLoaded(); + }.bind(this)); + if (args.recipient == 'window') instance.showSpinner(); + else if (args.recipient == 'panel' && contentContainer == contentEl && $('spinner')) $('spinner').show(); + }, + + updateContentHTML: function(instance, options, args){ + var contentEl = instance.contentEl; + var contentContainer = args.contentContainer; + var onContentLoaded = args.onContentLoaded; + var elementTypes = new Array('element', 'textnode', 'whitespace', 'collection'); + + if (elementTypes.contains($type(options.content))){ + options.content.inject(contentContainer); + } else { + contentContainer.set('html', options.content); + } + if (contentContainer == contentEl){ + if (args.recipient == 'window') instance.hideSpinner(); + else if (args.recipient == 'panel' && $('spinner')) $('spinner').hide(); + } + Browser.Engine.trident4 ? onContentLoaded.delay(50) : onContentLoaded(); + }, + + /* + + Function: reloadIframe + Reload an iframe. Fixes an issue in Firefox when trying to use location.reload on an iframe that has been destroyed and recreated. + + Arguments: + iframe - This should be both the name and the id of the iframe. + + Syntax: + (start code) + MUI.reloadIframe(element); + (end) + + Example: + To reload an iframe from within another iframe: + (start code) + parent.MUI.reloadIframe('myIframeName'); + (end) + + */ + reloadIframe: function(iframe){ + Browser.Engine.gecko ? $(iframe).src = $(iframe).src : top.frames[iframe].location.reload(true); + }, + + roundedRect: function(ctx, x, y, width, height, radius, rgb, a){ + ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')'; + ctx.beginPath(); + ctx.moveTo(x, y + radius); + ctx.lineTo(x, y + height - radius); + ctx.quadraticCurveTo(x, y + height, x + radius, y + height); + ctx.lineTo(x + width - radius, y + height); + ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius); + ctx.lineTo(x + width, y + radius); + ctx.quadraticCurveTo(x + width, y, x + width - radius, y); + ctx.lineTo(x + radius, y); + ctx.quadraticCurveTo(x, y, x, y + radius); + ctx.fill(); + }, + + triangle: function(ctx, x, y, width, height, rgb, a){ + ctx.beginPath(); + ctx.moveTo(x + width, y); + ctx.lineTo(x, y + height); + ctx.lineTo(x + width, y + height); + ctx.closePath(); + ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')'; + ctx.fill(); + }, + + circle: function(ctx, x, y, diameter, rgb, a){ + ctx.beginPath(); + ctx.arc(x, y, diameter, 0, Math.PI*2, true); + ctx.fillStyle = 'rgba(' + rgb.join(',') + ',' + a + ')'; + ctx.fill(); + }, + + notification: function(message){ + new MUI.Window({ + loadMethod: 'html', + closeAfter: 1500, + type: 'notification', + addClass: 'notification', + content: message, + width: 220, + height: 40, + y: 53, + padding: { top: 10, right: 12, bottom: 10, left: 12 }, + shadowBlur: 5 + }); + }, + + /* + + Function: toggleEffects + Turn effects on and off + + */ + toggleAdvancedEffects: function(link){ + if (MUI.options.advancedEffects == false) { + MUI.options.advancedEffects = true; + if (link){ + this.toggleAdvancedEffectsLink = new Element('div', { + 'class': 'check', + 'id': 'toggleAdvancedEffects_check' + }).inject(link); + } + } + else { + MUI.options.advancedEffects = false; + if (this.toggleAdvancedEffectsLink) { + this.toggleAdvancedEffectsLink.destroy(); + } + } + }, + /* + + Function: toggleStandardEffects + Turn standard effects on and off + + */ + toggleStandardEffects: function(link){ + if (MUI.options.standardEffects == false) { + MUI.options.standardEffects = true; + if (link){ + this.toggleStandardEffectsLink = new Element('div', { + 'class': 'check', + 'id': 'toggleStandardEffects_check' + }).inject(link); + } + } + else { + MUI.options.standardEffects = false; + if (this.toggleStandardEffectsLink) { + this.toggleStandardEffectsLink.destroy(); + } + } + }, + + /* + + The underlay is inserted directly under windows when they are being dragged or resized + so that the cursor is not captured by iframes or other plugins (such as Flash) + underneath the window. + + */ + underlayInitialize: function(){ + var windowUnderlay = new Element('div', { + 'id': 'windowUnderlay', + 'styles': { + 'height': parent.getCoordinates().height, + 'opacity': .01, + 'display': 'none' + } + }).inject(document.body); + }, + setUnderlaySize: function(){ + $('windowUnderlay').setStyle('height', parent.getCoordinates().height); + } +}); + +/* + +function: fixPNG + Bob Osola's PngFix for IE6. + +example: + (begin code) + foo + (end) + +note: + You must have the image height and width attributes specified in the markup. + +*/ + +function fixPNG(myImage){ + if (Browser.Engine.trident4 && document.body.filters){ + var imgID = (myImage.id) ? "id='" + myImage.id + "' " : ""; + var imgClass = (myImage.className) ? "class='" + myImage.className + "' " : ""; + var imgTitle = (myImage.title) ? "title='" + myImage.title + "' " : "title='" + myImage.alt + "' "; + var imgStyle = "display:inline-block;" + myImage.style.cssText; + var strNewHTML = ""; + myImage.outerHTML = strNewHTML; + } +} + +// Blur all windows if user clicks anywhere else on the page +document.addEvent('mousedown', function(event){ + MUI.blurAll.delay(50); +}); + +window.addEvent('domready', function(){ + MUI.underlayInitialize(); +}); + +window.addEvent('resize', function(){ + if ($('windowUnderlay')) { + MUI.setUnderlaySize(); + } + else { + MUI.underlayInitialize(); + } +}); + +Element.implement({ + hide: function(){ + this.setStyle('display', 'none'); + return this; + }, + show: function(){ + this.setStyle('display', 'block'); + return this; + } +}); + +/* + +Shake effect by Uvumi Tools +http://tools.uvumi.com/element-shake.html + +Function: shake + +Example: + Shake a window. + (start code) + $('parametrics').shake() + (end) + +*/ + +Element.implement({ + shake: function(radius,duration){ + radius = radius || 3; + duration = duration || 500; + duration = (duration/50).toInt() - 1; + var parent = this.getParent(); + if(parent != $(document.body) && parent.getStyle('position') == 'static'){ + parent.setStyle('position','relative'); + } + var position = this.getStyle('position'); + if(position == 'static'){ + this.setStyle('position','relative'); + position = 'relative'; + } + if(Browser.Engine.trident){ + parent.setStyle('height',parent.getStyle('height')); + } + var coords = this.getPosition(parent); + if(position == 'relative' && !Browser.Engine.presto){ + coords.x -= parent.getStyle('paddingLeft').toInt(); + coords.y -= parent.getStyle('paddingTop').toInt(); + } + var morph = this.retrieve('morph'); + if (morph){ + morph.cancel(); + var oldOptions = morph.options; + } + var morph = this.get('morph',{ + duration:50, + link:'chain' + }); + for(var i=0 ; i < duration ; i++){ + morph.start({ + top:coords.y+$random(-radius,radius), + left:coords.x+$random(-radius,radius) + }); + } + morph.start({ + top:coords.y, + left:coords.x + }).chain(function(){ + if(oldOptions){ + this.set('morph',oldOptions); + } + }.bind(this)); + return this; + } +}); + +String.implement({ + + parseQueryString: function() { + var vars = this.split(/[&;]/); + var rs = {}; + if (vars.length) vars.each(function(val) { + var keys = val.split('='); + if (keys.length && keys.length == 2) rs[decodeURIComponent(keys[0])] = decodeURIComponent(keys[1]); + }); + return rs; + } + +}); + +// Mootools Patch: Fixes issues in Safari, Chrome, and Internet Explorer caused by processing text as XML. +Request.HTML.implement({ + + processHTML: function(text){ + var match = text.match(/]*>([\s\S]*?)<\/body>/i); + text = (match) ? match[1] : text; + var container = new Element('div'); + return container.set('html', text); + } + +}); + +/* + + Examples: + (start code) + getCSSRule('.myRule'); + getCSSRule('#myRule'); + (end) + +*/ +MUI.getCSSRule = function(selector) { + for (var ii = 0; ii < document.styleSheets.length; ii++) { + var mysheet = document.styleSheets[ii]; + var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules; + for (i = 0; i < myrules.length; i++){ + if (myrules[i].selectorText == selector){ + return myrules[i]; + } + } + } + return false; +} + +// This makes it so Request will work to some degree locally +if (location.protocol == "file:"){ + + Request.implement({ + isSuccess : function(status){ + return (status == 0 || (status >= 200) && (status < 300)); + } + }); + + Browser.Request = function(){ + return $try(function(){ + return new ActiveXObject('MSXML2.XMLHTTP'); + }, function(){ + return new XMLHttpRequest(); + }); + }; + +} + +MUI.Require = new Class({ + + Implements: [Options], + + options: { + css: [], + images: [], + js: [], + onload: $empty + }, + + initialize: function(options){ + this.setOptions(options); + var options = this.options; + + this.assetsToLoad = options.css.length + options.images.length + options.js.length; + this.assetsLoaded = 0; + + var cssLoaded = 0; + + // Load CSS before images and JavaScript + + if (options.css.length){ + options.css.each( function(sheet){ + + this.getAsset(sheet, function(){ + if (cssLoaded == options.css.length - 1){ + + if (this.assetsLoaded == this.assetsToLoad - 1){ + this.requireOnload(); + } + else { + // Add a little delay since we are relying on cached CSS from XHR request. + this.assetsLoaded++; + this.requireContinue.delay(50, this); + } + } + else { + cssLoaded++; + this.assetsLoaded++; + } + }.bind(this)); + }.bind(this)); + } + else if (!options.js.length && !options.images.length){ + this.options.onload(); + return true; + } + else { + this.requireContinue.delay(50, this); // Delay is for Safari + } + + }, + + requireOnload: function(){ + this.assetsLoaded++; + if (this.assetsLoaded == this.assetsToLoad){ + this.options.onload(); + return true; + } + + }, + + requireContinue: function(){ + + var options = this.options; + if (options.images.length){ + options.images.each( function(image){ + this.getAsset(image, this.requireOnload.bind(this)); + }.bind(this)); + } + + if (options.js.length){ + options.js.each( function(script){ + this.getAsset(script, this.requireOnload.bind(this)); + }.bind(this)); + } + + }, + + getAsset: function(source, onload){ + + // If the asset is loaded, fire the onload function. + if ( MUI.files[source] == 'loaded' ){ + if (typeof onload == 'function'){ + onload(); + } + return true; + } + + // If the asset is loading, wait until it is loaded and then fire the onload function. + // If asset doesn't load by a number of tries, fire onload anyway. + else if ( MUI.files[source] == 'loading' ){ + var tries = 0; + var checker = (function(){ + tries++; + if (MUI.files[source] == 'loading' && tries < '100') return; + $clear(checker); + if (typeof onload == 'function'){ + onload(); + } + }).periodical(50); + } + + // If the asset is not yet loaded or loading, start loading the asset. + else { + MUI.files[source] = 'loading'; + + properties = { + 'onload': onload != 'undefined' ? onload : $empty + }; + + // Add to the onload function + var oldonload = properties.onload; + properties.onload = function() { + MUI.files[source] = 'loaded'; + if (oldonload) { + oldonload(); + } + }.bind(this); + + switch ( source.match(/\.\w+$/)[0] ) { + case '.js': return Asset.javascript(source, properties); + case '.css': return Asset.css(source, properties); + case '.jpg': + case '.png': + case '.gif': return Asset.image(source, properties); + } + + alert('The required file "' + source + '" could not be loaded'); + } + } + +}); + +$extend(Asset, { + + /* Fix an Opera bug in Mootools 1.2 */ + javascript: function(source, properties){ + properties = $extend({ + onload: $empty, + document: document, + check: $lambda(true) + }, properties); + + if ($(properties.id)) { + properties.onload(); + return $(properties.id); + } + + var script = new Element('script', {'src': source, 'type': 'text/javascript'}); + + var load = properties.onload.bind(script), check = properties.check, doc = properties.document; + delete properties.onload; delete properties.check; delete properties.document; + + if (!Browser.Engine.webkit419 && !Browser.Engine.presto){ + script.addEvents({ + load: load, + readystatechange: function(){ + if (Browser.Engine.trident && ['loaded', 'complete'].contains(this.readyState)) + load(); + } + }).setProperties(properties); + } + else { + var checker = (function(){ + if (!$try(check)) return; + $clear(checker); + // Opera has difficulty with multiple scripts being injected into the head simultaneously. We need to give it time to catch up. + Browser.Engine.presto ? load.delay(500) : load(); + }).periodical(50); + } + return script.inject(doc.head); + }, + + // Get the CSS with XHR before appending it to document.head so that we can have an onload callback. + css: function(source, properties){ + + properties = $extend({ + id: null, + media: 'screen', + onload: $empty + }, properties); + + new Request({ + method: 'get', + url: source, + onComplete: function(response) { + var newSheet = new Element('link', { + 'id': properties.id, + 'rel': 'stylesheet', + 'media': properties.media, + 'type': 'text/css', + 'href': source + }).inject(document.head); + properties.onload(); + }.bind(this), + onFailure: function(response){ + }, + onSuccess: function(){ + }.bind(this) + }).send(); + } + +}); + +/* + +REGISTER PLUGINS + + Register Components and Plugins for Lazy Loading + + How this works may take a moment to grasp. Take a look at MUI.Window below. + If we try to create a new Window and Window.js has not been loaded then the function + below will run. It will load the CSS required by the MUI.Window Class and then + then it will load Window.js. Here is the interesting part. When Window.js loads, + it will overwrite the function below, and new MUI.Window(arg) will be ran + again. This time it will create a new MUI.Window instance, and any future calls + to new MUI.Window(arg) will immediately create new windows since the assets + have already been loaded and our temporary function below has been overwritten. + + Example: + + MyPlugins.extend({ + + MyGadget: function(arg){ + new MUI.Require({ + css: [MUI.path.plugins + 'myGadget/css/style.css'], + images: [MUI.path.plugins + 'myGadget/images/background.gif'] + js: [MUI.path.plugins + 'myGadget/scripts/myGadget.js'], + onload: function(){ + new MyPlguins.MyGadget(arg); + } + }); + } + + }); + +-------------------------------------------------------------------- */ + +MUI.extend({ + + newWindowsFromJSON: function(arg){ + new MUI.Require({ + js: [MUI.path.source + 'Window/Windows-from-json.js'], + onload: function(){ + new MUI.newWindowsFromJSON(arg); + } + }); + }, + + arrangeCascade: function(){ + new MUI.Require({ + js: [MUI.path.source + 'Window/Arrange-cascade.js'], + onload: function(){ + new MUI.arrangeCascade(); + } + }); + }, + + arrangeTile: function(){ + new MUI.Require({ + js: [MUI.path.source + 'Window/Arrange-tile.js'], + onload: function(){ + new MUI.arrangeTile(); + } + }); + }, + + saveWorkspace: function(){ + new MUI.Require({ + js: [MUI.path.source + 'Layout/Workspaces.js'], + onload: function(){ + new MUI.saveWorkspace(); + } + }); + }, + + loadWorkspace: function(){ + new MUI.Require({ + js: [MUI.path.source + 'Layout/Workspaces.js'], + onload: function(){ + new MUI.loadWorkspace(); + } + }); + }, + + Themes: { + init: function(arg){ + new MUI.Require({ + js: [MUI.path.source + 'Utilities/Themes.js'], + onload: function(){ + MUI.Themes.init(arg); + } + }); + } + } + +}); +/* + +Script: Themes.js + Allows for switching themes dynamically. + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Requires: + Core.js + +Notes: + Themes are new and experimental. + +Syntax: + (start code) + new MUI.Themes.init(newTheme); + (end) + +Example: + (start code) + new MUI.Themes.init('charcoal'); + (end) + +Arguments: + newTheme - (string) The theme name + +*/ + +MUI.files[MUI.path.source + 'Utilities/Themes.js'] = 1; + +MUI.Themes = { + + /* + + Function: themeInit + Initialize a theme. This is experimental and not fully implemented yet. + + */ + init: function(newTheme){ + this.newTheme = newTheme.toLowerCase(); + if (!this.newTheme || this.newTheme == null || this.newTheme == MUI.options.theme.toLowerCase()) return; + + if ($('spinner')) $('spinner').show(); + + this.oldURIs = []; + this.oldSheets = []; + + $$('link').each( function(link){ + var href = link.get('href'); + if (href.contains(MUI.path.themes + MUI.options.theme)){ + this.oldURIs.push(href); + this.oldSheets.push(link); + } + }.bind(this)); + + /* + MUI.files.each( function(value, key, hash){ + if (key.contains(MUI.path.themes + MUI.options.theme)){ + this.oldURIs.push(key); + } + }.bind(this)); + */ + + this.newSheetURLs = this.oldURIs.map(function(item, index){ + return item.replace("/" + MUI.options.theme + "/", "/" + MUI.Themes.newTheme + "/"); + }.bind(this)); + + this.sheetsToLoad = this.oldURIs.length; + this.sheetsLoaded = 0; + + // Download new stylesheets and add them to an array + this.newSheets = []; + this.newSheetURLs.each( function(link){ + var href = link; + + //var id = link.id; + + var cssRequest = new Request({ + method: 'get', + url: href, + onComplete: function(response) { + var newSheet = new Element('link', { + //'id': id, + 'rel': 'stylesheet', + 'media': 'screen', + 'type': 'text/css', + 'href': href + }); + this.newSheets.push(newSheet); + }.bind(this), + onFailure: function(response){ + this.themeLoadSuccess = false; + if ($('spinner')) $('spinner').hide(); + MUI.notification('Stylesheets did not load.'); + }, + onSuccess: function(){ + this.sheetsLoaded++; + if (this.sheetsLoaded == this.sheetsToLoad) { + this.updateThemeStylesheets(); + this.themeLoadSuccess = true; + } + }.bind(this) + }); + cssRequest.send(); + + }.bind(this)); + + }, + updateThemeStylesheets: function(){ + + this.oldSheets.each( function(sheet){ + sheet.destroy(); + }); + + this.newSheets.each( function(sheet){ + MUI.files[sheet.get('href')] = 1; + sheet.inject(document.head); + }); + + // Delay gives the stylesheets time to take effect. IE6 needs more delay. + if (Browser.Engine.trident){ + this.redraw.delay(1250, this); + } + else { + this.redraw.delay(250, this); + } + + }, + redraw: function(){ + + $$('.replaced').removeClass('replaced'); + + // Redraw open windows + $$('.mocha').each( function(element){ + var instance = element.retrieve('instance'); + + // Convert CSS colors to Canvas colors. + instance.setColors(); + instance.drawWindow(); + }); + + if (MUI.Dock){ + if (MUI.Dock.options.useControls){ + MUI.Dock.setDockColors(); + MUI.Dock.renderDockControls(); + } + } + + // Reformat layout + if (MUI.Desktop.desktop){ + var checker = (function(){ + // Make sure the style sheets are really ready. + if (MUI.Desktop.desktop.getStyle('overflow') != 'hidden'){ + return; + } + $clear(checker); + MUI.Desktop.setDesktopSize(); + }).periodical(50); + } + + if ($('spinner')) $('spinner').hide(); + MUI.options.theme = this.newTheme; + + /* + this.cookie = new Hash.Cookie('mochaUIthemeCookie', {duration: 3600}); + this.cookie.empty(); + this.cookie.set('theme', MUI.options.theme); + this.cookie.save(); + */ + + } +}; + +window.addEvent('load', function(){ + /* + // Load theme the user was last using. This needs work. + var cookie = new Hash.Cookie('mochaUIthemeCookie', {duration: 3600}); + var themeCookie = cookie.load(); + if(cookie.getKeys().length){ + if (themeCookie.get('theme') != MUI.Themes.options.theme){ + MUI.Themes.init.delay(1000, MUI.Themes, themeCookie.get('theme')); + } + } + */ + + if ($('themeControl')){ + $('themeControl').getElements('option').setProperty('selected', 'false'); + if ($('chooseTheme')){ + $('chooseTheme').setProperty('selected', 'true'); + } + } +}); +/* + +Script: Window.js + Build windows. + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Requires: + Core.js + +*/ + +MUI.files[MUI.path.source + 'Window/Window.js'] = 'loading'; +//$require(MUI.themePath() + '/css/Dock.css'); + +/* +Class: Window + Creates a single MochaUI window. + +Syntax: + (start code) + new MUI.Window(options); + (end) + +Arguments: + options + +Options: + id - The ID of the window. If not defined, it will be set to 'win' + windowIDCount. + title - The title of the window. + icon - Place an icon in the window's titlebar. This is either set to false or to the url of the icon. It is set up for icons that are 16 x 16px. + type - ('window', 'modal', 'modal2', or 'notification') Defaults to 'window'. Modals should be created with new MUI.Modal(options). + loadMethod - ('html', 'xhr', or 'iframe') Defaults to 'html' if there is no contentURL. Defaults to 'xhr' if there is a contentURL. You only really need to set this if using the 'iframe' method. + contentURL - Used if loadMethod is set to 'xhr' or 'iframe'. + closeAfter - Either false or time in milliseconds. Closes the window after a certain period of time in milliseconds. This is particularly useful for notifications. + evalScripts - (boolean) An xhr loadMethod option. Defaults to true. + evalResponse - (boolean) An xhr loadMethod option. Defaults to false. + content - (string or element) An html loadMethod option. + toolbar - (boolean) Create window toolbar. Defaults to false. This can be used for tabs, media controls, and so forth. + toolbarPosition - ('top' or 'bottom') Defaults to top. + toolbarHeight - (number) + toolbarURL - (url) Defaults to 'pages/lipsum.html'. + toolbarContent - (string) + toolbarOnload - (function) + toolbar2 - (boolean) Create window toolbar. Defaults to false. This can be used for tabs, media controls, and so forth. + toolbar2Position - ('top' or 'bottom') Defaults to top. + toolbar2Height - (number) + toolbar2URL - (url) Defaults to 'pages/lipsum.html'. + toolbar2Content - (string) + toolbar2Onload - (function) + container - (element ID) Element the window is injected in. The container defaults to 'desktop'. If no desktop then to document.body. Use 'pageWrapper' if you don't want the windows to overlap the toolbars. + restrict - (boolean) Restrict window to container when dragging. + shape - ('box' or 'gauge') Shape of window. Defaults to 'box'. + collapsible - (boolean) Defaults to true. + minimizable - (boolean) Requires MUI.Desktop and MUI.Dock. Defaults to true if dependenices are met. + maximizable - (boolean) Requires MUI.Desktop. Defaults to true if dependenices are met. + closable - (boolean) Defaults to true. + storeOnClose - (boolean) Hides a window and it's dock tab rather than destroying them on close. If you try to create the window again it will unhide the window and dock tab. + modalOverlayClose - (boolean) Whether or not you can close a modal by clicking on the modal overlay. Defaults to true. + draggable - (boolean) Defaults to false for modals; otherwise true. + draggableGrid - (false or number) Distance in pixels for snap-to-grid dragging. Defaults to false. + draggableLimit - (false or number) An object with x and y properties used to limit the movement of the Window. Defaults to false. + draggableSnap - (boolean) The distance to drag before the Window starts to respond to the drag. Defaults to false. + resizable - (boolean) Defaults to false for modals, notifications and gauges; otherwise true. + resizeLimit - (object) Minimum and maximum width and height of window when resized. + addClass - (string) Add a class to the window for more control over styling. + width - (number) Width of content area. + height - (number) Height of content area. + headerHeight - (number) Height of window titlebar. + footerHeight - (number) Height of window footer. + cornerRadius - (number) + x - (number) If x and y are left undefined the window is centered on the page. + y - (number) + scrollbars - (boolean) + padding - (object) + shadowBlur - (number) Width of shadows. + shadowOffset - Should be positive and not be greater than the ShadowBlur. + controlsOffset - Change this if you want to reposition the window controls. + useCanvas - (boolean) Set this to false if you don't want a canvas body. + useCanvasControls - (boolean) Set this to false if you wish to use images for the buttons. + useSpinner - (boolean) Toggles whether or not the ajax spinners are displayed in window footers. Defaults to true. + headerStartColor - ([r,g,b,]) Titlebar gradient's top color + headerStopColor - ([r,g,b,]) Titlebar gradient's bottom color + bodyBgColor - ([r,g,b,]) Background color of the main canvas shape + minimizeBgColor - ([r,g,b,]) Minimize button background color + minimizeColor - ([r,g,b,]) Minimize button color + maximizeBgColor - ([r,g,b,]) Maximize button background color + maximizeColor - ([r,g,b,]) Maximize button color + closeBgColor - ([r,g,b,]) Close button background color + closeColor - ([r,g,b,]) Close button color + resizableColor - ([r,g,b,]) Resizable icon color + onBeforeBuild - (function) Fired just before the window is built. + onContentLoaded - (function) Fired when content is successfully loaded via XHR or Iframe. + onFocus - (function) Fired when the window is focused. + onBlur - (function) Fired when window loses focus. + onResize - (function) Fired when the window is resized. + onMinimize - (function) Fired when the window is minimized. + onMaximize - (function) Fired when the window is maximized. + onRestore - (function) Fired when a window is restored from minimized or maximized. + onClose - (function) Fired just before the window is closed. + onCloseComplete - (function) Fired after the window is closed. + +Returns: + Window object. + +Example: + Define a window. It is suggested you name the function the same as your window ID + "Window". + (start code) + var mywindowWindow = function(){ + new MUI.Window({ + id: 'mywindow', + title: 'My Window', + loadMethod: 'xhr', + contentURL: 'pages/lipsum.html', + width: 340, + height: 150 + }); + } + (end) + +Example: + Create window onDomReady. + (start code) + window.addEvent('domready', function(){ + mywindow(); + }); + (end) + +Example: + Add link events to build future windows. It is suggested you give your anchor the same ID as your window + "WindowLink" or + "WindowLinkCheck". Use the latter if it is a link in the menu toolbar. + + If you wish to add links in windows that open other windows remember to add events to those links when the windows are created. + + (start code) + // Javascript: + if ($('mywindowLink')){ + $('mywindowLink').addEvent('click', function(e) { + new Event(e).stop(); + mywindow(); + }); + } + + // HTML: + My Window + (end) + + + Loading Content with an XMLHttpRequest(xhr): + For content to load via xhr all the files must be online and in the same domain. If you need to load content from another domain or wish to have it work offline, load the content in an iframe instead of using the xhr option. + + Iframes: + If you use the iframe loadMethod your iframe will automatically be resized when the window it is in is resized. If you want this same functionality when using one of the other load options simply add class="mochaIframe" to those iframes and they will be resized for you as well. + +*/ + +// Having these options outside of the Class allows us to add, change, and remove +// individual options without rewriting all of them. + +MUI.extend({ + Windows: { + instances: new Hash(), + indexLevel: 100, // Used for window z-Index + windowIDCount: 0, // Used for windows without an ID defined by the user + windowsVisible: true, // Ctrl-Alt-Q to toggle window visibility + focusingWindow: false + } +}); + +MUI.Windows.windowOptions = { + id: null, + title: 'New Window', + icon: false, + type: 'window', + require: { + css: [], + images: [], + js: [], + onload: null + }, + loadMethod: null, + method: 'get', + contentURL: null, + data: null, + + closeAfter: false, + + // xhr options + evalScripts: true, + evalResponse: false, + + // html options + content: 'Window content', + + // Toolbar + toolbar: false, + toolbarPosition: 'top', + toolbarHeight: 29, + toolbarURL: 'pages/lipsum.html', + toolbarData: null, + toolbarContent: '', + toolbarOnload: $empty, + + // Toolbar + toolbar2: false, + toolbar2Position: 'bottom', + toolbar2Height: 29, + toolbar2URL: 'pages/lipsum.html', + toolbar2Data: null, + toolbar2Content: '', + toolbar2Onload: $empty, + + // Container options + container: null, + restrict: true, + shape: 'box', + + // Window Controls + collapsible: true, + minimizable: true, + maximizable: true, + closable: true, + + // Close options + storeOnClose: false, + + // Modal options + modalOverlayClose: true, + + // Draggable + draggable: null, + draggableGrid: false, + draggableLimit: false, + draggableSnap: false, + + // Resizable + resizable: null, + resizeLimit: {'x': [250, 2500], 'y': [125, 2000]}, + + // Style options: + addClass: '', + width: 300, + height: 125, + headerHeight: 25, + footerHeight: 25, + cornerRadius: 8, + x: null, + y: null, + scrollbars: true, + padding: { top: 10, right: 12, bottom: 10, left: 12 }, + shadowBlur: 5, + shadowOffset: {'x': 0, 'y': 1}, + controlsOffset: {'right': 6, 'top': 6}, + useCanvas: true, + useCanvasControls: true, + useSpinner: true, + + // Color options: + headerStartColor: [250, 250, 250], + headerStopColor: [229, 229, 229], + bodyBgColor: [229, 229, 229], + minimizeBgColor: [255, 255, 255], + minimizeColor: [0, 0, 0], + maximizeBgColor: [255, 255, 255], + maximizeColor: [0, 0, 0], + closeBgColor: [255, 255, 255], + closeColor: [0, 0, 0], + resizableColor: [254, 254, 254], + + // Events + onBeforeBuild: $empty, + onContentLoaded: $empty, + onFocus: $empty, + onBlur: $empty, + onResize: $empty, + onMinimize: $empty, + onMaximize: $empty, + onRestore: $empty, + onClose: $empty, + onCloseComplete: $empty +}; + +MUI.Windows.windowOptionsOriginal = $merge(MUI.Windows.windowOptions); + +MUI.Window = new Class({ + + Implements: [Events, Options], + + options: MUI.Windows.windowOptions, + + initialize: function(options){ + this.setOptions(options); + + // Shorten object chain + var options = this.options; + + $extend(this, { + mochaControlsWidth: 0, + minimizebuttonX: 0, // Minimize button horizontal position + maximizebuttonX: 0, // Maximize button horizontal position + closebuttonX: 0, // Close button horizontal position + headerFooterShadow: options.headerHeight + options.footerHeight + (options.shadowBlur * 2), + oldTop: 0, + oldLeft: 0, + isMaximized: false, + isMinimized: false, + isCollapsed: false, + timestamp: $time() + }); + + if (options.type != 'window'){ + options.container = document.body; + options.minimizable = false; + } + if (!options.container){ + options.container = MUI.Desktop && MUI.Desktop.desktop ? MUI.Desktop.desktop : document.body; + } + + // Set this.options.resizable to default if it was not defined + if (options.resizable == null){ + if (options.type != 'window' || options.shape == 'gauge'){ + options.resizable = false; + } + else { + options.resizable = true; + } + } + + // Set this.options.draggable if it was not defined + if (options.draggable == null){ + options.draggable = options.type != 'window' ? false : true; + } + + // Gauges are not maximizable or resizable + if (options.shape == 'gauge' || options.type == 'notification'){ + options.collapsible = false; + options.maximizable = false; + options.contentBgColor = 'transparent'; + options.scrollbars = false; + options.footerHeight = 0; + } + if (options.type == 'notification'){ + options.closable = false; + options.headerHeight = 0; + } + + // Minimizable, dock is required and window cannot be modal + if (MUI.Dock && $(MUI.options.dock)){ + if (MUI.Dock.dock && options.type != 'modal' && options.type != 'modal2'){ + options.minimizable = options.minimizable; + } + } + else { + options.minimizable = false; + } + + // Maximizable, desktop is required + options.maximizable = MUI.Desktop && MUI.Desktop.desktop && options.maximizable && options.type != 'modal' && options.type != 'modal2'; + + if (this.options.type == 'modal2') { + this.options.shadowBlur = 0; + this.options.shadowOffset = {'x': 0, 'y': 0}; + this.options.useSpinner = false; + this.options.useCanvas = false; + this.options.footerHeight = 0; + this.options.headerHeight = 0; + } + + // If window has no ID, give it one. + options.id = options.id || 'win' + (++MUI.Windows.windowIDCount); + + this.windowEl = $(options.id); + + if (options.require.css.length || options.require.images.length){ + new MUI.Require({ + css: options.require.css, + images: options.require.images, + onload: function(){ + this.newWindow(); + }.bind(this) + }); + } + else { + this.newWindow(); + } + + // Return window object + return this; + }, + saveValues: function(){ + var coordinates = this.windowEl.getCoordinates(); + this.options.x = coordinates.left.toInt(); + this.options.y = coordinates.top.toInt(); + }, + + /* + + Internal Function: newWindow + + Arguments: + properties + + */ + newWindow: function(properties){ // options is not doing anything + + // Shorten object chain + var instances = MUI.Windows.instances; + var instanceID = MUI.Windows.instances.get(this.options.id); + var options = this.options; + + // Here we check to see if there is already a class instance for this window + if (instanceID) var instance = instanceID; + + // Check if window already exists and is not in progress of closing + if ( this.windowEl && !this.isClosing ){ + // Restore if minimized + if (instance.isMinimized){ + MUI.Dock.restoreMinimized(this.windowEl); + } + // Expand and focus if collapsed + else if (instance.isCollapsed){ + MUI.collapseToggle(this.windowEl); + setTimeout(MUI.focusWindow.pass(this.windowEl, this),10); + } + else if (this.windowEl.hasClass('windowClosed')){ + + if (instance.check) instance.check.show(); + + this.windowEl.removeClass('windowClosed'); + this.windowEl.setStyle('opacity', 0); + this.windowEl.addClass('mocha'); + + if (MUI.Dock && $(MUI.options.dock) && instance.options.type == 'window') { + var currentButton = $(instance.options.id + '_dockTab'); + if (currentButton != null) { + currentButton.show(); + } + MUI.Desktop.setDesktopSize(); + } + + instance.displayNewWindow(); + + } + // Else focus + else { + var coordinates = document.getCoordinates(); + if (this.windowEl.getStyle('left').toInt() > coordinates.width || this.windowEl.getStyle('top').toInt() > coordinates.height){ + MUI.centerWindow(this.windowEl); + } + setTimeout(MUI.focusWindow.pass(this.windowEl, this),10); + if (MUI.options.standardEffects == true) { + this.windowEl.shake(); + } + } + return; + } + else { + instances.set(options.id, this); + } + + this.isClosing = false; + this.fireEvent('onBeforeBuild'); + + // Create window div + MUI.Windows.indexLevel++; + this.windowEl = new Element('div', { + 'class': 'mocha', + 'id': options.id, + 'styles': { + 'position': 'absolute', + 'width': options.width, + 'height': options.height, + 'display': 'block', + 'opacity': 0, + 'zIndex': MUI.Windows.indexLevel += 2 + } + }); + + this.windowEl.store('instance', this); + + this.windowEl.addClass(options.addClass); + + if (options.type == 'modal2') { + this.windowEl.addClass('modal2'); + } + + // Fix a mouseover issue with gauges in IE7 + if ( Browser.Engine.trident && options.shape == 'gauge') { + this.windowEl.setStyle('backgroundImage', 'url(../images/spacer.gif)'); + } + + if ((this.options.type == 'modal' || options.type == 'modal2' ) && Browser.Platform.mac && Browser.Engine.gecko){ + if (/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)) { + var ffversion = new Number(RegExp.$1); + if (ffversion < 3) { + this.windowEl.setStyle('position', 'fixed'); + } + } + } + + if (options.loadMethod == 'iframe') { + options.padding = { top: 0, right: 0, bottom: 0, left: 0 }; + } + + // Insert sub elements inside windowEl + this.insertWindowElements(); + + // Set title + this.titleEl.set('html', options.title); + + this.contentWrapperEl.setStyle('overflow', 'hidden'); + + this.contentEl.setStyles({ + 'padding-top': options.padding.top, + 'padding-bottom': options.padding.bottom, + 'padding-left': options.padding.left, + 'padding-right': options.padding.right + }); + + if (options.shape == 'gauge'){ + if (options.useCanvasControls){ + this.canvasControlsEl.setStyle('visibility', 'hidden'); + } + else { + this.controlsEl.setStyle('visibility', 'hidden'); + } + this.windowEl.addEvent('mouseover', function(){ + this.mouseover = true; + var showControls = function(){ + if (this.mouseover != false){ + if (options.useCanvasControls){ + this.canvasControlsEl.setStyle('visibility', 'visible'); + } + else { + this.controlsEl.setStyle('visibility', 'visible'); + } + this.canvasHeaderEl.setStyle('visibility', 'visible'); + this.titleEl.show(); + } + }; + showControls.delay(0, this); + + }.bind(this)); + this.windowEl.addEvent('mouseleave', function(){ + this.mouseover = false; + if (this.options.useCanvasControls){ + this.canvasControlsEl.setStyle('visibility', 'hidden'); + } + else { + this.controlsEl.setStyle('visibility', 'hidden'); + } + this.canvasHeaderEl.setStyle('visibility', 'hidden'); + this.titleEl.hide(); + }.bind(this)); + } + + // Inject window into DOM + this.windowEl.inject(options.container); + + // Convert CSS colors to Canvas colors. + this.setColors(); + + if (options.type != 'notification'){ + this.setMochaControlsWidth(); + } + + // Add content to window. + MUI.updateContent({ + 'element': this.windowEl, + 'content': options.content, + 'method': options.method, + 'url': options.contentURL, + 'data': options.data, + 'onContentLoaded': null, + 'require': { + js: options.require.js, + onload: options.require.onload + } + }); + + // Add content to window toolbar. + if (this.options.toolbar == true){ + MUI.updateContent({ + 'element': this.windowEl, + 'childElement': this.toolbarEl, + 'content': options.toolbarContent, + 'loadMethod': 'xhr', + 'method': options.method, + 'url': options.toolbarURL, + 'data': options.toolbarData, + 'onContentLoaded': options.toolbarOnload + }); + } + + // Add content to window toolbar. + if (this.options.toolbar2 == true){ + MUI.updateContent({ + 'element': this.windowEl, + 'childElement': this.toolbar2El, + 'content': options.toolbar2Content, + 'loadMethod': 'xhr', + 'method': options.method, + 'url': options.toolbar2URL, + 'data': options.toolbar2Data, + 'onContentLoaded': options.toolbar2Onload + }); + } + + this.drawWindow(); + + // Attach events to the window + this.attachDraggable(); + this.attachResizable(); + this.setupEvents(); + + if (options.resizable){ + this.adjustHandles(); + } + + // Position window. If position not specified by user then center the window on the page. + if (options.container == document.body || options.container == MUI.Desktop.desktop){ + var dimensions = window.getSize(); + } + else { + var dimensions = $(this.options.container).getSize(); + } + + if (!options.y) { + if (MUI.Desktop && MUI.Desktop.desktop) { + var y = (dimensions.y * .5) - (this.windowEl.offsetHeight * .5); + if (y < -options.shadowBlur) y = -options.shadowBlur; + } + else { + var y = window.getScroll().y + (window.getSize().y * .5) - (this.windowEl.offsetHeight * .5); + if (y < -options.shadowBlur) y = -options.shadowBlur; + } + } + else { + var y = options.y - options.shadowBlur; + } + + if (!this.options.x) { + var x = (dimensions.x * .5) - (this.windowEl.offsetWidth * .5); + if (x < -options.shadowBlur) x = -options.shadowBlur; + } + else { + var x = options.x - options.shadowBlur; + } + + this.windowEl.setStyles({ + 'top': y, + 'left': x + }); + + // Create opacityMorph + + this.opacityMorph = new Fx.Morph(this.windowEl, { + 'duration': 350, + transition: Fx.Transitions.Sine.easeInOut, + onComplete: function(){ + if (Browser.Engine.trident){ + this.drawWindow(); + } + }.bind(this) + }); + + this.displayNewWindow(); + + // This is a generic morph that can be reused later by functions like centerWindow() + // It returns the windowEl element rather than this Class. + this.morph = new Fx.Morph(this.windowEl, { + 'duration': 200 + }); + this.windowEl.store('morph', this.morph); + + this.resizeMorph = new Fx.Elements([this.contentWrapperEl, this.windowEl], { + duration: 400, + transition: Fx.Transitions.Sine.easeInOut, + onStart: function(){ + this.resizeAnimation = this.drawWindow.periodical(20, this); + }.bind(this), + onComplete: function(){ + $clear(this.resizeAnimation); + this.drawWindow(); + // Show iframe + if ( this.iframeEl ) { + this.iframeEl.setStyle('visibility', 'visible'); + } + }.bind(this) + }); + this.windowEl.store('resizeMorph', this.resizeMorph); + + // Add check mark to menu if link exists in menu + // Need to make sure the check mark is not added to links not in menu + if ($(this.windowEl.id + 'LinkCheck')){ + this.check = new Element('div', { + 'class': 'check', + 'id': this.options.id + '_check' + }).inject(this.windowEl.id + 'LinkCheck'); + } + + if (this.options.closeAfter != false){ + MUI.closeWindow.delay(this.options.closeAfter, this, this.windowEl); + } + + if (MUI.Dock && $(MUI.options.dock) && this.options.type == 'window' ){ + MUI.Dock.createDockTab(this.windowEl); + } + + }, + displayNewWindow: function(){ + + options = this.options; + if (options.type == 'modal' || options.type == 'modal2') { + MUI.currentModal = this.windowEl; + if (Browser.Engine.trident4){ + $('modalFix').show(); + } + $('modalOverlay').show(); + if (MUI.options.advancedEffects == false){ + $('modalOverlay').setStyle('opacity', .6); + this.windowEl.setStyles({ + 'zIndex': 11000, + 'opacity': 1 + }); + } + else { + MUI.Modal.modalOverlayCloseMorph.cancel(); + MUI.Modal.modalOverlayOpenMorph.start({ + 'opacity': .6 + }); + this.windowEl.setStyles({ + 'zIndex': 11000 + }); + this.opacityMorph.start({ + 'opacity': 1 + }); + } + + $$('.dockTab').removeClass('activeDockTab'); + $$('.mocha').removeClass('isFocused'); + this.windowEl.addClass('isFocused'); + + } + else if (MUI.options.advancedEffects == false){ + this.windowEl.setStyle('opacity', 1); + setTimeout(MUI.focusWindow.pass(this.windowEl, this), 10); + } + else { + // IE cannot handle both element opacity and VML alpha at the same time. + if (Browser.Engine.trident){ + this.drawWindow(false); + } + this.opacityMorph.start({ + 'opacity': 1 + }); + setTimeout(MUI.focusWindow.pass(this.windowEl, this), 10); + } + + }, + setupEvents: function() { + var windowEl = this.windowEl; + // Set events + // Note: if a button does not exist, its due to properties passed to newWindow() stating otherwice + if (this.closeButtonEl){ + this.closeButtonEl.addEvent('click', function(e) { + new Event(e).stop(); + MUI.closeWindow(windowEl); + }.bind(this)); + } + + if (this.options.type == 'window'){ + windowEl.addEvent('mousedown', function(e) { + if (Browser.Engine.trident) { + new Event(e).stop(); + } + MUI.focusWindow(windowEl); + if (windowEl.getStyle('top').toInt() < -this.options.shadowBlur) { + windowEl.setStyle('top', -this.options.shadowBlur); + } + }.bind(this)); + } + + if (this.minimizeButtonEl) { + this.minimizeButtonEl.addEvent('click', function(e) { + new Event(e).stop(); + MUI.Dock.minimizeWindow(windowEl); + }.bind(this)); + } + + if (this.maximizeButtonEl) { + this.maximizeButtonEl.addEvent('click', function(e) { + new Event(e).stop(); + if (this.isMaximized) { + MUI.Desktop.restoreWindow(windowEl); + } else { + MUI.Desktop.maximizeWindow(windowEl); + } + }.bind(this)); + } + + if (this.options.collapsible == true){ + // Keep titlebar text from being selected on double click in Safari. + this.titleEl.addEvent('selectstart', function(e) { + e = new Event(e).stop(); + }.bind(this)); + + if (Browser.Engine.trident) { + this.titleBarEl.addEvent('mousedown', function(e) { + this.titleEl.setCapture(); + }.bind(this)); + this.titleBarEl.addEvent('mouseup', function(e) { + this.titleEl.releaseCapture(); + }.bind(this)); + } + + this.titleBarEl.addEvent('dblclick', function(e) { + e = new Event(e).stop(); + MUI.collapseToggle(this.windowEl); + }.bind(this)); + } + + }, + /* + + Internal Function: attachDraggable() + Make window draggable. + + */ + attachDraggable: function(){ + var windowEl = this.windowEl; + if (!this.options.draggable) return; + this.windowDrag = new Drag.Move(windowEl, { + handle: this.titleBarEl, + container: this.options.restrict == true ? $(this.options.container) : false, + grid: this.options.draggableGrid, + limit: this.options.draggableLimit, + snap: this.options.draggableSnap, + onStart: function() { + if (this.options.type != 'modal' && this.options.type != 'modal2'){ + MUI.focusWindow(windowEl); + $('windowUnderlay').show(); + } + if (this.iframeEl) { + if (!Browser.Engine.trident) { + this.iframeEl.setStyle('visibility', 'hidden'); + } + else { + this.iframeEl.hide(); + } + } + }.bind(this), + onComplete: function() { + if (this.options.type != 'modal' && this.options.type != 'modal2') { + $('windowUnderlay').hide(); + } + if ( this.iframeEl ){ + if (!Browser.Engine.trident) { + this.iframeEl.setStyle('visibility', 'visible'); + } + else { + this.iframeEl.show(); + } + } + // Store new position in options. + this.saveValues(); + }.bind(this) + }); + }, + /* + + Internal Function: attachResizable + Make window resizable. + + */ + attachResizable: function(){ + var windowEl = this.windowEl; + if (!this.options.resizable) return; + this.resizable1 = this.windowEl.makeResizable({ + handle: [this.n, this.ne, this.nw], + limit: { + y: [ + function(){ + return this.windowEl.getStyle('top').toInt() + this.windowEl.getStyle('height').toInt() - this.options.resizeLimit.y[1]; + }.bind(this), + function(){ + return this.windowEl.getStyle('top').toInt() + this.windowEl.getStyle('height').toInt() - this.options.resizeLimit.y[0]; + }.bind(this) + ] + }, + modifiers: {x: false, y: 'top'}, + onStart: function(){ + this.resizeOnStart(); + this.coords = this.contentWrapperEl.getCoordinates(); + this.y2 = this.coords.top.toInt() + this.contentWrapperEl.offsetHeight; + }.bind(this), + onDrag: function(){ + this.coords = this.contentWrapperEl.getCoordinates(); + this.contentWrapperEl.setStyle('height', this.y2 - this.coords.top.toInt()); + this.resizeOnDrag(); + }.bind(this), + onComplete: function(){ + this.resizeOnComplete(); + }.bind(this) + }); + + this.resizable2 = this.contentWrapperEl.makeResizable({ + handle: [this.e, this.ne], + limit: { + x: [this.options.resizeLimit.x[0] - (this.options.shadowBlur * 2), this.options.resizeLimit.x[1] - (this.options.shadowBlur * 2) ] + }, + modifiers: {x: 'width', y: false}, + onStart: function(){ + this.resizeOnStart(); + }.bind(this), + onDrag: function(){ + this.resizeOnDrag(); + }.bind(this), + onComplete: function(){ + this.resizeOnComplete(); + }.bind(this) + }); + + this.resizable3 = this.contentWrapperEl.makeResizable({ + container: this.options.restrict == true ? $(this.options.container) : false, + handle: this.se, + limit: { + x: [this.options.resizeLimit.x[0] - (this.options.shadowBlur * 2), this.options.resizeLimit.x[1] - (this.options.shadowBlur * 2) ], + y: [this.options.resizeLimit.y[0] - this.headerFooterShadow, this.options.resizeLimit.y[1] - this.headerFooterShadow] + }, + modifiers: {x: 'width', y: 'height'}, + onStart: function(){ + this.resizeOnStart(); + }.bind(this), + onDrag: function(){ + this.resizeOnDrag(); + }.bind(this), + onComplete: function(){ + this.resizeOnComplete(); + }.bind(this) + }); + + this.resizable4 = this.contentWrapperEl.makeResizable({ + handle: [this.s, this.sw], + limit: { + y: [this.options.resizeLimit.y[0] - this.headerFooterShadow, this.options.resizeLimit.y[1] - this.headerFooterShadow] + }, + modifiers: {x: false, y: 'height'}, + onStart: function(){ + this.resizeOnStart(); + }.bind(this), + onDrag: function(){ + this.resizeOnDrag(); + }.bind(this), + onComplete: function(){ + this.resizeOnComplete(); + }.bind(this) + }); + + this.resizable5 = this.windowEl.makeResizable({ + handle: [this.w, this.sw, this.nw], + limit: { + x: [ + function(){ + return this.windowEl.getStyle('left').toInt() + this.windowEl.getStyle('width').toInt() - this.options.resizeLimit.x[1]; + }.bind(this), + function(){ + return this.windowEl.getStyle('left').toInt() + this.windowEl.getStyle('width').toInt() - this.options.resizeLimit.x[0]; + }.bind(this) + ] + }, + modifiers: {x: 'left', y: false}, + onStart: function(){ + this.resizeOnStart(); + this.coords = this.contentWrapperEl.getCoordinates(); + this.x2 = this.coords.left.toInt() + this.contentWrapperEl.offsetWidth; + }.bind(this), + onDrag: function(){ + this.coords = this.contentWrapperEl.getCoordinates(); + this.contentWrapperEl.setStyle('width', this.x2 - this.coords.left.toInt()); + this.resizeOnDrag(); + }.bind(this), + onComplete: function(){ + this.resizeOnComplete(); + }.bind(this) + }); + + }, + resizeOnStart: function(){ + $('windowUnderlay').show(); + if (this.iframeEl){ + if (!Browser.Engine.trident) { + this.iframeEl.setStyle('visibility', 'hidden'); + } + else { + this.iframeEl.hide(); + } + } + }, + resizeOnDrag: function(){ + // Fix for a rendering glitch in FF when resizing a window with panels in it + if (Browser.Engine.gecko) { + this.windowEl.getElements('.panel').each(function(panel){ + panel.store('oldOverflow', panel.getStyle('overflow')); + panel.setStyle('overflow', 'visible'); + }); + } + this.drawWindow(); + this.adjustHandles(); + if (Browser.Engine.gecko) { + this.windowEl.getElements('.panel').each(function(panel){ + panel.setStyle('overflow', panel.retrieve('oldOverflow')); // Fix for a rendering bug in FF + }); + } + }, + resizeOnComplete: function(){ + $('windowUnderlay').hide(); + if (this.iframeEl){ + if (!Browser.Engine.trident) { + this.iframeEl.setStyle('visibility', 'visible'); + } + else { + this.iframeEl.show(); + // The following hack is to get IE8 RC1 IE8 Standards Mode to properly resize an iframe + // when only the vertical dimension is changed. + this.iframeEl.setStyle('width', '99%'); + this.iframeEl.setStyle('height', this.contentWrapperEl.offsetHeight); + this.iframeEl.setStyle('width', '100%'); + this.iframeEl.setStyle('height', this.contentWrapperEl.offsetHeight); + } + } + + // Resize panels if there are any + if (this.contentWrapperEl.getChildren('.column') != null) { + MUI.rWidth(this.contentWrapperEl); + this.contentWrapperEl.getChildren('.column').each(function(column){ + MUI.panelHeight(column); + }); + } + + this.fireEvent('onResize', this.windowEl); + }, + adjustHandles: function(){ + + var shadowBlur = this.options.shadowBlur; + var shadowBlur2x = shadowBlur * 2; + var shadowOffset = this.options.shadowOffset; + var top = shadowBlur - shadowOffset.y - 1; + var right = shadowBlur + shadowOffset.x - 1; + var bottom = shadowBlur + shadowOffset.y - 1; + var left = shadowBlur - shadowOffset.x - 1; + + var coordinates = this.windowEl.getCoordinates(); + var width = coordinates.width - shadowBlur2x + 2; + var height = coordinates.height - shadowBlur2x + 2; + + this.n.setStyles({ + 'top': top, + 'left': left + 10, + 'width': width - 20 + }); + this.e.setStyles({ + 'top': top + 10, + 'right': right, + 'height': height - 30 + }); + this.s.setStyles({ + 'bottom': bottom, + 'left': left + 10, + 'width': width - 30 + }); + this.w.setStyles({ + 'top': top + 10, + 'left': left, + 'height': height - 20 + }); + this.ne.setStyles({ + 'top': top, + 'right': right + }); + this.se.setStyles({ + 'bottom': bottom, + 'right': right + }); + this.sw.setStyles({ + 'bottom': bottom, + 'left': left + }); + this.nw.setStyles({ + 'top': top, + 'left': left + }); + }, + detachResizable: function(){ + this.resizable1.detach(); + this.resizable2.detach(); + this.resizable3.detach(); + this.resizable4.detach(); + this.resizable5.detach(); + this.windowEl.getElements('.handle').hide(); + }, + reattachResizable: function(){ + this.resizable1.attach(); + this.resizable2.attach(); + this.resizable3.attach(); + this.resizable4.attach(); + this.resizable5.attach(); + this.windowEl.getElements('.handle').show(); + }, + /* + + Internal Function: insertWindowElements + + Arguments: + windowEl + + */ + insertWindowElements: function(){ + + var options = this.options; + var height = options.height; + var width = options.width; + var id = options.id; + + var cache = {}; + + if (Browser.Engine.trident4){ + cache.zIndexFixEl = new Element('iframe', { + 'id': id + '_zIndexFix', + 'class': 'zIndexFix', + 'scrolling': 'no', + 'marginWidth': 0, + 'marginHeight': 0, + 'src': '', + 'styles': { + 'position': 'absolute' // This is set here to make theme transitions smoother + } + }).inject(this.windowEl); + } + + cache.overlayEl = new Element('div', { + 'id': id + '_overlay', + 'class': 'mochaOverlay', + 'styles': { + 'position': 'absolute', // This is set here to make theme transitions smoother + 'top': 0, + 'left': 0 + } + }).inject(this.windowEl); + + cache.titleBarEl = new Element('div', { + 'id': id + '_titleBar', + 'class': 'mochaTitlebar', + 'styles': { + 'cursor': options.draggable ? 'move' : 'default' + } + }).inject(cache.overlayEl, 'top'); + + cache.titleEl = new Element('h3', { + 'id': id + '_title', + 'class': 'mochaTitle' + }).inject(cache.titleBarEl); + + if (options.icon != false){ + cache.titleEl.setStyles({ + 'padding-left': 28, + 'background': 'url(' + options.icon + ') 5px 4px no-repeat' + }); + } + + cache.contentBorderEl = new Element('div', { + 'id': id + '_contentBorder', + 'class': 'mochaContentBorder' + }).inject(cache.overlayEl); + + if (options.toolbar){ + cache.toolbarWrapperEl = new Element('div', { + 'id': id + '_toolbarWrapper', + 'class': 'mochaToolbarWrapper', + 'styles': { 'height': options.toolbarHeight } + }).inject(cache.contentBorderEl, options.toolbarPosition == 'bottom' ? 'after' : 'before'); + + if (options.toolbarPosition == 'bottom') { + cache.toolbarWrapperEl.addClass('bottom'); + } + cache.toolbarEl = new Element('div', { + 'id': id + '_toolbar', + 'class': 'mochaToolbar', + 'styles': { 'height': options.toolbarHeight } + }).inject(cache.toolbarWrapperEl); + } + + if (options.toolbar2){ + cache.toolbar2WrapperEl = new Element('div', { + 'id': id + '_toolbar2Wrapper', + 'class': 'mochaToolbarWrapper', + 'styles': { 'height': options.toolbar2Height } + }).inject(cache.contentBorderEl, options.toolbar2Position == 'bottom' ? 'after' : 'before'); + + if (options.toolbar2Position == 'bottom') { + cache.toolbar2WrapperEl.addClass('bottom'); + } + cache.toolbar2El = new Element('div', { + 'id': id + '_toolbar2', + 'class': 'mochaToolbar', + 'styles': { 'height': options.toolbar2Height } + }).inject(cache.toolbar2WrapperEl); + } + + cache.contentWrapperEl = new Element('div', { + 'id': id + '_contentWrapper', + 'class': 'mochaContentWrapper', + 'styles': { + 'width': width + 'px', + 'height': height + 'px' + } + }).inject(cache.contentBorderEl); + + if (this.options.shape == 'gauge'){ + cache.contentBorderEl.setStyle('borderWidth', 0); + } + + cache.contentEl = new Element('div', { + 'id': id + '_content', + 'class': 'mochaContent' + }).inject(cache.contentWrapperEl); + + if (this.options.useCanvas == true && Browser.Engine.trident != true) { + cache.canvasEl = new Element('canvas', { + 'id': id + '_canvas', + 'class': 'mochaCanvas', + 'width': 10, + 'height': 10 + }).inject(this.windowEl); + } + + if (this.options.useCanvas == true && Browser.Engine.trident) { + cache.canvasEl = new Element('canvas', { + 'id': id + '_canvas', + 'class': 'mochaCanvas', + 'width': 50000, // IE8 excanvas requires these large numbers + 'height': 20000, + 'styles': { + 'position': 'absolute', + 'top': 0, + 'left': 0 + } + }).inject(this.windowEl); + + if (MUI.ieSupport == 'excanvas'){ + G_vmlCanvasManager.initElement(cache.canvasEl); + cache.canvasEl = this.windowEl.getElement('.mochaCanvas'); + } + } + + cache.controlsEl = new Element('div', { + 'id': id + '_controls', + 'class': 'mochaControls' + }).inject(cache.overlayEl, 'after'); + + if (options.useCanvasControls == true){ + cache.canvasControlsEl = new Element('canvas', { + 'id': id + '_canvasControls', + 'class': 'mochaCanvasControls', + 'width': 14, + 'height': 14 + }).inject(this.windowEl); + + if (Browser.Engine.trident && MUI.ieSupport == 'excanvas'){ + G_vmlCanvasManager.initElement(cache.canvasControlsEl); + cache.canvasControlsEl = this.windowEl.getElement('.mochaCanvasControls'); + } + } + + if (options.closable){ + cache.closeButtonEl = new Element('div', { + 'id': id + '_closeButton', + 'class': 'mochaCloseButton mochaWindowButton', + 'title': 'Close' + }).inject(cache.controlsEl); + } + + if (options.maximizable){ + cache.maximizeButtonEl = new Element('div', { + 'id': id + '_maximizeButton', + 'class': 'mochaMaximizeButton mochaWindowButton', + 'title': 'Maximize' + }).inject(cache.controlsEl); + } + + if (options.minimizable){ + cache.minimizeButtonEl = new Element('div', { + 'id': id + '_minimizeButton', + 'class': 'mochaMinimizeButton mochaWindowButton', + 'title': 'Minimize' + }).inject(cache.controlsEl); + } + + if (options.useSpinner == true && options.shape != 'gauge' && options.type != 'notification'){ + cache.spinnerEl = new Element('div', { + 'id': id + '_spinner', + 'class': 'mochaSpinner', + 'width': 16, + 'height': 16 + }).inject(this.windowEl, 'bottom'); + } + + if (this.options.shape == 'gauge'){ + cache.canvasHeaderEl = new Element('canvas', { + 'id': id + '_canvasHeader', + 'class': 'mochaCanvasHeader', + 'width': this.options.width, + 'height': 26 + }).inject(this.windowEl, 'bottom'); + + if (Browser.Engine.trident && MUI.ieSupport == 'excanvas'){ + G_vmlCanvasManager.initElement(cache.canvasHeaderEl); + cache.canvasHeaderEl = this.windowEl.getElement('.mochaCanvasHeader'); + } + } + + if ( Browser.Engine.trident ){ + cache.overlayEl.setStyle('zIndex', 2); + } + + // For Mac Firefox 2 to help reduce scrollbar bugs in that browser + if (Browser.Platform.mac && Browser.Engine.gecko){ + if (/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)){ + var ffversion = new Number(RegExp.$1); + if (ffversion < 3){ + cache.overlayEl.setStyle('overflow', 'auto'); + } + } + } + + if (options.resizable){ + cache.n = new Element('div', { + 'id': id + '_resizeHandle_n', + 'class': 'handle', + 'styles': { + 'top': 0, + 'left': 10, + 'cursor': 'n-resize' + } + }).inject(cache.overlayEl, 'after'); + + cache.ne = new Element('div', { + 'id': id + '_resizeHandle_ne', + 'class': 'handle corner', + 'styles': { + 'top': 0, + 'right': 0, + 'cursor': 'ne-resize' + } + }).inject(cache.overlayEl, 'after'); + + cache.e = new Element('div', { + 'id': id + '_resizeHandle_e', + 'class': 'handle', + 'styles': { + 'top': 10, + 'right': 0, + 'cursor': 'e-resize' + } + }).inject(cache.overlayEl, 'after'); + + cache.se = new Element('div', { + 'id': id + '_resizeHandle_se', + 'class': 'handle cornerSE', + 'styles': { + 'bottom': 0, + 'right': 0, + 'cursor': 'se-resize' + } + }).inject(cache.overlayEl, 'after'); + + cache.s = new Element('div', { + 'id': id + '_resizeHandle_s', + 'class': 'handle', + 'styles': { + 'bottom': 0, + 'left': 10, + 'cursor': 's-resize' + } + }).inject(cache.overlayEl, 'after'); + + cache.sw = new Element('div', { + 'id': id + '_resizeHandle_sw', + 'class': 'handle corner', + 'styles': { + 'bottom': 0, + 'left': 0, + 'cursor': 'sw-resize' + } + }).inject(cache.overlayEl, 'after'); + + cache.w = new Element('div', { + 'id': id + '_resizeHandle_w', + 'class': 'handle', + 'styles': { + 'top': 10, + 'left': 0, + 'cursor': 'w-resize' + } + }).inject(cache.overlayEl, 'after'); + + cache.nw = new Element('div', { + 'id': id + '_resizeHandle_nw', + 'class': 'handle corner', + 'styles': { + 'top': 0, + 'left': 0, + 'cursor': 'nw-resize' + } + }).inject(cache.overlayEl, 'after'); + } + $extend(this, cache); + + }, + /* + + Convert CSS colors to Canvas colors. + + */ + setColors: function(){ + + if (this.options.useCanvas == true) { + + // Set TitlebarColor + var pattern = /\?(.*?)\)/; + if (this.titleBarEl.getStyle('backgroundImage') != 'none'){ + var gradient = this.titleBarEl.getStyle('backgroundImage'); + gradient = gradient.match(pattern)[1]; + gradient = gradient.parseQueryString(); + var gradientFrom = gradient.from; + var gradientTo = gradient.to.replace(/\"/, ''); // IE7 was adding a quotation mark in. No idea why. + + this.options.headerStartColor = new Color(gradientFrom); + this.options.headerStopColor = new Color(gradientTo); + this.titleBarEl.addClass('replaced'); + } + else if (this.titleBarEl.getStyle('background-color') !== '' && this.titleBarEl.getStyle('background-color') !== 'transparent') { + this.options.headerStartColor = new Color(this.titleBarEl.getStyle('background-color')).mix('#fff', 20); + this.options.headerStopColor = new Color(this.titleBarEl.getStyle('background-color')).mix('#000', 20); + this.titleBarEl.addClass('replaced'); + } + + // Set BodyBGColor + if (this.windowEl.getStyle('background-color') !== '' && this.windowEl.getStyle('background-color') !== 'transparent') { + this.options.bodyBgColor = new Color(this.windowEl.getStyle('background-color')); + this.windowEl.addClass('replaced'); + } + + // Set resizableColor, the color of the SE corner resize handle + if (this.options.resizable && this.se.getStyle('background-color') !== '' && this.se.getStyle('background-color') !== 'transparent') { + this.options.resizableColor = new Color(this.se.getStyle('background-color')); + this.se.addClass('replaced'); + } + + } + + if (this.options.useCanvasControls == true){ + + if (this.minimizeButtonEl){ + + // Set Minimize Button Foreground Color + if (this.minimizeButtonEl.getStyle('color') !== '' && this.minimizeButtonEl.getStyle('color') !== 'transparent') { + this.options.minimizeColor = new Color(this.minimizeButtonEl.getStyle('color')); + } + + // Set Minimize Button Background Color + if (this.minimizeButtonEl.getStyle('background-color') !== '' && this.minimizeButtonEl.getStyle('background-color') !== 'transparent') { + this.options.minimizeBgColor = new Color(this.minimizeButtonEl.getStyle('background-color')); + this.minimizeButtonEl.addClass('replaced'); + } + + } + + if (this.maximizeButtonEl){ + + // Set Maximize Button Foreground Color + if (this.maximizeButtonEl.getStyle('color') !== '' && this.maximizeButtonEl.getStyle('color') !== 'transparent') { + this.options.maximizeColor = new Color(this.maximizeButtonEl.getStyle('color')); + } + + // Set Maximize Button Background Color + if (this.maximizeButtonEl.getStyle('background-color') !== '' && this.maximizeButtonEl.getStyle('background-color') !== 'transparent') { + this.options.maximizeBgColor = new Color(this.maximizeButtonEl.getStyle('background-color')); + this.maximizeButtonEl.addClass('replaced'); + } + + } + + if (this.closeButtonEl){ + + // Set Close Button Foreground Color + if (this.closeButtonEl.getStyle('color') !== '' && this.closeButtonEl.getStyle('color') !== 'transparent') { + this.options.closeColor = new Color(this.closeButtonEl.getStyle('color')); + } + + // Set Close Button Background Color + if (this.closeButtonEl.getStyle('background-color') !== '' && this.closeButtonEl.getStyle('background-color') !== 'transparent') { + this.options.closeBgColor = new Color(this.closeButtonEl.getStyle('background-color')); + this.closeButtonEl.addClass('replaced'); + } + + } + } + }, + /* + + Internal function: drawWindow + This is where we create the canvas GUI + + Arguments: + windowEl: the $(window) + shadows: (boolean) false will draw a window without shadows + + */ + drawWindow: function(shadows) { + + if (this.drawingWindow == true) return; + this.drawingWindow = true; + + if (this.isCollapsed){ + this.drawWindowCollapsed(shadows); + return; + } + + var windowEl = this.windowEl; + + var options = this.options; + var shadowBlur = options.shadowBlur; + var shadowBlur2x = shadowBlur * 2; + var shadowOffset = this.options.shadowOffset; + + this.overlayEl.setStyles({ + 'width': this.contentWrapperEl.offsetWidth + }); + + // Resize iframe when window is resized + if (this.iframeEl) { + this.iframeEl.setStyle('height', this.contentWrapperEl.offsetHeight); + } + + var borderHeight = this.contentBorderEl.getStyle('border-top').toInt() + this.contentBorderEl.getStyle('border-bottom').toInt(); + var toolbarHeight = this.toolbarWrapperEl ? this.toolbarWrapperEl.getStyle('height').toInt() + this.toolbarWrapperEl.getStyle('border-top').toInt() : 0; + var toolbar2Height = this.toolbar2WrapperEl ? this.toolbar2WrapperEl.getStyle('height').toInt() + this.toolbar2WrapperEl.getStyle('border-top').toInt() : 0; + + this.headerFooterShadow = options.headerHeight + options.footerHeight + shadowBlur2x; + var height = this.contentWrapperEl.getStyle('height').toInt() + this.headerFooterShadow + toolbarHeight + toolbar2Height + borderHeight; + var width = this.contentWrapperEl.getStyle('width').toInt() + shadowBlur2x; + this.windowEl.setStyles({ + 'height': height, + 'width': width + }); + + this.overlayEl.setStyles({ + 'height': height, + 'top': shadowBlur - shadowOffset.y, + 'left': shadowBlur - shadowOffset.x + }); + + if (this.options.useCanvas == true) { + if (Browser.Engine.trident) { + this.canvasEl.height = 20000; + this.canvasEl.width = 50000; + } + this.canvasEl.height = height; + this.canvasEl.width = width; + } + + // Part of the fix for IE6 select z-index bug + if (Browser.Engine.trident4){ + this.zIndexFixEl.setStyles({ + 'width': width, + 'height': height + }) + } + + this.titleBarEl.setStyles({ + 'width': width - shadowBlur2x, + 'height': options.headerHeight + }); + + // Make sure loading icon is placed correctly. + if (options.useSpinner == true && options.shape != 'gauge' && options.type != 'notification'){ + this.spinnerEl.setStyles({ + 'left': shadowBlur - shadowOffset.x + 3, + 'bottom': shadowBlur + shadowOffset.y + 4 + }); + } + + if (this.options.useCanvas != false) { + + // Draw Window + var ctx = this.canvasEl.getContext('2d'); + ctx.clearRect(0, 0, width, height); + + switch (options.shape) { + case 'box': + this.drawBox(ctx, width, height, shadowBlur, shadowOffset, shadows); + break; + case 'gauge': + this.drawGauge(ctx, width, height, shadowBlur, shadowOffset, shadows); + break; + } + + if (options.resizable){ + MUI.triangle( + ctx, + width - (shadowBlur + shadowOffset.x + 17), + height - (shadowBlur + shadowOffset.y + 18), + 11, + 11, + options.resizableColor, + 1.0 + ); + } + + // Invisible dummy object. The last element drawn is not rendered consistently while resizing in IE6 and IE7 + if (Browser.Engine.trident){ + MUI.triangle(ctx, 0, 0, 10, 10, options.resizableColor, 0); + } + } + + if (options.type != 'notification' && options.useCanvasControls == true){ + this.drawControls(width, height, shadows); + } + + // Resize panels if there are any + if (MUI.Desktop && this.contentWrapperEl.getChildren('.column').length != 0) { + MUI.rWidth(this.contentWrapperEl); + this.contentWrapperEl.getChildren('.column').each(function(column){ + MUI.panelHeight(column); + }); + } + + this.drawingWindow = false; + return this; + + }, + drawWindowCollapsed: function(shadows) { + + var windowEl = this.windowEl; + + var options = this.options; + var shadowBlur = options.shadowBlur; + var shadowBlur2x = shadowBlur * 2; + var shadowOffset = options.shadowOffset; + + var headerShadow = options.headerHeight + shadowBlur2x + 2; + var height = headerShadow; + var width = this.contentWrapperEl.getStyle('width').toInt() + shadowBlur2x; + this.windowEl.setStyle('height', height); + + this.overlayEl.setStyles({ + 'height': height, + 'top': shadowBlur - shadowOffset.y, + 'left': shadowBlur - shadowOffset.x + }); + + // Part of the fix for IE6 select z-index bug + if (Browser.Engine.trident4){ + this.zIndexFixEl.setStyles({ + 'width': width, + 'height': height + }); + } + + // Set width + this.windowEl.setStyle('width', width); + this.overlayEl.setStyle('width', width); + this.titleBarEl.setStyles({ + 'width': width - shadowBlur2x, + 'height': options.headerHeight + }); + + // Draw Window + if (this.options.useCanvas != false) { + this.canvasEl.height = height; + this.canvasEl.width = width; + + var ctx = this.canvasEl.getContext('2d'); + ctx.clearRect(0, 0, width, height); + + this.drawBoxCollapsed(ctx, width, height, shadowBlur, shadowOffset, shadows); + if (options.useCanvasControls == true) { + this.drawControls(width, height, shadows); + } + + // Invisible dummy object. The last element drawn is not rendered consistently while resizing in IE6 and IE7 + if (Browser.Engine.trident){ + MUI.triangle(ctx, 0, 0, 10, 10, options.resizableColor, 0); + } + } + + this.drawingWindow = false; + return this; + + }, + drawControls : function(width, height, shadows){ + var options = this.options; + var shadowBlur = options.shadowBlur; + var shadowOffset = options.shadowOffset; + var controlsOffset = options.controlsOffset; + + // Make sure controls are placed correctly. + this.controlsEl.setStyles({ + 'right': shadowBlur + shadowOffset.x + controlsOffset.right, + 'top': shadowBlur - shadowOffset.y + controlsOffset.top + }); + + this.canvasControlsEl.setStyles({ + 'right': shadowBlur + shadowOffset.x + controlsOffset.right, + 'top': shadowBlur - shadowOffset.y + controlsOffset.top + }); + + // Calculate X position for controlbuttons + //var mochaControlsWidth = 52; + this.closebuttonX = options.closable ? this.mochaControlsWidth - 7 : this.mochaControlsWidth + 12; + this.maximizebuttonX = this.closebuttonX - (options.maximizable ? 19 : 0); + this.minimizebuttonX = this.maximizebuttonX - (options.minimizable ? 19 : 0); + + var ctx2 = this.canvasControlsEl.getContext('2d'); + ctx2.clearRect(0, 0, 100, 100); + + if (this.options.closable){ + this.closebutton( + ctx2, + this.closebuttonX, + 7, + options.closeBgColor, + 1.0, + options.closeColor, + 1.0 + ); + } + if (this.options.maximizable){ + this.maximizebutton( + ctx2, + this.maximizebuttonX, + 7, + options.maximizeBgColor, + 1.0, + options.maximizeColor, + 1.0 + ); + } + if (this.options.minimizable){ + this.minimizebutton( + ctx2, + this.minimizebuttonX, + 7, + options.minimizeBgColor, + 1.0, + options.minimizeColor, + 1.0 + ); + } + // Invisible dummy object. The last element drawn is not rendered consistently while resizing in IE6 and IE7 + if (Browser.Engine.trident){ + MUI.circle(ctx2, 0, 0, 3, this.options.resizableColor, 0); + } + + }, + drawBox: function(ctx, width, height, shadowBlur, shadowOffset, shadows){ + + var options = this.options; + var shadowBlur2x = shadowBlur * 2; + var cornerRadius = this.options.cornerRadius; + + // This is the drop shadow. It is created onion style. + if ( shadows != false ) { + for (var x = 0; x <= shadowBlur; x++){ + MUI.roundedRect( + ctx, + shadowOffset.x + x, + shadowOffset.y + x, + width - (x * 2) - shadowOffset.x, + height - (x * 2) - shadowOffset.y, + cornerRadius + (shadowBlur - x), + [0, 0, 0], + x == shadowBlur ? .29 : .065 + (x * .01) + ); + } + } + // Window body. + this.bodyRoundedRect( + ctx, // context + shadowBlur - shadowOffset.x, // x + shadowBlur - shadowOffset.y, // y + width - shadowBlur2x, // width + height - shadowBlur2x, // height + cornerRadius, // corner radius + options.bodyBgColor // Footer color + ); + + if (this.options.type != 'notification'){ + // Window header. + this.topRoundedRect( + ctx, // context + shadowBlur - shadowOffset.x, // x + shadowBlur - shadowOffset.y, // y + width - shadowBlur2x, // width + options.headerHeight, // height + cornerRadius, // corner radius + options.headerStartColor, // Header gradient's top color + options.headerStopColor // Header gradient's bottom color + ); + } + }, + drawBoxCollapsed: function(ctx, width, height, shadowBlur, shadowOffset, shadows){ + + var options = this.options; + var shadowBlur2x = shadowBlur * 2; + var cornerRadius = options.cornerRadius; + + // This is the drop shadow. It is created onion style. + if ( shadows != false ){ + for (var x = 0; x <= shadowBlur; x++){ + MUI.roundedRect( + ctx, + shadowOffset.x + x, + shadowOffset.y + x, + width - (x * 2) - shadowOffset.x, + height - (x * 2) - shadowOffset.y, + cornerRadius + (shadowBlur - x), + [0, 0, 0], + x == shadowBlur ? .3 : .06 + (x * .01) + ); + } + } + + // Window header + this.topRoundedRect2( + ctx, // context + shadowBlur - shadowOffset.x, // x + shadowBlur - shadowOffset.y, // y + width - shadowBlur2x, // width + options.headerHeight + 2, // height + cornerRadius, // corner radius + options.headerStartColor, // Header gradient's top color + options.headerStopColor // Header gradient's bottom color + ); + + }, + drawGauge: function(ctx, width, height, shadowBlur, shadowOffset, shadows){ + var options = this.options; + var radius = (width * .5) - (shadowBlur) + 16; + if (shadows != false) { + for (var x = 0; x <= shadowBlur; x++){ + MUI.circle( + ctx, + width * .5 + shadowOffset.x, + (height + options.headerHeight) * .5 + shadowOffset.x, + (width *.5) - (x * 2) - shadowOffset.x, + [0, 0, 0], + x == shadowBlur ? .75 : .075 + (x * .04) + ); + } + } + MUI.circle( + ctx, + width * .5 - shadowOffset.x, + (height + options.headerHeight) * .5 - shadowOffset.y, + (width *.5) - shadowBlur, + options.bodyBgColor, + 1 + ); + + // Draw gauge header + this.canvasHeaderEl.setStyles({ + 'top': shadowBlur - shadowOffset.y, + 'left': shadowBlur - shadowOffset.x + }); + var ctx = this.canvasHeaderEl.getContext('2d'); + ctx.clearRect(0, 0, width, 100); + ctx.beginPath(); + ctx.lineWidth = 24; + ctx.lineCap = 'round'; + ctx.moveTo(13, 13); + ctx.lineTo(width - (shadowBlur*2) - 13, 13); + ctx.strokeStyle = 'rgba(0, 0, 0, .65)'; + ctx.stroke(); + }, + bodyRoundedRect: function(ctx, x, y, width, height, radius, rgb){ + ctx.fillStyle = 'rgba(' + rgb.join(',') + ', 1)'; + ctx.beginPath(); + ctx.moveTo(x, y + radius); + ctx.lineTo(x, y + height - radius); + ctx.quadraticCurveTo(x, y + height, x + radius, y + height); + ctx.lineTo(x + width - radius, y + height); + ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius); + ctx.lineTo(x + width, y + radius); + ctx.quadraticCurveTo(x + width, y, x + width - radius, y); + ctx.lineTo(x + radius, y); + ctx.quadraticCurveTo(x, y, x, y + radius); + ctx.fill(); + + }, + topRoundedRect: function(ctx, x, y, width, height, radius, headerStartColor, headerStopColor){ + var lingrad = ctx.createLinearGradient(0, 0, 0, height); + lingrad.addColorStop(0, 'rgb(' + headerStartColor.join(',') + ')'); + lingrad.addColorStop(1, 'rgb(' + headerStopColor.join(',') + ')'); + ctx.fillStyle = lingrad; + ctx.beginPath(); + ctx.moveTo(x, y); + ctx.lineTo(x, y + height); + ctx.lineTo(x + width, y + height); + ctx.lineTo(x + width, y + radius); + ctx.quadraticCurveTo(x + width, y, x + width - radius, y); + ctx.lineTo(x + radius, y); + ctx.quadraticCurveTo(x, y, x, y + radius); + ctx.fill(); + + }, + topRoundedRect2: function(ctx, x, y, width, height, radius, headerStartColor, headerStopColor){ + // Chrome is having trouble rendering the LinearGradient in this particular case + if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) { + ctx.fillStyle = 'rgba(' + headerStopColor.join(',') + ', 1)'; + } + else { + var lingrad = ctx.createLinearGradient(0, this.options.shadowBlur - 1, 0, height + this.options.shadowBlur + 3); + lingrad.addColorStop(0, 'rgb(' + headerStartColor.join(',') + ')'); + lingrad.addColorStop(1, 'rgb(' + headerStopColor.join(',') + ')'); + ctx.fillStyle = lingrad; + } + ctx.beginPath(); + ctx.moveTo(x, y + radius); + ctx.lineTo(x, y + height - radius); + ctx.quadraticCurveTo(x, y + height, x + radius, y + height); + ctx.lineTo(x + width - radius, y + height); + ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius); + ctx.lineTo(x + width, y + radius); + ctx.quadraticCurveTo(x + width, y, x + width - radius, y); + ctx.lineTo(x + radius, y); + ctx.quadraticCurveTo(x, y, x, y + radius); + ctx.fill(); + }, + maximizebutton: function(ctx, x, y, rgbBg, aBg, rgb, a){ + // Circle + ctx.beginPath(); + ctx.arc(x, y, 7, 0, Math.PI*2, true); + ctx.fillStyle = 'rgba(' + rgbBg.join(',') + ',' + aBg + ')'; + ctx.fill(); + // X sign + ctx.strokeStyle = 'rgba(' + rgb.join(',') + ',' + a + ')'; + ctx.lineWidth = 2; + ctx.beginPath(); + ctx.moveTo(x, y - 3.5); + ctx.lineTo(x, y + 3.5); + ctx.moveTo(x - 3.5, y); + ctx.lineTo(x + 3.5, y); + ctx.stroke(); + }, + closebutton: function(ctx, x, y, rgbBg, aBg, rgb, a){ + // Circle + ctx.beginPath(); + ctx.arc(x, y, 7, 0, Math.PI*2, true); + ctx.fillStyle = 'rgba(' + rgbBg.join(',') + ',' + aBg + ')'; + ctx.fill(); + // Plus sign + ctx.strokeStyle = 'rgba(' + rgb.join(',') + ',' + a + ')'; + ctx.lineWidth = 2; + ctx.beginPath(); + ctx.moveTo(x - 3, y - 3); + ctx.lineTo(x + 3, y + 3); + ctx.moveTo(x + 3, y - 3); + ctx.lineTo(x - 3, y + 3); + ctx.stroke(); + }, + minimizebutton: function(ctx, x, y, rgbBg, aBg, rgb, a){ + // Circle + ctx.beginPath(); + ctx.arc(x,y,7,0,Math.PI*2,true); + ctx.fillStyle = 'rgba(' + rgbBg.join(',') + ',' + aBg + ')'; + ctx.fill(); + // Minus sign + ctx.strokeStyle = 'rgba(' + rgb.join(',') + ',' + a + ')'; + ctx.lineWidth = 2; + ctx.beginPath(); + ctx.moveTo(x - 3.5, y); + ctx.lineTo(x + 3.5, y); + ctx.stroke(); + }, + setMochaControlsWidth: function(){ + this.mochaControlsWidth = 0; + var options = this.options; + if (options.minimizable){ + this.mochaControlsWidth += (this.minimizeButtonEl.getStyle('margin-left').toInt() + this.minimizeButtonEl.getStyle('width').toInt()); + } + if (options.maximizable){ + this.mochaControlsWidth += (this.maximizeButtonEl.getStyle('margin-left').toInt() + this.maximizeButtonEl.getStyle('width').toInt()); + } + if (options.closable){ + this.mochaControlsWidth += (this.closeButtonEl.getStyle('margin-left').toInt() + this.closeButtonEl.getStyle('width').toInt()); + } + this.controlsEl.setStyle('width', this.mochaControlsWidth); + if (options.useCanvasControls == true){ + this.canvasControlsEl.setProperty('width', this.mochaControlsWidth); + } + }, + /* + + Function: hideSpinner + Hides the spinner. + + Example: + (start code) + $('myWindow').retrieve('instance').hideSpinner(); + (end) + + */ + hideSpinner: function() { + if (this.spinnerEl) this.spinnerEl.hide(); + return this; + }, + /* + + Function: showSpinner + Shows the spinner. + + Example: + (start code) + $('myWindow').retrieve('instance').showSpinner(); + (end) + + */ + showSpinner: function(){ + if (this.spinnerEl) this.spinnerEl.show(); + return this; + }, + /* + + Function: close + Closes the window. This is an alternative to using MUI.Core.closeWindow(). + + Example: + (start code) + $('myWindow').retrieve('instance').close(); + (end) + + */ + close: function( ) { + if (!this.isClosing) MUI.closeWindow(this.windowEl); + return this; + }, + /* + + Function: minimize + Minimizes the window. + + Example: + (start code) + $('myWindow').retrieve('instance').minimize(); + (end) + + */ + minimize: function( ){ + MUI.Dock.minimizeWindow(this.windowEl); + return this; + }, + /* + + Function: maximize + Maximizes the window. + + Example: + (start code) + $('myWindow').retrieve('instance').maximize(); + (end) + + */ + maximize: function( ) { + if (this.isMinimized){ + MUI.Dock.restoreMinimized(this.windowEl); + } + MUI.Desktop.maximizeWindow(this.windowEl); + return this; + }, + /* + + Function: restore + Restores a minimized/maximized window to its original size. + + Example: + (start code) + $('myWindow').retrieve('instance').restore(); + (end) + + */ + restore: function() { + if ( this.isMinimized ) + MUI.Dock.restoreMinimized(this.windowEl); + else if ( this.isMaximized ) + MUI.Desktop.restoreWindow(this.windowEl); + return this; + }, + /* + + Function: resize + Resize a window. + + Notes: + If Advanced Effects are on the resize is animated. If centered is set to true the window remains centered as it resizes. + + Example: + (start code) + $('myWindow').retrieve('instance').resize({width:500,height:300,centered:true}); + (end) + + */ + resize: function(options){ + MUI.resizeWindow(this.windowEl, options); + return this; + }, + /* + + Function: center + Center a window. + + Example: + (start code) + $('myWindow').retrieve('instance').center(); + (end) + + */ + center: function() { + MUI.centerWindow(this.windowEl); + return this; + }, + + hide: function(){ + this.windowEl.setStyle('display', 'none'); + return this; + }, + + show: function(){ + this.windowEl.setStyle('display', 'block'); + return this; + } + +}); + +MUI.extend({ + /* + + Function: closeWindow + Closes a window. + + Syntax: + (start code) + MUI.closeWindow(); + (end) + + Arguments: + windowEl - the ID of the window to be closed + + Returns: + true - the window was closed + false - the window was not closed + + */ + closeWindow: function(windowEl){ + + var instance = windowEl.retrieve('instance'); + + // Does window exist and is not already in process of closing ? + if (windowEl != $(windowEl) || instance.isClosing) return; + + instance.isClosing = true; + instance.fireEvent('onClose', windowEl); + + if (instance.options.storeOnClose){ + this.storeOnClose(instance, windowEl); + return; + } + if (instance.check) instance.check.destroy(); + + if ((instance.options.type == 'modal' || instance.options.type == 'modal2') && Browser.Engine.trident4){ + $('modalFix').hide(); + } + + if (MUI.options.advancedEffects == false){ + if (instance.options.type == 'modal' || instance.options.type == 'modal2'){ + $('modalOverlay').setStyle('opacity', 0); + } + MUI.closingJobs(windowEl); + return true; + } + else { + // Redraws IE windows without shadows since IE messes up canvas alpha when you change element opacity + if (Browser.Engine.trident) instance.drawWindow(false); + if (instance.options.type == 'modal' || instance.options.type == 'modal2'){ + MUI.Modal.modalOverlayCloseMorph.start({ + 'opacity': 0 + }); + } + var closeMorph = new Fx.Morph(windowEl, { + duration: 120, + onComplete: function(){ + MUI.closingJobs(windowEl); + return true; + }.bind(this) + }); + closeMorph.start({ + 'opacity': .4 + }); + } + + }, + closingJobs: function(windowEl){ + + var instances = MUI.Windows.instances; + var instance = instances.get(windowEl.id); + windowEl.setStyle('visibility', 'hidden'); + // Destroy throws an error in IE8 + if (Browser.Engine.trident) { + windowEl.dispose(); + } + else { + windowEl.destroy(); + } + instance.fireEvent('onCloseComplete'); + + if (instance.options.type != 'notification'){ + var newFocus = this.getWindowWithHighestZindex(); + this.focusWindow(newFocus); + } + + instances.erase(instance.options.id); + if (this.loadingWorkspace == true) { + this.windowUnload(); + } + + if (MUI.Dock && $(MUI.options.dock) && instance.options.type == 'window') { + var currentButton = $(instance.options.id + '_dockTab'); + if (currentButton != null) { + MUI.Dock.dockSortables.removeItems(currentButton).destroy(); + } + // Need to resize everything in case the dock becomes smaller when a tab is removed + MUI.Desktop.setDesktopSize(); + } + }, + storeOnClose: function(instance, windowEl){ + + if (instance.check) instance.check.hide(); + + windowEl.setStyles({ + zIndex: -1 + }); + windowEl.addClass('windowClosed'); + windowEl.removeClass('mocha'); + + if (MUI.Dock && $(MUI.options.dock) && instance.options.type == 'window') { + var currentButton = $(instance.options.id + '_dockTab'); + if (currentButton != null) { + currentButton.hide(); + } + MUI.Desktop.setDesktopSize(); + } + + instance.fireEvent('onCloseComplete'); + + if (instance.options.type != 'notification'){ + var newFocus = this.getWindowWithHighestZindex(); + this.focusWindow(newFocus); + } + + instance.isClosing = false; + + }, + /* + + Function: closeAll + Close all open windows. + + */ + closeAll: function() { + $$('.mocha').each(function(windowEl){ + this.closeWindow(windowEl); + }.bind(this)); + }, + /* + + Function: collapseToggle + Collapses an expanded window. Expands a collapsed window. + + */ + collapseToggle: function(windowEl){ + var instance = windowEl.retrieve('instance'); + var handles = windowEl.getElements('.handle'); + if (instance.isMaximized == true) return; + if (instance.isCollapsed == false) { + instance.isCollapsed = true; + handles.hide(); + if ( instance.iframeEl ) { + instance.iframeEl.setStyle('visibility', 'hidden'); + } + instance.contentBorderEl.setStyles({ + visibility: 'hidden', + position: 'absolute', + top: -10000, + left: -10000 + }); + if(instance.toolbarWrapperEl){ + instance.toolbarWrapperEl.setStyles({ + visibility: 'hidden', + position: 'absolute', + top: -10000, + left: -10000 + }); + } + instance.drawWindowCollapsed(); + } + else { + instance.isCollapsed = false; + instance.drawWindow(); + instance.contentBorderEl.setStyles({ + visibility: 'visible', + position: null, + top: null, + left: null + }); + if(instance.toolbarWrapperEl){ + instance.toolbarWrapperEl.setStyles({ + visibility: 'visible', + position: null, + top: null, + left: null + }); + } + if ( instance.iframeEl ) { + instance.iframeEl.setStyle('visibility', 'visible'); + } + handles.show(); + } + }, + /* + + Function: toggleWindowVisibility + Toggle window visibility with Ctrl-Alt-Q. + + */ + toggleWindowVisibility: function(){ + MUI.Windows.instances.each(function(instance){ + if (instance.options.type == 'modal' || instance.options.type == 'modal2' || instance.isMinimized == true) return; + var id = $(instance.options.id); + if (id.getStyle('visibility') == 'visible'){ + if (instance.iframe){ + instance.iframeEl.setStyle('visibility', 'hidden'); + } + if (instance.toolbarEl){ + instance.toolbarWrapperEl.setStyle('visibility', 'hidden'); + } + instance.contentBorderEl.setStyle('visibility', 'hidden'); + id.setStyle('visibility', 'hidden'); + MUI.Windows.windowsVisible = false; + } + else { + id.setStyle('visibility', 'visible'); + instance.contentBorderEl.setStyle('visibility', 'visible'); + if (instance.iframe){ + instance.iframeEl.setStyle('visibility', 'visible'); + } + if (instance.toolbarEl){ + instance.toolbarWrapperEl.setStyle('visibility', 'visible'); + } + MUI.Windows.windowsVisible = true; + } + }.bind(this)); + + }, + focusWindow: function(windowEl, fireEvent){ + + // This is used with blurAll + MUI.Windows.focusingWindow = true; + var windowClicked = function(){ + MUI.Windows.focusingWindow = false; + }; + windowClicked.delay(170, this); + + // Only focus when needed + if ($$('.mocha').length == 0) return; + if (windowEl != $(windowEl) || windowEl.hasClass('isFocused')) return; + + var instances = MUI.Windows.instances; + var instance = instances.get(windowEl.id); + + if (instance.options.type == 'notification'){ + windowEl.setStyle('zIndex', 11001); + return; + }; + + MUI.Windows.indexLevel += 2; + windowEl.setStyle('zIndex', MUI.Windows.indexLevel); + + // Used when dragging and resizing windows + $('windowUnderlay').setStyle('zIndex', MUI.Windows.indexLevel - 1).inject($(windowEl),'after'); + + // Fire onBlur for the window that lost focus. + instances.each(function(instance){ + if (instance.windowEl.hasClass('isFocused')){ + instance.fireEvent('onBlur', instance.windowEl); + } + instance.windowEl.removeClass('isFocused'); + }); + + if (MUI.Dock && $(MUI.options.dock) && instance.options.type == 'window') { + MUI.Dock.makeActiveTab(); + } + windowEl.addClass('isFocused'); + + if (fireEvent != false){ + instance.fireEvent('onFocus', windowEl); + } + + }, + getWindowWithHighestZindex: function(){ + this.highestZindex = 0; + $$('.mocha').each(function(element){ + this.zIndex = element.getStyle('zIndex'); + if (this.zIndex >= this.highestZindex) { + this.highestZindex = this.zIndex; + } + }.bind(this)); + $$('.mocha').each(function(element){ + if (element.getStyle('zIndex') == this.highestZindex) { + this.windowWithHighestZindex = element; + } + }.bind(this)); + return this.windowWithHighestZindex; + }, + blurAll: function(){ + if (MUI.Windows.focusingWindow == false) { + $$('.mocha').each(function(windowEl){ + var instance = windowEl.retrieve('instance'); + if (instance.options.type != 'modal' && instance.options.type != 'modal2'){ + windowEl.removeClass('isFocused'); + } + }); + $$('.dockTab').removeClass('activeDockTab'); + } + }, + centerWindow: function(windowEl){ + + if(!windowEl){ + MUI.Windows.instances.each(function(instance){ + if (instance.windowEl.hasClass('isFocused')){ + windowEl = instance.windowEl; + } + }); + } + + var instance = windowEl.retrieve('instance'); + var options = instance.options; + var dimensions = options.container.getCoordinates(); + + var windowPosTop = window.getScroll().y + (window.getSize().y * .5) - (windowEl.offsetHeight * .5); + if (windowPosTop < -instance.options.shadowBlur){ + windowPosTop = -instance.options.shadowBlur; + } + var windowPosLeft = (dimensions.width * .5) - (windowEl.offsetWidth * .5); + if (windowPosLeft < -instance.options.shadowBlur){ + windowPosLeft = -instance.options.shadowBlur; + } + if (MUI.options.advancedEffects == true){ + instance.morph.start({ + 'top': windowPosTop, + 'left': windowPosLeft + }); + } + else { + windowEl.setStyles({ + 'top': windowPosTop, + 'left': windowPosLeft + }); + } + }, + resizeWindow: function(windowEl, options){ + var instance = windowEl.retrieve('instance'); + + $extend({ + width: null, + height: null, + top: null, + left: null, + centered: true + }, options); + + var oldWidth = windowEl.getStyle('width').toInt(); + var oldHeight = windowEl.getStyle('height').toInt(); + var oldTop = windowEl.getStyle('top').toInt(); + var oldLeft = windowEl.getStyle('left').toInt(); + + if (options.centered){ + var top = options.top || oldTop - ((options.height - oldHeight) * .5); + var left = options.left || oldLeft - ((options.width - oldWidth) * .5); + } + else { + var top = options.top || oldTop; + var left = options.left || oldLeft; + } + + if (MUI.options.advancedEffects == false){ + windowEl.setStyles({ + 'top': top, + 'left': left + }); + instance.contentWrapperEl.setStyles({ + 'height': options.height, + 'width': options.width + }); + instance.drawWindow(); + // Show iframe + if (instance.iframeEl){ + if (!Browser.Engine.trident) { + instance.iframeEl.setStyle('visibility', 'visible'); + } + else { + instance.iframeEl.show(); + } + } + } + else { + windowEl.retrieve('resizeMorph').start({ + '0': { 'height': options.height, + 'width': options.width + }, + '1': { 'top': top, + 'left': left + } + }); + } + return instance; + }, + /* + + Internal Function: dynamicResize + Use with a timer to resize a window as the window's content size changes, such as with an accordian. + + */ + dynamicResize: function(windowEl){ + var instance = windowEl.retrieve('instance'); + var contentWrapperEl = instance.contentWrapperEl; + var contentEl = instance.contentEl; + + contentWrapperEl.setStyles({ + 'height': contentEl.offsetHeight, + 'width': contentEl.offsetWidth + }); + instance.drawWindow(); + } +}); + +// Toggle window visibility with Ctrl-Alt-Q +document.addEvent('keydown', function(event){ + if (event.key == 'q' && event.control && event.alt) { + MUI.toggleWindowVisibility(); + } +}); +/* + +Script: Modal.js + Create modal dialog windows. + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Requires: + Core.js, Window.js + +See Also: + + +*/ + +MUI.files[MUI.path.source + 'Window/Modal.js'] = 'loaded'; + +MUI.Modal = new Class({ + + Extends: MUI.Window, + + options: { + type: 'modal' + }, + + initialize: function(options){ + + if (!$('modalOverlay')){ + this.modalInitialize(); + + window.addEvent('resize', function(){ + this.setModalSize(); + }.bind(this)); + } + this.parent(options); + + }, + modalInitialize: function(){ + var modalOverlay = new Element('div', { + 'id': 'modalOverlay', + 'styles': { + 'height': document.getCoordinates().height, + 'opacity': .6 + } + }).inject(document.body); + + modalOverlay.setStyles({ + 'position': Browser.Engine.trident4 ? 'absolute' : 'fixed' + }); + + modalOverlay.addEvent('click', function(e){ + var instance = MUI.Windows.instances.get(MUI.currentModal.id); + if (instance.options.modalOverlayClose == true) { + MUI.closeWindow(MUI.currentModal); + } + }); + + if (Browser.Engine.trident4){ + var modalFix = new Element('iframe', { + 'id': 'modalFix', + 'scrolling': 'no', + 'marginWidth': 0, + 'marginHeight': 0, + 'src': '', + 'styles': { + 'height': document.getCoordinates().height + } + }).inject(document.body); + } + + MUI.Modal.modalOverlayOpenMorph = new Fx.Morph($('modalOverlay'), { + 'duration': 150 + }); + MUI.Modal.modalOverlayCloseMorph = new Fx.Morph($('modalOverlay'), { + 'duration': 150, + onComplete: function(){ + $('modalOverlay').hide(); + if (Browser.Engine.trident4){ + $('modalFix').hide(); + } + }.bind(this) + }); + }, + setModalSize: function(){ + $('modalOverlay').setStyle('height', document.getCoordinates().height); + if (Browser.Engine.trident4){ + $('modalFix').setStyle('height', document.getCoordinates().height); + } + } + +}); +/* + +Script: Windows-from-html.js + Create windows from html markup in page. + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Requires: + Core.js, Window.js + +Example: + HTML markup. + (start code) +
+

My Window

+

My Window Content

+
+ (end) + +See Also: + + +*/ + +MUI.files[MUI.path.source + 'Window/Windows-from-html.js'] = 'loaded'; + +MUI.extend({ + NewWindowsFromHTML: function(){ + $$('.mocha').each(function(el) { + // Get the window title and destroy that element, so it does not end up in window content + if ( Browser.Engine.presto || Browser.Engine.trident5 ){ + el.hide(); // Required by Opera, and probably IE7 + } + var title = el.getElement('h3.mochaTitle'); + + if(Browser.Engine.presto) el.show(); + + var elDimensions = el.getStyles('height', 'width'); + var properties = { + id: el.getProperty('id'), + height: elDimensions.height.toInt(), + width: elDimensions.width.toInt(), + x: el.getStyle('left').toInt(), + y: el.getStyle('top').toInt() + }; + // If there is a title element, set title and destroy the element so it does not end up in window content + if ( title ) { + properties.title = title.innerHTML; + title.destroy(); + } + + // Get content and destroy the element + properties.content = el.innerHTML; + el.destroy(); + + // Create window + new MUI.Window(properties, true); + }.bind(this)); + } +}); +/* + +Script: Windows-from-json.js + Create one or more windows from JSON data. You can define all the same properties as you can for new MUI.Window(). Undefined properties are set to their defaults. + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Syntax: + (start code) + MUI.newWindowsFromJSON(properties); + (end) + +Example: + (start code) + MUI.jsonWindows = function(){ + var url = 'data/json-windows-data.js'; + var request = new Request.JSON({ + url: url, + method: 'get', + onComplete: function(properties) { + MUI.newWindowsFromJSON(properties.windows); + } + }).send(); + } + (end) + +Note: + Windows created from JSON are not compatible with the current cookie based version + of Save and Load Workspace. + +See Also: + + +*/ + +MUI.files[MUI.path.source + 'Window/Windows-from-json.js'] = 'loaded'; + +MUI.extend({ + newWindowsFromJSON: function(newWindows){ + newWindows.each(function(options) { + var temp = new Hash(options); + temp.each( function(value, key, hash) { + if ($type(value) != 'string') return; + if (value.substring(0,8) == 'function'){ + eval("options." + key + " = " + value); + } + }); + new MUI.Window(options); + }); + } +}); +/* + +Script: Arrange-cascade.js + Cascade windows. + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Requires: + Core.js, Window.js + +Syntax: + (start code) + MUI.arrangeCascade(); + (end) + +*/ + +MUI.files[MUI.path.source + 'Window/Arrange-cascade.js'] = 'loaded'; + +MUI.extend({ + arrangeCascade: function(){ + + var viewportTopOffset = 30; // Use a negative number if neccessary to place first window where you want it + var viewportLeftOffset = 20; + var windowTopOffset = 50; // Initial vertical spacing of each window + var windowLeftOffset = 40; + + // See how much space we have to work with + var coordinates = document.getCoordinates(); + + var openWindows = 0; + MUI.Windows.instances.each(function(instance){ + if (!instance.isMinimized && instance.options.draggable) openWindows ++; + }); + + if ((windowTopOffset * (openWindows + 1)) >= (coordinates.height - viewportTopOffset)) { + var topOffset = (coordinates.height - viewportTopOffset) / (openWindows + 1); + } + else { + var topOffset = windowTopOffset; + } + + if ((windowLeftOffset * (openWindows + 1)) >= (coordinates.width - viewportLeftOffset - 20)) { + var leftOffset = (coordinates.width - viewportLeftOffset - 20) / (openWindows + 1); + } + else { + var leftOffset = windowLeftOffset; + } + + var x = viewportLeftOffset; + var y = viewportTopOffset; + $$('.mocha').each(function(windowEl){ + var instance = windowEl.retrieve('instance'); + if (!instance.isMinimized && !instance.isMaximized && instance.options.draggable){ + id = windowEl.id; + MUI.focusWindow(windowEl); + x += leftOffset; + y += topOffset; + + if (MUI.options.advancedEffects == false){ + windowEl.setStyles({ + 'top': y, + 'left': x + }); + } + else { + var cascadeMorph = new Fx.Morph(windowEl, { + 'duration': 550 + }); + cascadeMorph.start({ + 'top': y, + 'left': x + }); + } + } + }.bind(this)); + } +}); +/* + +Script: Arrange-tile.js + Cascade windows. + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +Authors: + Harry Roberts and Greg Houston + +License: + MIT-style license. + +Requires: + Core.js, Window.js + +Syntax: + (start code) + MUI.arrangeTile(); + (end) + +*/ + +MUI.files[MUI.path.source + 'Window/Arrange-tile.js'] = 'loaded'; + +MUI.extend({ + arrangeTile: function(){ + + var viewportTopOffset = 30; // Use a negative number if neccessary to place first window where you want it + var viewportLeftOffset = 20; + + var x = 10; + var y = 80; + + var instances = MUI.Windows.instances; + + var windowsNum = 0; + + instances.each(function(instance){ + if (!instance.isMinimized && !instance.isMaximized){ + windowsNum++; + } + }); + + var cols = 3; + var rows = Math.ceil(windowsNum / cols); + + var coordinates = document.getCoordinates(); + + var col_width = ((coordinates.width - viewportLeftOffset) / cols); + var col_height = ((coordinates.height - viewportTopOffset) / rows); + + var row = 0; + var col = 0; + + instances.each(function(instance){ + if (!instance.isMinimized && !instance.isMaximized && instance.options.draggable ){ + + var content = instance.contentWrapperEl; + var content_coords = content.getCoordinates(); + var window_coords = instance.windowEl.getCoordinates(); + + // Calculate the amount of padding around the content window + var padding_top = content_coords.top - window_coords.top; + var padding_bottom = window_coords.height - content_coords.height - padding_top; + var padding_left = content_coords.left - window_coords.left; + var padding_right = window_coords.width - content_coords.width - padding_left; + + /* + + // This resizes the windows + if (instance.options.shape != 'gauge' && instance.options.resizable == true){ + var width = (col_width - 3 - padding_left - padding_right); + var height = (col_height - 3 - padding_top - padding_bottom); + + if (width > instance.options.resizeLimit.x[0] && width < instance.options.resizeLimit.x[1]){ + content.setStyle('width', width); + } + if (height > instance.options.resizeLimit.y[0] && height < instance.options.resizeLimit.y[1]){ + content.setStyle('height', height); + } + + }*/ + + var left = (x + (col * col_width)); + var top = (y + (row * col_height)); + + instance.drawWindow(); + + MUI.focusWindow(instance.windowEl); + + if (MUI.options.advancedEffects == false){ + instance.windowEl.setStyles({ + 'top': top, + 'left': left + }); + } + else { + var tileMorph = new Fx.Morph(instance.windowEl, { + 'duration': 550 + }); + tileMorph.start({ + 'top': top, + 'left': left + }); + } + + if (++col === cols) { + row++; + col = 0; + } + } + }.bind(this)); + } +}); +/* + +Script: Tabs.js + Functionality for window tabs. + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Requires: + Core.js, Window.js (for tabbed windows) or Layout.js (for tabbed panels) + +*/ + +MUI.files[MUI.path.source + 'Components/Tabs.js'] = 'loaded'; + +MUI.extend({ + /* + + Function: initializeTabs + Add click event to each list item that fires the selected function. + + */ + initializeTabs: function(el){ + $(el).setStyle('list-style', 'none'); // This is to fix a glitch that occurs in IE8 RC1 when dynamically switching themes + $(el).getElements('li').addEvent('click', function(e){ + MUI.selected(this, el); + }); + }, + /* + + Function: selected + Add "selected" class to current list item and remove it from sibling list items. + + Syntax: + (start code) + selected(el, parent); + (end) + + Arguments: + el - the list item + parent - the ul + + */ + selected: function(el, parent){ + $(parent).getChildren().each(function(listitem){ + listitem.removeClass('selected'); + }); + el.addClass('selected'); + } +}); + +/* + +Script: Layout.js + Create web application layouts. Enables window maximize. + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Requires: + Core.js + +*/ + +MUI.files[MUI.path.source + 'Layout/Layout.js'] = 'loaded'; + +MUI.extend({ + Columns: { + instances: new Hash(), + columnIDCount: 0 // Used for columns without an ID defined by the user + }, + Panels: { + instances: new Hash(), + panelIDCount: 0 // Used for panels without an ID defined by the user + } +}); + +MUI.Desktop = { + + options: { + // Naming options: + // If you change the IDs of the MochaUI Desktop containers in your HTML, you need to change them here as well. + desktop: 'desktop', + desktopHeader: 'desktopHeader', + desktopFooter: 'desktopFooter', + desktopNavBar: 'desktopNavbar', + pageWrapper: 'pageWrapper', + page: 'page', + desktopFooter: 'desktopFooterWrapper' + }, + initialize: function(){ + + this.desktop = $(this.options.desktop); + this.desktopHeader = $(this.options.desktopHeader); + this.desktopNavBar = $(this.options.desktopNavBar); + this.pageWrapper = $(this.options.pageWrapper); + this.page = $(this.options.page); + this.desktopFooter = $(this.options.desktopFooter); + + if (this.desktop) { + ($$('body')).setStyles({ + overflow: 'hidden', + height: '100%', + margin: 0 + }); + ($$('html')).setStyles({ + overflow: 'hidden', + height: '100%' + }); + } + + // This is run on dock initialize so no need to do it twice. + if (!MUI.Dock){ + this.setDesktopSize(); + } + this.menuInitialize(); + + // Resize desktop, page wrapper, modal overlay, and maximized windows when browser window is resized + window.addEvent('resize', function(e){ + this.onBrowserResize(); + }.bind(this)); + + if (MUI.myChain){ + MUI.myChain.callChain(); + } + + }, + menuInitialize: function(){ + // Fix for dropdown menus in IE6 + if (Browser.Engine.trident4 && this.desktopNavBar){ + this.desktopNavBar.getElements('li').each(function(element) { + element.addEvent('mouseenter', function(){ + this.addClass('ieHover'); + }); + element.addEvent('mouseleave', function(){ + this.removeClass('ieHover'); + }); + }); + }; + }, + onBrowserResize: function(){ + this.setDesktopSize(); + // Resize maximized windows to fit new browser window size + setTimeout( function(){ + MUI.Windows.instances.each(function(instance){ + if (instance.isMaximized){ + + // Hide iframe while resize for better performance + if ( instance.iframeEl ){ + instance.iframeEl.setStyle('visibility', 'hidden'); + } + + var coordinates = document.getCoordinates(); + var borderHeight = instance.contentBorderEl.getStyle('border-top').toInt() + instance.contentBorderEl.getStyle('border-bottom').toInt(); + var toolbarHeight = instance.toolbarWrapperEl ? instance.toolbarWrapperEl.getStyle('height').toInt() + instance.toolbarWrapperEl.getStyle('border-top').toInt() : 0; + instance.contentWrapperEl.setStyles({ + 'height': coordinates.height - instance.options.headerHeight - instance.options.footerHeight - borderHeight - toolbarHeight, + 'width': coordinates.width + }); + + instance.drawWindow(); + if ( instance.iframeEl ){ + instance.iframeEl.setStyles({ + 'height': instance.contentWrapperEl.getStyle('height') + }); + instance.iframeEl.setStyle('visibility', 'visible'); + } + + } + }.bind(this)); + }.bind(this), 100); + }, + setDesktopSize: function(){ + var windowDimensions = window.getCoordinates(); + + // var dock = $(MUI.options.dock); + var dockWrapper = $(MUI.options.dockWrapper); + + // Setting the desktop height may only be needed by IE7 + if (this.desktop){ + this.desktop.setStyle('height', windowDimensions.height); + } + + // Set pageWrapper height so the dock doesn't cover the pageWrapper scrollbars. + if (this.pageWrapper) { + var dockOffset = MUI.dockVisible ? dockWrapper.offsetHeight : 0; + var pageWrapperHeight = windowDimensions.height; + pageWrapperHeight -= this.pageWrapper.getStyle('border-top').toInt(); + pageWrapperHeight -= this.pageWrapper.getStyle('border-bottom').toInt(); + if (this.desktopHeader){ pageWrapperHeight -= this.desktopHeader.offsetHeight; } + if (this.desktopFooter){ pageWrapperHeight -= this.desktopFooter.offsetHeight; } + pageWrapperHeight -= dockOffset; + + if (pageWrapperHeight < 0){ + pageWrapperHeight = 0; + } + this.pageWrapper.setStyle('height', pageWrapperHeight); + } + + if (MUI.Columns.instances.getKeys().length > 0){ // Conditional is a fix for a bug in IE6 in the no toolbars demo. + MUI.Desktop.resizePanels(); + } + }, + resizePanels: function(){ + MUI.panelHeight(); + MUI.rWidth(); + }, + /* + + Function: maximizeWindow + Maximize a window. + + Syntax: + (start code) + MUI.Desktop.maximizeWindow(windowEl); + (end) + + */ + maximizeWindow: function(windowEl){ + + var instance = MUI.Windows.instances.get(windowEl.id); + var options = instance.options; + var windowDrag = instance.windowDrag; + + // If window no longer exists or is maximized, stop + if (windowEl != $(windowEl) || instance.isMaximized ) return; + + if (instance.isCollapsed){ + MUI.collapseToggle(windowEl); + } + + instance.isMaximized = true; + + // If window is restricted to a container, it should not be draggable when maximized. + if (instance.options.restrict){ + windowDrag.detach(); + if (options.resizable) { + instance.detachResizable(); + } + instance.titleBarEl.setStyle('cursor', 'default'); + } + + // If the window has a container that is not the desktop + // temporarily move the window to the desktop while it is minimized. + if (options.container != this.desktop){ + this.desktop.grab(windowEl); + if (this.options.restrict){ + windowDrag.container = this.desktop; + } + } + + // Save original position + instance.oldTop = windowEl.getStyle('top'); + instance.oldLeft = windowEl.getStyle('left'); + + var contentWrapperEl = instance.contentWrapperEl; + + // Save original dimensions + contentWrapperEl.oldWidth = contentWrapperEl.getStyle('width'); + contentWrapperEl.oldHeight = contentWrapperEl.getStyle('height'); + + // Hide iframe + // Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues + if ( instance.iframeEl ) { + if (!Browser.Engine.trident) { + instance.iframeEl.setStyle('visibility', 'hidden'); + } + else { + instance.iframeEl.hide(); + } + } + + var windowDimensions = document.getCoordinates(); + var options = instance.options; + var shadowBlur = options.shadowBlur; + var shadowOffset = options.shadowOffset; + var newHeight = windowDimensions.height - options.headerHeight - options.footerHeight; + newHeight -= instance.contentBorderEl.getStyle('border-top').toInt(); + newHeight -= instance.contentBorderEl.getStyle('border-bottom').toInt(); + newHeight -= (instance.toolbarWrapperEl ? instance.toolbarWrapperEl.getStyle('height').toInt() + instance.toolbarWrapperEl.getStyle('border-top').toInt() : 0); + + MUI.resizeWindow(windowEl, { + width: windowDimensions.width, + height: newHeight, + top: shadowOffset.y - shadowBlur, + left: shadowOffset.x - shadowBlur + }); + instance.fireEvent('onMaximize', windowEl); + + if (instance.maximizeButtonEl) { + instance.maximizeButtonEl.setProperty('title', 'Restore'); + } + MUI.focusWindow(windowEl); + + }, + /* + + Function: restoreWindow + Restore a maximized window. + + Syntax: + (start code) + MUI.Desktop.restoreWindow(windowEl); + (end) + + */ + restoreWindow: function(windowEl){ + + var instance = windowEl.retrieve('instance'); + + // Window exists and is maximized ? + if (windowEl != $(windowEl) || !instance.isMaximized) return; + + var options = instance.options; + instance.isMaximized = false; + + if (options.restrict){ + instance.windowDrag.attach(); + if (options.resizable){ + instance.reattachResizable(); + } + instance.titleBarEl.setStyle('cursor', 'move'); + } + + // Hide iframe + // Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues + if ( instance.iframeEl ) { + if (!Browser.Engine.trident) { + instance.iframeEl.setStyle('visibility', 'hidden'); + } + else { + instance.iframeEl.hide(); + } + } + + var contentWrapperEl = instance.contentWrapperEl; + + MUI.resizeWindow(windowEl,{ + width: contentWrapperEl.oldWidth, + height: contentWrapperEl.oldHeight, + top: instance.oldTop, + left: instance.oldLeft + }); + instance.fireEvent('onRestore', windowEl); + + if (instance.maximizeButtonEl){ + instance.maximizeButtonEl.setProperty('title', 'Maximize'); + } + } +}; + +/* + +Class: Column + Create a column. Columns should be created from left to right. + +Syntax: +(start code) + MUI.Column(); +(end) + +Arguments: + options + +Options: + id - The ID of the column. This must be set when creating the column. + container - Defaults to MUI.Desktop.pageWrapper. + placement - Can be 'right', 'main', or 'left'. There must be at least one column with the 'main' option. + width - 'main' column is fluid and should not be given a width. + resizeLimit - resizelimit of a 'right' or 'left' column. + sortable - (boolean) Whether the panels can be reordered via drag and drop. + onResize - (function) Fired when the column is resized. + onCollapse - (function) Fired when the column is collapsed. + onExpand - (function) Fired when the column is expanded. + +*/ +MUI.Column = new Class({ + + Implements: [Events, Options], + + options: { + id: null, + container: null, + placement: null, + width: null, + resizeLimit: [], + sortable: true, + + // Events + onResize: $empty, + onCollapse: $empty, + onExpand: $empty + + }, + + initialize: function(options){ + this.setOptions(options); + + $extend(this, { + timestamp: $time(), + isCollapsed: false, + oldWidth: 0 + }); + + // If column has no ID, give it one. + if (this.options.id == null){ + this.options.id = 'column' + (++MUI.Columns.columnIDCount); + } + + // Shorten object chain + var options = this.options; + var instances = MUI.Columns.instances; + var instanceID = instances.get(options.id); + + if (options.container == null) { + options.container = MUI.Desktop.pageWrapper + } + else { + $(options.container).setStyle('overflow', 'hidden'); + } + + if (typeof this.options.container == 'string'){ + this.options.container = $(this.options.container); + } + + // Check to see if there is already a class instance for this Column + if (instanceID){ + var instance = instanceID; + } + + // Check if column already exists + if ( this.columnEl ){ + return; + } + else { + instances.set(options.id, this); + } + + // If loading columns into a panel, hide the regular content container. + if ($(options.container).getElement('.pad') != null) { + $(options.container).getElement('.pad').hide(); + } + + // If loading columns into a window, hide the regular content container. + if ($(options.container).getElement('.mochaContent') != null) { + $(options.container).getElement('.mochaContent').hide(); + } + + this.columnEl = new Element('div', { + 'id': this.options.id, + 'class': 'column expanded', + 'styles': { + 'width': options.placement == 'main' ? null : options.width + } + }).inject($(options.container)); + + this.columnEl.store('instance', this); + + var parent = this.columnEl.getParent(); + var columnHeight = parent.getStyle('height').toInt(); + this.columnEl.setStyle('height', columnHeight); + + if (this.options.sortable){ + if (!this.options.container.retrieve('sortables')){ + var sortables = new Sortables(this.columnEl, { + opacity: 1, + handle: '.panel-header', + constrain: false, + revert: false, + onSort: function(){ + $$('.column').each(function(column){ + column.getChildren('.panelWrapper').each(function(panelWrapper){ + panelWrapper.getElement('.panel').removeClass('bottomPanel'); + }); + if (column.getChildren('.panelWrapper').getLast()){ + column.getChildren('.panelWrapper').getLast().getElement('.panel').addClass('bottomPanel'); + } + MUI.panelHeight(); + }.bind(this)); + }.bind(this) + }); + this.options.container.store('sortables', sortables); + } + else { + this.options.container.retrieve('sortables').addLists(this.columnEl); + } + } + + if (options.placement == 'main'){ + this.columnEl.addClass('rWidth'); + } + + switch (this.options.placement) { + case 'left': + this.handleEl = new Element('div', { + 'id': this.options.id + '_handle', + 'class': 'columnHandle' + }).inject(this.columnEl, 'after'); + + this.handleIconEl = new Element('div', { + 'id': options.id + '_handle_icon', + 'class': 'handleIcon' + }).inject(this.handleEl); + + addResizeRight(this.columnEl, options.resizeLimit[0], options.resizeLimit[1]); + break; + case 'right': + this.handleEl = new Element('div', { + 'id': this.options.id + '_handle', + 'class': 'columnHandle' + }).inject(this.columnEl, 'before'); + + this.handleIconEl = new Element('div', { + 'id': options.id + '_handle_icon', + 'class': 'handleIcon' + }).inject(this.handleEl); + addResizeLeft(this.columnEl, options.resizeLimit[0], options.resizeLimit[1]); + break; + } + + if (this.handleEl != null){ + this.handleEl.addEvent('dblclick', function(){ + this.columnToggle(); + }.bind(this)); + } + + MUI.rWidth(); + + }, + columnToggle: function(){ + var column = this.columnEl; + + // Collapse + if (this.isCollapsed == false){ + this.oldWidth = column.getStyle('width').toInt(); + + this.resize.detach(); + this.handleEl.removeEvents('dblclick'); + this.handleEl.addEvent('click', function(){ + this.columnToggle(); + }.bind(this)); + this.handleEl.setStyle('cursor', 'pointer').addClass('detached'); + + column.setStyle('width', 0); + this.isCollapsed = true; + column.addClass('collapsed'); + column.removeClass('expanded'); + MUI.rWidth(); + this.fireEvent('onCollapse'); + } + // Expand + else { + column.setStyle('width', this.oldWidth); + this.isCollapsed = false; + column.addClass('expanded'); + column.removeClass('collapsed'); + + this.handleEl.removeEvents('click'); + this.handleEl.addEvent('dblclick', function(){ + this.columnToggle(); + }.bind(this)); + this.resize.attach(); + this.handleEl.setStyle('cursor', Browser.Engine.webkit ? 'col-resize' : 'e-resize').addClass('attached'); + + MUI.rWidth(); + this.fireEvent('onExpand'); + } + } +}); +MUI.Column.implement(new Options, new Events); + +/* + +Class: Panel + Create a panel. Panels go one on top of another in columns. Create your columns first and then add your panels. Panels should be created from top to bottom, left to right. + +Syntax: +(start code) + MUI.Panel(); +(end) + +Arguments: + options + +Options: + id - The ID of the panel. This must be set when creating the panel. + column - Where to inject the panel. This must be set when creating the panel. + loadMethod - ('html', 'xhr', or 'iframe') Defaults to 'html' if there is no contentURL. Defaults to 'xhr' if there is a contentURL. You only really need to set this if using the 'iframe' method. May create a 'panel' loadMethod in the future. + contentURL - Used if loadMethod is set to 'xhr' or 'iframe'. + method - ('get', or 'post') The method used to get the data. Defaults to 'get'. + data - (hash) Data to send with the URL. Defaults to null. + evalScripts - (boolean) An xhr loadMethod option. Defaults to true. + evalResponse - (boolean) An xhr loadMethod option. Defaults to false. + content - (string or element) An html loadMethod option. + tabsURL - (url) + tabsData - (hash) Data to send with the URL. Defaults to null. + tabsOnload - (function) + header - (boolean) Display the panel header or not + headerToolbox: (boolean) + headerToolboxURL: (url) + headerToolboxOnload: (function) + height - (number) Height of content area. + addClass - (string) Add a class to the panel. + scrollbars - (boolean) + padding - (object) + collapsible - (boolean) + onBeforeBuild - (function) Fired before the panel is created. + onContentLoaded - (function) Fired after the panel's conten is loaded. + onResize - (function) Fired when the panel is resized. + onCollapse - (function) Fired when the panel is collapsed. + onExpand - (function) Fired when the panel is expanded. + +*/ +MUI.Panel = new Class({ + + Implements: [Events, Options], + + options: { + id: null, + title: 'New Panel', + column: null, + require: { + css: [], + images: [], + js: [], + onload: null + }, + loadMethod: null, + contentURL: null, + + // xhr options + method: 'get', + data: null, + evalScripts: true, + evalResponse: false, + + // html options + content: 'Panel content', + + // Tabs + tabsURL: null, + tabsData: null, + tabsOnload: $empty, + + header: true, + headerToolbox: false, + headerToolboxURL: 'pages/lipsum.html', + headerToolboxOnload: $empty, + + // Style options: + height: 125, + addClass: '', + scrollbars: true, + padding: { top: 8, right: 8, bottom: 8, left: 8 }, + + // Other: + collapsible: true, + + // Events + onBeforeBuild: $empty, + onContentLoaded: $empty, + onResize: $empty, + onCollapse: $empty, + onExpand: $empty + + }, + initialize: function(options){ + this.setOptions(options); + + $extend(this, { + timestamp: $time(), + isCollapsed: false, // This is probably redundant since we can check for the class + oldHeight: 0, + partner: null + }); + + // If panel has no ID, give it one. + if (this.options.id == null){ + this.options.id = 'panel' + (++MUI.Panels.panelIDCount); + } + + // Shorten object chain + var instances = MUI.Panels.instances; + var instanceID = instances.get(this.options.id); + var options = this.options; + + // Check to see if there is already a class instance for this panel + if (instanceID){ + var instance = instanceID; + } + + // Check if panel already exists + if ( this.panelEl ){ + return; + } + else { + instances.set(this.options.id, this); + } + + this.fireEvent('onBeforeBuild'); + + if (options.loadMethod == 'iframe') { + // Iframes have their own padding. + options.padding = { top: 0, right: 0, bottom: 0, left: 0 }; + } + + this.showHandle = true; + if ($(options.column).getChildren().length == 0) { + this.showHandle = false; + } + + this.panelWrapperEl = new Element('div', { + 'id': this.options.id + '_wrapper', + 'class': 'panelWrapper expanded' + }).inject($(options.column)); + + this.panelEl = new Element('div', { + 'id': this.options.id, + 'class': 'panel expanded', + 'styles': { + 'height': options.height + } + }).inject(this.panelWrapperEl); + + this.panelEl.store('instance', this); + + this.panelEl.addClass(options.addClass); + + this.contentEl = new Element('div', { + 'id': options.id + '_pad', + 'class': 'pad' + }).inject(this.panelEl); + + // This is in order to use the same variable as the windows do in updateContent. + // May rethink this. + this.contentWrapperEl = this.panelEl; + + this.contentEl.setStyles({ + 'padding-top': options.padding.top, + 'padding-bottom': options.padding.bottom, + 'padding-left': options.padding.left, + 'padding-right': options.padding.right + }); + + this.panelHeaderEl = new Element('div', { + 'id': this.options.id + '_header', + 'class': 'panel-header', + 'styles': { + 'display': options.header ? 'block' : 'none' + } + }).inject(this.panelEl, 'before'); + + var columnInstances = MUI.Columns.instances; + var columnInstance = columnInstances.get(this.options.column); + + if (columnInstance.options.sortable){ + this.panelHeaderEl.setStyle('cursor', 'move'); + columnInstance.options.container.retrieve('sortables').addItems(this.panelWrapperEl); + } + + if (this.options.collapsible) { + this.collapseToggleInit(); + } + + if (this.options.headerToolbox) { + this.panelHeaderToolboxEl = new Element('div', { + 'id': options.id + '_headerToolbox', + 'class': 'panel-header-toolbox' + }).inject(this.panelHeaderEl); + } + + this.panelHeaderContentEl = new Element('div', { + 'id': options.id + '_headerContent', + 'class': 'panel-headerContent' + }).inject(this.panelHeaderEl); + + this.titleEl = new Element('h2', { + 'id': options.id + '_title' + }).inject(this.panelHeaderContentEl); + + this.handleEl = new Element('div', { + 'id': options.id + '_handle', + 'class': 'horizontalHandle', + 'styles': { + 'display': this.showHandle == true ? 'block' : 'none' + } + }).inject(this.panelEl, 'after'); + + this.handleIconEl = new Element('div', { + 'id': options.id + '_handle_icon', + 'class': 'handleIcon' + }).inject(this.handleEl); + + addResizeBottom(options.id); + + if (options.require.css.length || options.require.images.length){ + new MUI.Require({ + css: options.require.css, + images: options.require.images, + onload: function(){ + this.newPanel(); + }.bind(this) + }); + } + else { + this.newPanel(); + } + }, + newPanel: function(){ + + options = this.options; + + if (this.options.headerToolbox) { + MUI.updateContent({ + 'element': this.panelEl, + 'childElement': this.panelHeaderToolboxEl, + 'loadMethod': 'xhr', + 'url': options.headerToolboxURL, + 'onContentLoaded': options.headerToolboxOnload + }); + } + + if (options.tabsURL == null) { + this.titleEl.set('html', options.title); + } else { + this.panelHeaderContentEl.addClass('tabs'); + MUI.updateContent({ + 'element': this.panelEl, + 'childElement': this.panelHeaderContentEl, + 'loadMethod': 'xhr', + 'url': options.tabsURL, + 'data': options.tabsData, + 'onContentLoaded': options.tabsOnload + }); + } + + // Add content to panel. + MUI.updateContent({ + 'element': this.panelEl, + 'content': options.content, + 'method': options.method, + 'data': options.data, + 'url': options.contentURL, + 'onContentLoaded': null, + 'require': { + js: options.require.js, + onload: options.require.onload + } + }); + + // Do this when creating and removing panels + $(options.column).getChildren('.panelWrapper').each(function(panelWrapper){ + panelWrapper.getElement('.panel').removeClass('bottomPanel'); + }); + $(options.column).getChildren('.panelWrapper').getLast().getElement('.panel').addClass('bottomPanel'); + + MUI.panelHeight(options.column, this.panelEl, 'new'); + + }, + collapseToggleInit: function(options){ + + var options = this.options; + + this.panelHeaderCollapseBoxEl = new Element('div', { + 'id': options.id + '_headerCollapseBox', + 'class': 'toolbox' + }).inject(this.panelHeaderEl); + + if (options.headerToolbox) { + this.panelHeaderCollapseBoxEl.addClass('divider'); + } + + this.collapseToggleEl = new Element('div', { + 'id': options.id + '_collapseToggle', + 'class': 'panel-collapse icon16', + 'styles': { + 'width': 16, + 'height': 16 + }, + 'title': 'Collapse Panel' + }).inject(this.panelHeaderCollapseBoxEl); + + this.collapseToggleEl.addEvent('click', function(event){ + var panel = this.panelEl; + var panelWrapper = this.panelWrapperEl + + // Get siblings and make sure they are not all collapsed. + // If they are all collapsed and the current panel is collapsing + // Then collapse the column. + var instances = MUI.Panels.instances; + var expandedSiblings = []; + + panelWrapper.getAllPrevious('.panelWrapper').each(function(sibling){ + var instance = instances.get(sibling.getElement('.panel').id); + if (instance.isCollapsed == false){ + expandedSiblings.push(sibling.getElement('.panel').id); + } + }); + + panelWrapper.getAllNext('.panelWrapper').each(function(sibling){ + var instance = instances.get(sibling.getElement('.panel').id); + if (instance.isCollapsed == false){ + expandedSiblings.push(sibling.getElement('.panel').id); + } + }); + + // Collapse Panel + if (this.isCollapsed == false) { + var currentColumn = MUI.Columns.instances.get($(options.column).id); + + if (expandedSiblings.length == 0 && currentColumn.options.placement != 'main'){ + var currentColumn = MUI.Columns.instances.get($(options.column).id); + currentColumn.columnToggle(); + return; + } + else if (expandedSiblings.length == 0 && currentColumn.options.placement == 'main'){ + return; + } + this.oldHeight = panel.getStyle('height').toInt(); + if (this.oldHeight < 10) this.oldHeight = 20; + this.contentEl.setStyle('position', 'absolute'); // This is so IE6 and IE7 will collapse the panel all the way + panel.setStyle('height', 0); + this.isCollapsed = true; + panelWrapper.addClass('collapsed'); + panelWrapper.removeClass('expanded'); + MUI.panelHeight(options.column, panel, 'collapsing'); + MUI.panelHeight(); // Run this a second time for panels within panels + this.collapseToggleEl.removeClass('panel-collapsed'); + this.collapseToggleEl.addClass('panel-expand'); + this.collapseToggleEl.setProperty('title','Expand Panel'); + this.fireEvent('onCollapse'); + } + + // Expand Panel + else { + this.contentEl.setStyle('position', null); // This is so IE6 and IE7 will collapse the panel all the way + panel.setStyle('height', this.oldHeight); + this.isCollapsed = false; + panelWrapper.addClass('expanded'); + panelWrapper.removeClass('collapsed'); + MUI.panelHeight(this.options.column, panel, 'expanding'); + MUI.panelHeight(); // Run this a second time for panels within panels + this.collapseToggleEl.removeClass('panel-expand'); + this.collapseToggleEl.addClass('panel-collapsed'); + this.collapseToggleEl.setProperty('title','Collapse Panel'); + this.fireEvent('onExpand'); + } + }.bind(this)); + } +}); +MUI.Panel.implement(new Options, new Events); + +/* + arguments: + column - The column to resize the panels in + changing - The panel that is collapsing, expanding, or new + action - collapsing, expanding, or new + +*/ + +MUI.extend({ + // Panel Height + panelHeight: function(column, changing, action){ + if (column != null) { + MUI.panelHeight2($(column), changing, action); + } + else { + $$('.column').each(function(column){ + MUI.panelHeight2(column); + }.bind(this)); + } + }, + /* + + actions can be new, collapsing or expanding. + + */ + panelHeight2: function(column, changing, action){ + + var instances = MUI.Panels.instances; + + var parent = column.getParent(); + var columnHeight = parent.getStyle('height').toInt(); + if (Browser.Engine.trident4 && parent == MUI.Desktop.pageWrapper) { + columnHeight -= 1; + } + column.setStyle('height', columnHeight); + + // Get column panels + var panels = []; + column.getChildren('.panelWrapper').each( function(panelWrapper){ + panels.push(panelWrapper.getElement('.panel')); + }.bind(this)); + + // Get expanded column panels + var panelsExpanded = []; + column.getChildren('.expanded').each( function(panelWrapper){ + panelsExpanded.push(panelWrapper.getElement('.panel')); + }.bind(this)); + + // All the panels in the column whose height will be effected. + var panelsToResize = []; + + // The panel with the greatest height. Remainders will be added to this panel + var tallestPanel; + var tallestPanelHeight = 0; + + this.panelsTotalHeight = 0; // Height of all the panels in the column + this.height = 0; // Height of all the elements in the column + + // Set panel resize partners + panels.each(function(panel){ + instance = instances.get(panel.id); + if (panel.getParent().hasClass('expanded') && panel.getParent().getNext('.expanded')) { + instance.partner = panel.getParent().getNext('.expanded').getElement('.panel'); + instance.resize.attach(); + instance.handleEl.setStyles({ + 'display': 'block', + 'cursor': Browser.Engine.webkit ? 'row-resize' : 'n-resize' + }).removeClass('detached'); + } else { + instance.resize.detach(); + instance.handleEl.setStyles({ + 'display': 'none', + 'cursor': null + }).addClass('detached'); + } + if (panel.getParent().getNext('.panelWrapper') == null) { + instance.handleEl.hide(); + } + }.bind(this)); + + // Add panels to panelsToResize + // Get the total height of all the resizable panels + // Get the total height of all the column's children + column.getChildren().each(function(panelWrapper){ + + panelWrapper.getChildren().each(function(el){ + + if (el.hasClass('panel')){ + var instance = instances.get(el.id); + + // Are any next siblings Expanded? + anyNextSiblingsExpanded = function(el){ + var test; + el.getParent().getAllNext('.panelWrapper').each(function(sibling){ + var siblingInstance = instances.get(sibling.getElement('.panel').id); + if (siblingInstance.isCollapsed == false){ + test = true; + } + }.bind(this)); + return test; + }.bind(this); + + // If a next sibling is expanding, are any of the nexts siblings of the expanding sibling Expanded? + anyExpandingNextSiblingsExpanded = function(el){ + var test; + changing.getParent().getAllNext('.panelWrapper').each(function(sibling){ + var siblingInstance = instances.get(sibling.getElement('.panel').id); + if (siblingInstance.isCollapsed == false){ + test = true; + } + }.bind(this)); + return test; + }.bind(this); + + // Is the panel that is collapsing, expanding, or new located after this panel? + anyNextContainsChanging = function(el){ + var allNext = []; + el.getParent().getAllNext('.panelWrapper').each(function(panelWrapper){ + allNext.push(panelWrapper.getElement('.panel')); + }.bind(this)); + var test = allNext.contains(changing); + return test; + }.bind(this); + + nextExpandedChanging = function(el){ + var test; + if (el.getParent().getNext('.expanded')){ + if (el.getParent().getNext('.expanded').getElement('.panel') == changing) test = true; + } + return test; + } + + // NEW PANEL + // Resize panels that are "new" or not collapsed + if (action == 'new') { + if (!instance.isCollapsed && el != changing) { + panelsToResize.push(el); + this.panelsTotalHeight += el.offsetHeight.toInt(); + } + } + + // COLLAPSING PANELS and CURRENTLY EXPANDED PANELS + // Resize panels that are not collapsed. + // If a panel is collapsing resize any expanded panels below. + // If there are no expanded panels below it, resize the expanded panels above it. + else if (action == null || action == 'collapsing' ){ + if (!instance.isCollapsed && (!anyNextContainsChanging(el) || !anyNextSiblingsExpanded(el))){ + panelsToResize.push(el); + this.panelsTotalHeight += el.offsetHeight.toInt(); + } + } + + // EXPANDING PANEL + // Resize panels that are not collapsed and are not expanding. + // Resize any expanded panels below the expanding panel. + // If there are no expanded panels below the expanding panel, resize the first expanded panel above it. + else if (action == 'expanding' && !instance.isCollapsed && el != changing){ + if (!anyNextContainsChanging(el) || (!anyExpandingNextSiblingsExpanded(el) && nextExpandedChanging(el))){ + panelsToResize.push(el); + this.panelsTotalHeight += el.offsetHeight.toInt(); + } + } + + if (el.style.height){ + this.height += el.getStyle('height').toInt(); + } + } + else { + this.height += el.offsetHeight.toInt(); + } + }.bind(this)); + + }.bind(this)); + + // Get the remaining height + var remainingHeight = column.offsetHeight.toInt() - this.height; + + this.height = 0; + + // Get height of all the column's children + column.getChildren().each(function(el){ + this.height += el.offsetHeight.toInt(); + }.bind(this)); + + var remainingHeight = column.offsetHeight.toInt() - this.height; + + panelsToResize.each(function(panel){ + var ratio = this.panelsTotalHeight / panel.offsetHeight.toInt(); + var newPanelHeight = panel.getStyle('height').toInt() + (remainingHeight / ratio); + if (newPanelHeight < 1){ + newPanelHeight = 0; + } + panel.setStyle('height', newPanelHeight); + }.bind(this)); + + // Make sure the remaining height is 0. If not add/subtract the + // remaining height to the tallest panel. This makes up for browser resizing, + // off ratios, and users trying to give panels too much height. + + // Get height of all the column's children + this.height = 0; + column.getChildren().each(function(panelWrapper){ + panelWrapper.getChildren().each(function(el){ + this.height += el.offsetHeight.toInt(); + if (el.hasClass('panel') && el.getStyle('height').toInt() > tallestPanelHeight){ + tallestPanel = el; + tallestPanelHeight = el.getStyle('height').toInt(); + } + }.bind(this)); + }.bind(this)); + + var remainingHeight = column.offsetHeight.toInt() - this.height; + + if (remainingHeight != 0 && tallestPanelHeight > 0){ + tallestPanel.setStyle('height', tallestPanel.getStyle('height').toInt() + remainingHeight ); + if (tallestPanel.getStyle('height') < 1){ + tallestPanel.setStyle('height', 0 ); + } + } + + parent.getChildren('.columnHandle').each(function(handle){ + var parent = handle.getParent(); + if (parent.getStyle('height').toInt() < 1) return; // Keeps IE7 and 8 from throwing an error when collapsing a panel within a panel + var handleHeight = parent.getStyle('height').toInt() - handle.getStyle('border-top').toInt() - handle.getStyle('border-bottom').toInt(); + if (Browser.Engine.trident4 && parent == MUI.Desktop.pageWrapper){ + handleHeight -= 1; + } + handle.setStyle('height', handleHeight); + }); + + panelsExpanded.each(function(panel){ + MUI.resizeChildren(panel); + }.bind(this)); + + }, + // May rename this resizeIframeEl() + resizeChildren: function(panel){ + var instances = MUI.Panels.instances; + var instance = instances.get(panel.id); + var contentWrapperEl = instance.contentWrapperEl; + + if (instance.iframeEl) { + if (!Browser.Engine.trident) { + instance.iframeEl.setStyles({ + 'height': contentWrapperEl.getStyle('height'), + 'width': contentWrapperEl.offsetWidth - contentWrapperEl.getStyle('border-left').toInt() - contentWrapperEl.getStyle('border-right').toInt() + }); + } + else { + // The following hack is to get IE8 RC1 IE8 Standards Mode to properly resize an iframe + // when only the vertical dimension is changed. + instance.iframeEl.setStyles({ + 'height': contentWrapperEl.getStyle('height'), + 'width': contentWrapperEl.offsetWidth - contentWrapperEl.getStyle('border-left').toInt() - contentWrapperEl.getStyle('border-right').toInt() - 1 + }); + instance.iframeEl.setStyles({ + 'width': contentWrapperEl.offsetWidth - contentWrapperEl.getStyle('border-left').toInt() - contentWrapperEl.getStyle('border-right').toInt() + }); + } + } + + }, + // Remaining Width + rWidth: function(container){ + if (container == null) { + var container = MUI.Desktop.desktop; + } + container.getElements('.rWidth').each(function(column){ + var currentWidth = column.offsetWidth.toInt(); + currentWidth -= column.getStyle('border-left').toInt(); + currentWidth -= column.getStyle('border-right').toInt(); + + var parent = column.getParent(); + this.width = 0; + + // Get the total width of all the parent element's children + parent.getChildren().each(function(el){ + if (el.hasClass('mocha') != true) { + this.width += el.offsetWidth.toInt(); + } + }.bind(this)); + + // Add the remaining width to the current element + var remainingWidth = parent.offsetWidth.toInt() - this.width; + var newWidth = currentWidth + remainingWidth; + if (newWidth < 1) newWidth = 0; + column.setStyle('width', newWidth); + column.getChildren('.panel').each(function(panel){ + panel.setStyle('width', newWidth - panel.getStyle('border-left').toInt() - panel.getStyle('border-right').toInt()); + MUI.resizeChildren(panel); + }.bind(this)); + + }); + } + +}); + +function addResizeRight(element, min, max){ + if (!$(element)) return; + element = $(element); + + var instances = MUI.Columns.instances; + var instance = instances.get(element.id); + + var handle = element.getNext('.columnHandle'); + handle.setStyle('cursor', Browser.Engine.webkit ? 'col-resize' : 'e-resize'); + if (!min) min = 50; + if (!max) max = 250; + if (Browser.Engine.trident) { + handle.addEvents({ + 'mousedown': function(){ + handle.setCapture(); + }, + 'mouseup': function(){ + handle.releaseCapture(); + } + }); + } + instance.resize = element.makeResizable({ + handle: handle, + modifiers: { + x: 'width', + y: false + }, + limit: { + x: [min, max] + }, + onStart: function(){ + element.getElements('iframe').setStyle('visibility', 'hidden'); + element.getNext('.column').getElements('iframe').setStyle('visibility', 'hidden'); + }.bind(this), + onDrag: function(){ + if (Browser.Engine.gecko) { + $$('.panel').each(function(panel){ + if (panel.getElements('.mochaIframe').length == 0) { + panel.hide(); // Fix for a rendering bug in FF + } + }); + } + MUI.rWidth(element.getParent()); + if (Browser.Engine.gecko) { + $$('.panel').show(); // Fix for a rendering bug in FF + } + if (Browser.Engine.trident4) { + element.getChildren().each(function(el){ + var width = $(element).getStyle('width').toInt(); + width -= el.getStyle('border-right').toInt(); + width -= el.getStyle('border-left').toInt(); + width -= el.getStyle('padding-right').toInt(); + width -= el.getStyle('padding-left').toInt(); + el.setStyle('width', width); + }.bind(this)); + } + }.bind(this), + onComplete: function(){ + MUI.rWidth(element.getParent()); + element.getElements('iframe').setStyle('visibility', 'visible'); + element.getNext('.column').getElements('iframe').setStyle('visibility', 'visible'); + instance.fireEvent('onResize'); + }.bind(this) + }); +} + +function addResizeLeft(element, min, max){ + if (!$(element)) return; + element = $(element); + + var instances = MUI.Columns.instances; + var instance = instances.get(element.id); + + var handle = element.getPrevious('.columnHandle'); + handle.setStyle('cursor', Browser.Engine.webkit ? 'col-resize' : 'e-resize'); + var partner = element.getPrevious('.column'); + if (!min) min = 50; + if (!max) max = 250; + if (Browser.Engine.trident){ + handle.addEvents({ + 'mousedown': function(){ + handle.setCapture(); + }, + 'mouseup': function(){ + handle.releaseCapture(); + } + }); + } + instance.resize = element.makeResizable({ + handle: handle, + modifiers: {x: 'width' , y: false}, + invert: true, + limit: { x: [min, max] }, + onStart: function(){ + $(element).getElements('iframe').setStyle('visibility','hidden'); + partner.getElements('iframe').setStyle('visibility','hidden'); + }.bind(this), + onDrag: function(){ + MUI.rWidth(element.getParent()); + }.bind(this), + onComplete: function(){ + MUI.rWidth(element.getParent()); + $(element).getElements('iframe').setStyle('visibility','visible'); + partner.getElements('iframe').setStyle('visibility','visible'); + instance.fireEvent('onResize'); + }.bind(this) + }); +} + +function addResizeBottom(element){ + if (!$(element)) return; + var element = $(element); + + var instances = MUI.Panels.instances; + var instance = instances.get(element.id); + var handle = instance.handleEl; + handle.setStyle('cursor', Browser.Engine.webkit ? 'row-resize' : 'n-resize'); + partner = instance.partner; + min = 0; + max = function(){ + return element.getStyle('height').toInt() + partner.getStyle('height').toInt(); + }.bind(this); + + if (Browser.Engine.trident) { + handle.addEvents({ + 'mousedown': function(){ + handle.setCapture(); + }, + 'mouseup': function(){ + handle.releaseCapture(); + } + }); + } + instance.resize = element.makeResizable({ + handle: handle, + modifiers: {x: false, y: 'height'}, + limit: { y: [min, max] }, + invert: false, + onBeforeStart: function(){ + partner = instance.partner; + this.originalHeight = element.getStyle('height').toInt(); + this.partnerOriginalHeight = partner.getStyle('height').toInt(); + }.bind(this), + onStart: function(){ + if (instance.iframeEl) { + if (!Browser.Engine.trident) { + instance.iframeEl.setStyle('visibility', 'hidden'); + partner.getElements('iframe').setStyle('visibility','hidden'); + } + else { + instance.iframeEl.hide(); + partner.getElements('iframe').hide(); + } + } + + }.bind(this), + onDrag: function(){ + partnerHeight = partnerOriginalHeight; + partnerHeight += (this.originalHeight - element.getStyle('height').toInt()); + partner.setStyle('height', partnerHeight); + MUI.resizeChildren(element, element.getStyle('height').toInt()); + MUI.resizeChildren(partner, partnerHeight); + element.getChildren('.column').each( function(column){ + MUI.panelHeight(column); + }); + partner.getChildren('.column').each( function(column){ + MUI.panelHeight(column); + }); + }.bind(this), + onComplete: function(){ + partnerHeight = partnerOriginalHeight; + partnerHeight += (this.originalHeight - element.getStyle('height').toInt()); + partner.setStyle('height', partnerHeight); + MUI.resizeChildren(element, element.getStyle('height').toInt()); + MUI.resizeChildren(partner, partnerHeight); + element.getChildren('.column').each( function(column){ + MUI.panelHeight(column); + }); + partner.getChildren('.column').each( function(column){ + MUI.panelHeight(column); + }); + if (instance.iframeEl) { + if (!Browser.Engine.trident) { + instance.iframeEl.setStyle('visibility', 'visible'); + partner.getElements('iframe').setStyle('visibility','visible'); + } + else { + instance.iframeEl.show(); + partner.getElements('iframe').show(); + // The following hack is to get IE8 Standards Mode to properly resize an iframe + // when only the vertical dimension is changed. + var width = instance.iframeEl.getStyle('width').toInt(); + instance.iframeEl.setStyle('width', width - 1); + MUI.rWidth(); + instance.iframeEl.setStyle('width', width); + } + } + instance.fireEvent('onResize'); + }.bind(this) + }); +} + +MUI.extend({ + /* + + Function: closeColumn + Destroys/removes a column. + + Syntax: + (start code) + MUI.closeColumn(); + (end) + + Arguments: + columnEl - the ID of the column to be closed + + Returns: + true - the column was closed + false - the column was not closed + + */ + closeColumn: function(columnEl){ + var instances = MUI.Columns.instances; + var instance = instances.get(columnEl.id); + if (columnEl != $(columnEl) || instance.isClosing) return; + + instance.isClosing = true; + + if (instance.options.sortable){ + instance.container.retrieve('sortables').removeLists(this.columnEl); + } + + // Destroy all the panels in the column. + var panels = columnEl.getChildren('.panel'); + panels.each(function(panel){ + MUI.closePanel($(panel.id)); + }.bind(this)); + + if (Browser.Engine.trident) { + columnEl.dispose(); + if (instance.handleEl != null) { + instance.handleEl.dispose(); + } + } + else { + columnEl.destroy(); + if (instance.handleEl != null) { + instance.handleEl.destroy(); + } + } + if (MUI.Desktop) { + MUI.Desktop.resizePanels(); + } + instances.erase(instance.options.id); + return true; + }, + /* + + Function: closePanel + Destroys/removes a panel. + + Syntax: + (start code) + MUI.closePanel(); + (end) + + Arguments: + panelEl - the ID of the panel to be closed + + Returns: + true - the panel was closed + false - the panel was not closed + + */ + closePanel: function(panelEl){ + var instances = MUI.Panels.instances; + var instance = instances.get(panelEl.id); + if (panelEl != $(panelEl) || instance.isClosing) return; + + var column = instance.options.column; + + instance.isClosing = true; + + var columnInstances = MUI.Columns.instances; + var columnInstance = columnInstances.get(column); + + if (columnInstance.options.sortable){ + columnInstance.options.container.retrieve('sortables').removeItems(instance.panelWrapperEl); + } + + instance.panelWrapperEl.destroy(); + + if (MUI.Desktop) { + MUI.Desktop.resizePanels(); + } + + // Do this when creating and removing panels + $(column).getChildren('.panelWrapper').each(function(panelWrapper){ + panelWrapper.getElement('.panel').removeClass('bottomPanel'); + }); + $(column).getChildren('.panelWrapper').getLast().getElement('.panel').addClass('bottomPanel'); + + instances.erase(instance.options.id); + return true; + + } +}); +/* + +Script: Dock.js + Implements the dock/taskbar. Enables window minimize. + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Requires: + Core.js, Window.js, Layout.js + +Todo: + - Make it so the dock requires no initial html markup. + +*/ + +MUI.files[MUI.path.source + 'Layout/Dock.js'] = 'loaded'; + +MUI.options.extend({ + // Naming options: + // If you change the IDs of the Mocha Desktop containers in your HTML, you need to change them here as well. + dockWrapper: 'dockWrapper', + dock: 'dock' +}); + +MUI.extend({ + /* + + Function: minimizeAll + Minimize all windows that are minimizable. + + */ + minimizeAll: function() { + $$('.mocha').each(function(windowEl){ + var instance = windowEl.retrieve('instance'); + if (!instance.isMinimized && instance.options.minimizable == true){ + MUI.Dock.minimizeWindow(windowEl); + } + }.bind(this)); + } +}); + +MUI.Dock = { + + options: { + useControls: true, // Toggles autohide and dock placement controls. + dockPosition: 'bottom', // Position the dock starts in, top or bottom. + // Style options + trueButtonColor: [70, 245, 70], // Color for autohide on + enabledButtonColor: [115, 153, 191], + disabledButtonColor: [170, 170, 170] + }, + + initialize: function(options){ + // Stops if MUI.Desktop is not implemented + if (!MUI.Desktop) return; + + MUI.dockVisible = true; + this.dockWrapper = $(MUI.options.dockWrapper); + this.dock = $(MUI.options.dock); + this.autoHideEvent = null; + this.dockAutoHide = false; // True when dock autohide is set to on, false if set to off + + if (!this.dockWrapper) return; + + if (!this.options.useControls){ + if($('dockPlacement')){ + $('dockPlacement').setStyle('cursor', 'default'); + } + if($('dockAutoHide')){ + $('dockAutoHide').setStyle('cursor', 'default'); + } + } + + this.dockWrapper.setStyles({ + 'display': 'block', + 'position': 'absolute', + 'top': null, + 'bottom': MUI.Desktop.desktopFooter ? MUI.Desktop.desktopFooter.offsetHeight : 0, + 'left': 0 + }); + + if (this.options.useControls){ + this.initializeDockControls(); + } + + // Add check mark to menu if link exists in menu + if ($('dockLinkCheck')){ + this.sidebarCheck = new Element('div', { + 'class': 'check', + 'id': 'dock_check' + }).inject($('dockLinkCheck')); + } + + this.dockSortables = new Sortables('#dockSort', { + opacity: 1, + constrain: true, + clone: false, + revert: false + }); + + MUI.Desktop.setDesktopSize(); + + if (MUI.myChain){ + MUI.myChain.callChain(); + } + + }, + + initializeDockControls: function(){ + + // Convert CSS colors to Canvas colors. + this.setDockColors(); + + if (this.options.useControls){ + // Insert canvas + var canvas = new Element('canvas', { + 'id': 'dockCanvas', + 'width': '15', + 'height': '18' + }).inject(this.dock); + + // Dynamically initialize canvas using excanvas. This is only required by IE + if (Browser.Engine.trident && MUI.ieSupport == 'excanvas'){ + G_vmlCanvasManager.initElement(canvas); + } + } + + var dockPlacement = $('dockPlacement'); + var dockAutoHide = $('dockAutoHide'); + + // Position top or bottom selector + dockPlacement.setProperty('title','Position Dock Top'); + + // Attach event + dockPlacement.addEvent('click', function(){ + this.moveDock(); + }.bind(this)); + + // Auto Hide toggle switch + dockAutoHide.setProperty('title','Turn Auto Hide On'); + + // Attach event Auto Hide + dockAutoHide.addEvent('click', function(event){ + if ( this.dockWrapper.getProperty('dockPosition') == 'top' ) + return false; + + var ctx = $('dockCanvas').getContext('2d'); + this.dockAutoHide = !this.dockAutoHide; // Toggle + if (this.dockAutoHide){ + $('dockAutoHide').setProperty('title', 'Turn Auto Hide Off'); + //ctx.clearRect(0, 11, 100, 100); + MUI.circle(ctx, 5 , 14, 3, this.options.trueButtonColor, 1.0); + + // Define event + this.autoHideEvent = function(event) { + if (!this.dockAutoHide) + return; + if (!MUI.Desktop.desktopFooter) { + var dockHotspotHeight = this.dockWrapper.offsetHeight; + if (dockHotspotHeight < 25) dockHotspotHeight = 25; + } + else if (MUI.Desktop.desktopFooter) { + var dockHotspotHeight = this.dockWrapper.offsetHeight + MUI.Desktop.desktopFooter.offsetHeight; + if (dockHotspotHeight < 25) dockHotspotHeight = 25; + } + if (!MUI.Desktop.desktopFooter && event.client.y > (document.getCoordinates().height - dockHotspotHeight)){ + if (!MUI.dockVisible){ + this.dockWrapper.show(); + MUI.dockVisible = true; + MUI.Desktop.setDesktopSize(); + } + } + else if (MUI.Desktop.desktopFooter && event.client.y > (document.getCoordinates().height - dockHotspotHeight)){ + if (!MUI.dockVisible){ + this.dockWrapper.show(); + MUI.dockVisible = true; + MUI.Desktop.setDesktopSize(); + } + } + else if (MUI.dockVisible){ + this.dockWrapper.hide(); + MUI.dockVisible = false; + MUI.Desktop.setDesktopSize(); + + } + }.bind(this); + + // Add event + document.addEvent('mousemove', this.autoHideEvent); + + } else { + $('dockAutoHide').setProperty('title', 'Turn Auto Hide On'); + //ctx.clearRect(0, 11, 100, 100); + MUI.circle(ctx, 5 , 14, 3, this.options.enabledButtonColor, 1.0); + // Remove event + document.removeEvent('mousemove', this.autoHideEvent); + } + + }.bind(this)); + + this.renderDockControls(); + + if (this.options.dockPosition == 'top'){ + this.moveDock(); + } + + }, + + setDockColors: function(){ + var dockButtonEnabled = MUI.getCSSRule('.dockButtonEnabled'); + if (dockButtonEnabled && dockButtonEnabled.style.backgroundColor){ + this.options.enabledButtonColor = new Color(dockButtonEnabled.style.backgroundColor); + } + + var dockButtonDisabled = MUI.getCSSRule('.dockButtonDisabled'); + if (dockButtonDisabled && dockButtonDisabled.style.backgroundColor){ + this.options.disabledButtonColor = new Color(dockButtonDisabled.style.backgroundColor); + } + + var trueButtonColor = MUI.getCSSRule('.dockButtonTrue'); + if (trueButtonColor && trueButtonColor.style.backgroundColor){ + this.options.trueButtonColor = new Color(trueButtonColor.style.backgroundColor); + } + }, + + renderDockControls: function(){ + // Draw dock controls + var ctx = $('dockCanvas').getContext('2d'); + ctx.clearRect(0, 0, 100, 100); + MUI.circle(ctx, 5 , 4, 3, this.options.enabledButtonColor, 1.0); + + if( this.dockWrapper.getProperty('dockPosition') == 'top'){ + MUI.circle(ctx, 5 , 14, 3, this.options.disabledButtonColor, 1.0) + } + else if (this.dockAutoHide){ + MUI.circle(ctx, 5 , 14, 3, this.options.trueButtonColor, 1.0); + } + else { + MUI.circle(ctx, 5 , 14, 3, this.options.enabledButtonColor, 1.0); + } + }, + + moveDock: function(){ + var ctx = $('dockCanvas').getContext('2d'); + // Move dock to top position + if (this.dockWrapper.getStyle('position') != 'relative'){ + this.dockWrapper.setStyles({ + 'position': 'relative', + 'bottom': null + }); + this.dockWrapper.addClass('top'); + MUI.Desktop.setDesktopSize(); + this.dockWrapper.setProperty('dockPosition','top'); + ctx.clearRect(0, 0, 100, 100); + MUI.circle(ctx, 5, 4, 3, this.options.enabledButtonColor, 1.0); + MUI.circle(ctx, 5, 14, 3, this.options.disabledButtonColor, 1.0); + $('dockPlacement').setProperty('title', 'Position Dock Bottom'); + $('dockAutoHide').setProperty('title', 'Auto Hide Disabled in Top Dock Position'); + this.dockAutoHide = false; + } + // Move dock to bottom position + else { + this.dockWrapper.setStyles({ + 'position': 'absolute', + 'bottom': MUI.Desktop.desktopFooter ? MUI.Desktop.desktopFooter.offsetHeight : 0 + }); + this.dockWrapper.removeClass('top'); + MUI.Desktop.setDesktopSize(); + this.dockWrapper.setProperty('dockPosition', 'bottom'); + ctx.clearRect(0, 0, 100, 100); + MUI.circle(ctx, 5, 4, 3, this.options.enabledButtonColor, 1.0); + MUI.circle(ctx, 5 , 14, 3, this.options.enabledButtonColor, 1.0); + $('dockPlacement').setProperty('title', 'Position Dock Top'); + $('dockAutoHide').setProperty('title', 'Turn Auto Hide On'); + } + }, + + createDockTab: function(windowEl){ + + var instance = windowEl.retrieve('instance'); + + var dockTab = new Element('div', { + 'id': instance.options.id + '_dockTab', + 'class': 'dockTab', + 'title': titleText + }).inject($('dockClear'), 'before'); + + dockTab.addEvent('mousedown', function(e){ + new Event(e).stop(); + this.timeDown = $time(); + }); + + dockTab.addEvent('mouseup', function(e){ + this.timeUp = $time(); + if ((this.timeUp - this.timeDown) < 275){ + // If the visibility of the windows on the page are toggled off, toggle visibility on. + if (MUI.Windows.windowsVisible == false) { + MUI.toggleWindowVisibility(); + if (instance.isMinimized == true) { + MUI.Dock.restoreMinimized.delay(25, MUI.Dock, windowEl); + } + else { + MUI.focusWindow(windowEl); + } + return; + } + // If window is minimized, restore window. + if (instance.isMinimized == true) { + MUI.Dock.restoreMinimized.delay(25, MUI.Dock, windowEl); + } + else{ + // If window is not minimized and is focused, minimize window. + if (instance.windowEl.hasClass('isFocused') && instance.options.minimizable == true){ + MUI.Dock.minimizeWindow(windowEl) + } + // If window is not minimized and is not focused, focus window. + else{ + MUI.focusWindow(windowEl); + } + // if the window is not minimized and is outside the viewport, center it in the viewport. + var coordinates = document.getCoordinates(); + if (windowEl.getStyle('left').toInt() > coordinates.width || windowEl.getStyle('top').toInt() > coordinates.height){ + MUI.centerWindow(windowEl); + } + } + } + }); + + this.dockSortables.addItems(dockTab); + + var titleText = instance.titleEl.innerHTML; + + var dockTabText = new Element('div', { + 'id': instance.options.id + '_dockTabText', + 'class': 'dockText' + }).set('html', titleText.substring(0,19) + (titleText.length > 19 ? '...' : '')).inject($(dockTab)); + + // If I implement this again, will need to also adjust the titleText truncate and the tab's + // left padding. + if (instance.options.icon != false){ + // dockTabText.setStyle('background', 'url(' + instance.options.icon + ') 4px 4px no-repeat'); + } + + // Need to resize everything in case the dock wraps when a new tab is added + MUI.Desktop.setDesktopSize(); + + }, + + makeActiveTab: function(){ + + // getWindowWith HighestZindex is used in case the currently focused window + // is closed. + var windowEl = MUI.getWindowWithHighestZindex(); + var instance = windowEl.retrieve('instance'); + + $$('.dockTab').removeClass('activeDockTab'); + if (instance.isMinimized != true) { + + instance.windowEl.addClass('isFocused'); + + var currentButton = $(instance.options.id + '_dockTab'); + if (currentButton != null) { + currentButton.addClass('activeDockTab'); + } + } + else { + instance.windowEl.removeClass('isFocused'); + } + }, + + minimizeWindow: function(windowEl){ + if (windowEl != $(windowEl)) return; + + var instance = windowEl.retrieve('instance'); + instance.isMinimized = true; + + // Hide iframe + // Iframe should be hidden when minimizing, maximizing, and moving for performance and Flash issues + if ( instance.iframeEl ) { + // Some elements are still visible in IE8 in the iframe when the iframe's visibility is set to hidden. + if (!Browser.Engine.trident) { + instance.iframeEl.setStyle('visibility', 'hidden'); + } + else { + instance.iframeEl.hide(); + } + } + + // Hide window and add to dock + instance.contentBorderEl.setStyle('visibility', 'hidden'); + if(instance.toolbarWrapperEl){ + instance.toolbarWrapperEl.hide(); + } + windowEl.setStyle('visibility', 'hidden'); + + // Fixes a scrollbar issue in Mac FF2 + if (Browser.Platform.mac && Browser.Engine.gecko){ + if (/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)){ + var ffversion = new Number(RegExp.$1); + if (ffversion < 3) { + instance.contentWrapperEl.setStyle('overflow', 'hidden'); + } + } + } + + MUI.Desktop.setDesktopSize(); + + // Have to use timeout because window gets focused when you click on the minimize button + setTimeout(function(){ + windowEl.setStyle('zIndex', 1); + windowEl.removeClass('isFocused'); + this.makeActiveTab(); + }.bind(this),100); + + instance.fireEvent('onMinimize', windowEl); + }, + + restoreMinimized: function(windowEl) { + + var instance = windowEl.retrieve('instance'); + + if (instance.isMinimized == false) return; + + if (MUI.Windows.windowsVisible == false){ + MUI.toggleWindowVisibility(); + } + + MUI.Desktop.setDesktopSize(); + + // Part of Mac FF2 scrollbar fix + if (instance.options.scrollbars == true && !instance.iframeEl){ + instance.contentWrapperEl.setStyle('overflow', 'auto'); + } + + if (instance.isCollapsed) { + MUI.collapseToggle(windowEl); + } + + windowEl.setStyle('visibility', 'visible'); + instance.contentBorderEl.setStyle('visibility', 'visible'); + if(instance.toolbarWrapperEl){ + instance.toolbarWrapperEl.show(); + } + + // Show iframe + if (instance.iframeEl){ + if (!Browser.Engine.trident){ + instance.iframeEl.setStyle('visibility', 'visible'); + } + else { + instance.iframeEl.show(); + } + } + + instance.isMinimized = false; + MUI.focusWindow(windowEl); + instance.fireEvent('onRestore', windowEl); + + } +}; +/* + +Script: Workspaces.js + Save and load workspaces. The Workspaces emulate Adobe Illustrator functionality remembering what windows are open and where they are positioned. + +Copyright: + Copyright (c) 2007-2009 Greg Houston, . + +License: + MIT-style license. + +Requires: + Core.js, Window.js + +To do: + - Move to Window + +*/ + +MUI.files[MUI.path.source + 'Layout/Workspaces.js'] = 'loaded'; + +MUI.extend({ + /* + + Function: saveWorkspace + Save the current workspace. + + Syntax: + (start code) + MUI.saveWorkspace(); + (end) + + Notes: + This version saves the ID of each open window to a cookie, and reloads those windows using the functions in mocha-init.js. This requires that each window have a function in mocha-init.js used to open them. Functions must be named the windowID + "Window". So if your window is called mywindow, it needs a function called mywindowWindow in mocha-init.js. + + */ + saveWorkspace: function(){ + this.cookie = new Hash.Cookie('mochaUIworkspaceCookie', {duration: 3600}); + this.cookie.empty(); + MUI.Windows.instances.each(function(instance) { + instance.saveValues(); + this.cookie.set(instance.options.id, { + 'id': instance.options.id, + 'top': instance.options.y, + 'left': instance.options.x, + 'width': instance.contentWrapperEl.getStyle('width').toInt(), + 'height': instance.contentWrapperEl.getStyle('height').toInt() + }); + }.bind(this)); + this.cookie.save(); + + new MUI.Window({ + loadMethod: 'html', + type: 'notification', + addClass: 'notification', + content: 'Workspace saved.', + closeAfter: '1400', + width: 200, + height: 40, + y: 53, + padding: { top: 10, right: 12, bottom: 10, left: 12 }, + shadowBlur: 5, + bodyBgColor: [255, 255, 255] + }); + + }, + windowUnload: function(){ + if ($$('.mocha').length == 0 && this.myChain){ + this.myChain.callChain(); + } + }, + loadWorkspace2: function(workspaceWindows){ + workspaceWindows.each(function(workspaceWindow){ + windowFunction = eval('MUI.' + workspaceWindow.id + 'Window'); + if (windowFunction){ + eval('MUI.' + workspaceWindow.id + 'Window({width:'+ workspaceWindow.width +',height:' + workspaceWindow.height + '});'); + var windowEl = $(workspaceWindow.id); + windowEl.setStyles({ + 'top': workspaceWindow.top, + 'left': workspaceWindow.left + }); + var instance = windowEl.retrieve('instance'); + instance.contentWrapperEl.setStyles({ + 'width': workspaceWindow.width, + 'height': workspaceWindow.height + }); + instance.drawWindow(); + } + }.bind(this)); + this.loadingWorkspace = false; + }, + /* + + Function: loadWorkspace + Load the saved workspace. + + Syntax: + (start code) + MUI.loadWorkspace(); + (end) + + */ + loadWorkspace: function(){ + cookie = new Hash.Cookie('mochaUIworkspaceCookie', {duration: 3600}); + workspaceWindows = cookie.load(); + + if(!cookie.getKeys().length){ + new MUI.Window({ + loadMethod: 'html', + type: 'notification', + addClass: 'notification', + content: 'You have no saved workspace.', + closeAfter: '1400', + width: 220, + height: 40, + y: 25, + padding: { top: 10, right: 12, bottom: 10, left: 12 }, + shadowBlur: 5, + bodyBgColor: [255, 255, 255] + }); + return; + } + + if ($$('.mocha').length != 0){ + this.loadingWorkspace = true; + this.myChain = new Chain(); + this.myChain.chain( + function(){ + $$('.mocha').each(function(el) { + this.closeWindow(el); + }.bind(this)); + }.bind(this), + function(){ + this.loadWorkspace2(workspaceWindows); + }.bind(this) + ); + this.myChain.callChain(); + } + else { + this.loadWorkspace2(workspaceWindows); + } + + } +}); diff --git a/src/webui/scripts/mootools-1.2-core-yc.js b/src/webui/scripts/mootools-1.2-core-yc.js new file mode 100644 index 000000000..7ff36d01d --- /dev/null +++ b/src/webui/scripts/mootools-1.2-core-yc.js @@ -0,0 +1,357 @@ +//MooTools, , My Object Oriented (JavaScript) Tools. Copyright (c) 2006-2009 Valerio Proietti, , MIT Style License. + +var MooTools={version:"1.2.4",build:"0d9113241a90b9cd5643b926795852a2026710d4"};var Native=function(k){k=k||{};var a=k.name;var i=k.legacy;var b=k.protect; +var c=k.implement;var h=k.generics;var f=k.initialize;var g=k.afterImplement||function(){};var d=f||i;h=h!==false;d.constructor=Native;d.$family={name:"native"}; +if(i&&f){d.prototype=i.prototype;}d.prototype.constructor=d;if(a){var e=a.toLowerCase();d.prototype.$family={name:e};Native.typize(d,e);}var j=function(n,l,o,m){if(!b||m||!n.prototype[l]){n.prototype[l]=o; +}if(h){Native.genericize(n,l,b);}g.call(n,l,o);return n;};d.alias=function(n,l,p){if(typeof n=="string"){var o=this.prototype[n];if((n=o)){return j(this,l,n,p); +}}for(var m in n){this.alias(m,n[m],l);}return this;};d.implement=function(m,l,o){if(typeof m=="string"){return j(this,m,l,o);}for(var n in m){j(this,n,m[n],l); +}return this;};if(c){d.implement(c);}return d;};Native.genericize=function(b,c,a){if((!a||!b[c])&&typeof b.prototype[c]=="function"){b[c]=function(){var d=Array.prototype.slice.call(arguments); +return b.prototype[c].apply(d.shift(),d);};}};Native.implement=function(d,c){for(var b=0,a=d.length;b-1:this.indexOf(a)>-1;},trim:function(){return this.replace(/^\s+|\s+$/g,"");},clean:function(){return this.replace(/\s+/g," ").trim(); +},camelCase:function(){return this.replace(/-\D/g,function(a){return a.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/[A-Z]/g,function(a){return("-"+a.charAt(0).toLowerCase()); +});},capitalize:function(){return this.replace(/\b[a-z]/g,function(a){return a.toUpperCase();});},escapeRegExp:function(){return this.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1"); +},toInt:function(a){return parseInt(this,a||10);},toFloat:function(){return parseFloat(this);},hexToRgb:function(b){var a=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); +return(a)?a.slice(1).hexToRgb(b):null;},rgbToHex:function(b){var a=this.match(/\d{1,3}/g);return(a)?a.rgbToHex(b):null;},stripScripts:function(b){var a=""; +var c=this.replace(/]*>([\s\S]*?)<\/script>/gi,function(){a+=arguments[1]+"\n";return"";});if(b===true){$exec(a);}else{if($type(b)=="function"){b(a,c); +}}return c;},substitute:function(a,b){return this.replace(b||(/\\?\{([^{}]+)\}/g),function(d,c){if(d.charAt(0)=="\\"){return d.slice(1);}return(a[c]!=undefined)?a[c]:""; +});}});Hash.implement({has:Object.prototype.hasOwnProperty,keyOf:function(b){for(var a in this){if(this.hasOwnProperty(a)&&this[a]===b){return a;}}return null; +},hasValue:function(a){return(Hash.keyOf(this,a)!==null);},extend:function(a){Hash.each(a||{},function(c,b){Hash.set(this,b,c);},this);return this;},combine:function(a){Hash.each(a||{},function(c,b){Hash.include(this,b,c); +},this);return this;},erase:function(a){if(this.hasOwnProperty(a)){delete this[a];}return this;},get:function(a){return(this.hasOwnProperty(a))?this[a]:null; +},set:function(a,b){if(!this[a]||this.hasOwnProperty(a)){this[a]=b;}return this;},empty:function(){Hash.each(this,function(b,a){delete this[a];},this); +return this;},include:function(a,b){if(this[a]==undefined){this[a]=b;}return this;},map:function(b,c){var a=new Hash;Hash.each(this,function(e,d){a.set(d,b.call(c,e,d,this)); +},this);return a;},filter:function(b,c){var a=new Hash;Hash.each(this,function(e,d){if(b.call(c,e,d,this)){a.set(d,e);}},this);return a;},every:function(b,c){for(var a in this){if(this.hasOwnProperty(a)&&!b.call(c,this[a],a)){return false; +}}return true;},some:function(b,c){for(var a in this){if(this.hasOwnProperty(a)&&b.call(c,this[a],a)){return true;}}return false;},getKeys:function(){var a=[]; +Hash.each(this,function(c,b){a.push(b);});return a;},getValues:function(){var a=[];Hash.each(this,function(b){a.push(b);});return a;},toQueryString:function(a){var b=[]; +Hash.each(this,function(f,e){if(a){e=a+"["+e+"]";}var d;switch($type(f)){case"object":d=Hash.toQueryString(f,e);break;case"array":var c={};f.each(function(h,g){c[g]=h; +});d=Hash.toQueryString(c,e);break;default:d=e+"="+encodeURIComponent(f);}if(f!=undefined){b.push(d);}});return b.join("&");}});Hash.alias({keyOf:"indexOf",hasValue:"contains"}); +var Event=new Native({name:"Event",initialize:function(a,f){f=f||window;var k=f.document;a=a||f.event;if(a.$extended){return a;}this.$extended=true;var j=a.type; +var g=a.target||a.srcElement;while(g&&g.nodeType==3){g=g.parentNode;}if(j.test(/key/)){var b=a.which||a.keyCode;var m=Event.Keys.keyOf(b);if(j=="keydown"){var d=b-111; +if(d>0&&d<13){m="f"+d;}}m=m||String.fromCharCode(b).toLowerCase();}else{if(j.match(/(click|mouse|menu)/i)){k=(!k.compatMode||k.compatMode=="CSS1Compat")?k.html:k.body; +var i={x:a.pageX||a.clientX+k.scrollLeft,y:a.pageY||a.clientY+k.scrollTop};var c={x:(a.pageX)?a.pageX-f.pageXOffset:a.clientX,y:(a.pageY)?a.pageY-f.pageYOffset:a.clientY}; +if(j.match(/DOMMouseScroll|mousewheel/)){var h=(a.wheelDelta)?a.wheelDelta/120:-(a.detail||0)/3;}var e=(a.which==3)||(a.button==2);var l=null;if(j.match(/over|out/)){switch(j){case"mouseover":l=a.relatedTarget||a.fromElement; +break;case"mouseout":l=a.relatedTarget||a.toElement;}if(!(function(){while(l&&l.nodeType==3){l=l.parentNode;}return true;}).create({attempt:Browser.Engine.gecko})()){l=false; +}}}}return $extend(this,{event:a,type:j,page:i,client:c,rightClick:e,wheel:h,relatedTarget:l,target:g,code:b,key:m,shift:a.shiftKey,control:a.ctrlKey,alt:a.altKey,meta:a.metaKey}); +}});Event.Keys=new Hash({enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46});Event.implement({stop:function(){return this.stopPropagation().preventDefault(); +},stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation();}else{this.event.cancelBubble=true;}return this;},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault(); +}else{this.event.returnValue=false;}return this;}});function Class(b){if(b instanceof Function){b={initialize:b};}var a=function(){Object.reset(this);if(a._prototyping){return this; +}this._current=$empty;var c=(this.initialize)?this.initialize.apply(this,arguments):this;delete this._current;delete this.caller;return c;}.extend(this); +a.implement(b);a.constructor=Class;a.prototype.constructor=a;return a;}Function.prototype.protect=function(){this._protected=true;return this;};Object.reset=function(a,c){if(c==null){for(var e in a){Object.reset(a,e); +}return a;}delete a[c];switch($type(a[c])){case"object":var d=function(){};d.prototype=a[c];var b=new d;a[c]=Object.reset(b);break;case"array":a[c]=$unlink(a[c]); +break;}return a;};new Native({name:"Class",initialize:Class}).extend({instantiate:function(b){b._prototyping=true;var a=new b;delete b._prototyping;return a; +},wrap:function(a,b,c){if(c._origin){c=c._origin;}return function(){if(c._protected&&this._current==null){throw new Error('The method "'+b+'" cannot be called.'); +}var e=this.caller,f=this._current;this.caller=f;this._current=arguments.callee;var d=c.apply(this,arguments);this._current=f;this.caller=e;return d;}.extend({_owner:a,_origin:c,_name:b}); +}});Class.implement({implement:function(a,d){if($type(a)=="object"){for(var e in a){this.implement(e,a[e]);}return this;}var f=Class.Mutators[a];if(f){d=f.call(this,d); +if(d==null){return this;}}var c=this.prototype;switch($type(d)){case"function":if(d._hidden){return this;}c[a]=Class.wrap(this,a,d);break;case"object":var b=c[a]; +if($type(b)=="object"){$mixin(b,d);}else{c[a]=$unlink(d);}break;case"array":c[a]=$unlink(d);break;default:c[a]=d;}return this;}});Class.Mutators={Extends:function(a){this.parent=a; +this.prototype=Class.instantiate(a);this.implement("parent",function(){var b=this.caller._name,c=this.caller._owner.parent.prototype[b];if(!c){throw new Error('The method "'+b+'" has no parent.'); +}return c.apply(this,arguments);}.protect());},Implements:function(a){$splat(a).each(function(b){if(b instanceof Function){b=Class.instantiate(b);}this.implement(b); +},this);}};var Chain=new Class({$chain:[],chain:function(){this.$chain.extend(Array.flatten(arguments));return this;},callChain:function(){return(this.$chain.length)?this.$chain.shift().apply(this,arguments):false; +},clearChain:function(){this.$chain.empty();return this;}});var Events=new Class({$events:{},addEvent:function(c,b,a){c=Events.removeOn(c);if(b!=$empty){this.$events[c]=this.$events[c]||[]; +this.$events[c].include(b);if(a){b.internal=true;}}return this;},addEvents:function(a){for(var b in a){this.addEvent(b,a[b]);}return this;},fireEvent:function(c,b,a){c=Events.removeOn(c); +if(!this.$events||!this.$events[c]){return this;}this.$events[c].each(function(d){d.create({bind:this,delay:a,"arguments":b})();},this);return this;},removeEvent:function(b,a){b=Events.removeOn(b); +if(!this.$events[b]){return this;}if(!a.internal){this.$events[b].erase(a);}return this;},removeEvents:function(c){var d;if($type(c)=="object"){for(d in c){this.removeEvent(d,c[d]); +}return this;}if(c){c=Events.removeOn(c);}for(d in this.$events){if(c&&c!=d){continue;}var b=this.$events[d];for(var a=b.length;a--;a){this.removeEvent(d,b[a]); +}}return this;}});Events.removeOn=function(a){return a.replace(/^on([A-Z])/,function(b,c){return c.toLowerCase();});};var Options=new Class({setOptions:function(){this.options=$merge.run([this.options].extend(arguments)); +if(!this.addEvent){return this;}for(var a in this.options){if($type(this.options[a])!="function"||!(/^on[A-Z]/).test(a)){continue;}this.addEvent(a,this.options[a]); +delete this.options[a];}return this;}});var Element=new Native({name:"Element",legacy:window.Element,initialize:function(a,b){var c=Element.Constructors.get(a); +if(c){return c(b);}if(typeof a=="string"){return document.newElement(a,b);}return document.id(a).set(b);},afterImplement:function(a,b){Element.Prototype[a]=b; +if(Array[a]){return;}Elements.implement(a,function(){var c=[],g=true;for(var e=0,d=this.length;e";}return document.id(this.createElement(a)).set(b);},newTextNode:function(a){return this.createTextNode(a); +},getDocument:function(){return this;},getWindow:function(){return this.window;},id:(function(){var a={string:function(d,c,b){d=b.getElementById(d);return(d)?a.element(d,c):null; +},element:function(b,e){$uid(b);if(!e&&!b.$family&&!(/^object|embed$/i).test(b.tagName)){var c=Element.Prototype;for(var d in c){b[d]=c[d];}}return b;},object:function(c,d,b){if(c.toElement){return a.element(c.toElement(b),d); +}return null;}};a.textnode=a.whitespace=a.window=a.document=$arguments(0);return function(c,e,d){if(c&&c.$family&&c.uid){return c;}var b=$type(c);return(a[b])?a[b](c,e,d||document):null; +};})()});if(window.$==null){Window.implement({$:function(a,b){return document.id(a,b,this.document);}});}Window.implement({$$:function(a){if(arguments.length==1&&typeof a=="string"){return this.document.getElements(a); +}var f=[];var c=Array.flatten(arguments);for(var d=0,b=c.length;d1);a.each(function(e){var f=this.getElementsByTagName(e.trim());(b)?c.extend(f):c=f; +},this);return new Elements(c,{ddup:b,cash:!d});}});(function(){var h={},f={};var i={input:"checked",option:"selected",textarea:(Browser.Engine.webkit&&Browser.Engine.version<420)?"innerHTML":"value"}; +var c=function(l){return(f[l]||(f[l]={}));};var g=function(n,l){if(!n){return;}var m=n.uid;if(Browser.Engine.trident){if(n.clearAttributes){var q=l&&n.cloneNode(false); +n.clearAttributes();if(q){n.mergeAttributes(q);}}else{if(n.removeEvents){n.removeEvents();}}if((/object/i).test(n.tagName)){for(var o in n){if(typeof n[o]=="function"){n[o]=$empty; +}}Element.dispose(n);}}if(!m){return;}h[m]=f[m]=null;};var d=function(){Hash.each(h,g);if(Browser.Engine.trident){$A(document.getElementsByTagName("object")).each(g); +}if(window.CollectGarbage){CollectGarbage();}h=f=null;};var j=function(n,l,s,m,p,r){var o=n[s||l];var q=[];while(o){if(o.nodeType==1&&(!m||Element.match(o,m))){if(!p){return document.id(o,r); +}q.push(o);}o=o[l];}return(p)?new Elements(q,{ddup:false,cash:!r}):null;};var e={html:"innerHTML","class":"className","for":"htmlFor",defaultValue:"defaultValue",text:(Browser.Engine.trident||(Browser.Engine.webkit&&Browser.Engine.version<420))?"innerText":"textContent"}; +var b=["compact","nowrap","ismap","declare","noshade","checked","disabled","readonly","multiple","selected","noresize","defer"];var k=["value","type","defaultValue","accessKey","cellPadding","cellSpacing","colSpan","frameBorder","maxLength","readOnly","rowSpan","tabIndex","useMap"]; +b=b.associate(b);Hash.extend(e,b);Hash.extend(e,k.associate(k.map(String.toLowerCase)));var a={before:function(m,l){if(l.parentNode){l.parentNode.insertBefore(m,l); +}},after:function(m,l){if(!l.parentNode){return;}var n=l.nextSibling;(n)?l.parentNode.insertBefore(m,n):l.parentNode.appendChild(m);},bottom:function(m,l){l.appendChild(m); +},top:function(m,l){var n=l.firstChild;(n)?l.insertBefore(m,n):l.appendChild(m);}};a.inside=a.bottom;Hash.each(a,function(l,m){m=m.capitalize();Element.implement("inject"+m,function(n){l(this,document.id(n,true)); +return this;});Element.implement("grab"+m,function(n){l(document.id(n,true),this);return this;});});Element.implement({set:function(o,m){switch($type(o)){case"object":for(var n in o){this.set(n,o[n]); +}break;case"string":var l=Element.Properties.get(o);(l&&l.set)?l.set.apply(this,Array.slice(arguments,1)):this.setProperty(o,m);}return this;},get:function(m){var l=Element.Properties.get(m); +return(l&&l.get)?l.get.apply(this,Array.slice(arguments,1)):this.getProperty(m);},erase:function(m){var l=Element.Properties.get(m);(l&&l.erase)?l.erase.apply(this):this.removeProperty(m); +return this;},setProperty:function(m,n){var l=e[m];if(n==undefined){return this.removeProperty(m);}if(l&&b[m]){n=!!n;}(l)?this[l]=n:this.setAttribute(m,""+n); +return this;},setProperties:function(l){for(var m in l){this.setProperty(m,l[m]);}return this;},getProperty:function(m){var l=e[m];var n=(l)?this[l]:this.getAttribute(m,2); +return(b[m])?!!n:(l)?n:n||null;},getProperties:function(){var l=$A(arguments);return l.map(this.getProperty,this).associate(l);},removeProperty:function(m){var l=e[m]; +(l)?this[l]=(l&&b[m])?false:"":this.removeAttribute(m);return this;},removeProperties:function(){Array.each(arguments,this.removeProperty,this);return this; +},hasClass:function(l){return this.className.contains(l," ");},addClass:function(l){if(!this.hasClass(l)){this.className=(this.className+" "+l).clean(); +}return this;},removeClass:function(l){this.className=this.className.replace(new RegExp("(^|\\s)"+l+"(?:\\s|$)"),"$1");return this;},toggleClass:function(l){return this.hasClass(l)?this.removeClass(l):this.addClass(l); +},adopt:function(){Array.flatten(arguments).each(function(l){l=document.id(l,true);if(l){this.appendChild(l);}},this);return this;},appendText:function(m,l){return this.grab(this.getDocument().newTextNode(m),l); +},grab:function(m,l){a[l||"bottom"](document.id(m,true),this);return this;},inject:function(m,l){a[l||"bottom"](this,document.id(m,true));return this;},replaces:function(l){l=document.id(l,true); +l.parentNode.replaceChild(this,l);return this;},wraps:function(m,l){m=document.id(m,true);return this.replaces(m).grab(m,l);},getPrevious:function(l,m){return j(this,"previousSibling",null,l,false,m); +},getAllPrevious:function(l,m){return j(this,"previousSibling",null,l,true,m);},getNext:function(l,m){return j(this,"nextSibling",null,l,false,m);},getAllNext:function(l,m){return j(this,"nextSibling",null,l,true,m); +},getFirst:function(l,m){return j(this,"nextSibling","firstChild",l,false,m);},getLast:function(l,m){return j(this,"previousSibling","lastChild",l,false,m); +},getParent:function(l,m){return j(this,"parentNode",null,l,false,m);},getParents:function(l,m){return j(this,"parentNode",null,l,true,m);},getSiblings:function(l,m){return this.getParent().getChildren(l,m).erase(this); +},getChildren:function(l,m){return j(this,"nextSibling","firstChild",l,true,m);},getWindow:function(){return this.ownerDocument.window;},getDocument:function(){return this.ownerDocument; +},getElementById:function(o,n){var m=this.ownerDocument.getElementById(o);if(!m){return null;}for(var l=m.parentNode;l!=this;l=l.parentNode){if(!l){return null; +}}return document.id(m,n);},getSelected:function(){return new Elements($A(this.options).filter(function(l){return l.selected;}));},getComputedStyle:function(m){if(this.currentStyle){return this.currentStyle[m.camelCase()]; +}var l=this.getDocument().defaultView.getComputedStyle(this,null);return(l)?l.getPropertyValue([m.hyphenate()]):null;},toQueryString:function(){var l=[]; +this.getElements("input, select, textarea",true).each(function(m){if(!m.name||m.disabled||m.type=="submit"||m.type=="reset"||m.type=="file"){return;}var n=(m.tagName.toLowerCase()=="select")?Element.getSelected(m).map(function(o){return o.value; +}):((m.type=="radio"||m.type=="checkbox")&&!m.checked)?null:m.value;$splat(n).each(function(o){if(typeof o!="undefined"){l.push(m.name+"="+encodeURIComponent(o)); +}});});return l.join("&");},clone:function(o,l){o=o!==false;var r=this.cloneNode(o);var n=function(v,u){if(!l){v.removeAttribute("id");}if(Browser.Engine.trident){v.clearAttributes(); +v.mergeAttributes(u);v.removeAttribute("uid");if(v.options){var w=v.options,s=u.options;for(var t=w.length;t--;){w[t].selected=s[t].selected;}}}var x=i[u.tagName.toLowerCase()]; +if(x&&u[x]){v[x]=u[x];}};if(o){var p=r.getElementsByTagName("*"),q=this.getElementsByTagName("*");for(var m=p.length;m--;){n(p[m],q[m]);}}n(r,this);return document.id(r); +},destroy:function(){Element.empty(this);Element.dispose(this);g(this,true);return null;},empty:function(){$A(this.childNodes).each(function(l){Element.destroy(l); +});return this;},dispose:function(){return(this.parentNode)?this.parentNode.removeChild(this):this;},hasChild:function(l){l=document.id(l,true);if(!l){return false; +}if(Browser.Engine.webkit&&Browser.Engine.version<420){return $A(this.getElementsByTagName(l.tagName)).contains(l);}return(this.contains)?(this!=l&&this.contains(l)):!!(this.compareDocumentPosition(l)&16); +},match:function(l){return(!l||(l==this)||(Element.get(this,"tag")==l));}});Native.implement([Element,Window,Document],{addListener:function(o,n){if(o=="unload"){var l=n,m=this; +n=function(){m.removeListener("unload",n);l();};}else{h[this.uid]=this;}if(this.addEventListener){this.addEventListener(o,n,false);}else{this.attachEvent("on"+o,n); +}return this;},removeListener:function(m,l){if(this.removeEventListener){this.removeEventListener(m,l,false);}else{this.detachEvent("on"+m,l);}return this; +},retrieve:function(m,l){var o=c(this.uid),n=o[m];if(l!=undefined&&n==undefined){n=o[m]=l;}return $pick(n);},store:function(m,l){var n=c(this.uid);n[m]=l; +return this;},eliminate:function(l){var m=c(this.uid);delete m[l];return this;}});window.addListener("unload",d);})();Element.Properties=new Hash;Element.Properties.style={set:function(a){this.style.cssText=a; +},get:function(){return this.style.cssText;},erase:function(){this.style.cssText="";}};Element.Properties.tag={get:function(){return this.tagName.toLowerCase(); +}};Element.Properties.html=(function(){var c=document.createElement("div");var a={table:[1,"","
"],select:[1,""],tbody:[2,"","
"],tr:[3,"","
"]}; +a.thead=a.tfoot=a.tbody;var b={set:function(){var e=Array.flatten(arguments).join("");var f=Browser.Engine.trident&&a[this.get("tag")];if(f){var g=c;g.innerHTML=f[1]+e+f[2]; +for(var d=f[0];d--;){g=g.firstChild;}this.empty().adopt(g.childNodes);}else{this.innerHTML=e;}}};b.erase=b.set;return b;})();if(Browser.Engine.webkit&&Browser.Engine.version<420){Element.Properties.text={get:function(){if(this.innerText){return this.innerText; +}var a=this.ownerDocument.newElement("div",{html:this.innerHTML}).inject(this.ownerDocument.body);var b=a.innerText;a.destroy();return b;}};}Element.Properties.events={set:function(a){this.addEvents(a); +}};Native.implement([Element,Window,Document],{addEvent:function(e,g){var h=this.retrieve("events",{});h[e]=h[e]||{keys:[],values:[]};if(h[e].keys.contains(g)){return this; +}h[e].keys.push(g);var f=e,a=Element.Events.get(e),c=g,i=this;if(a){if(a.onAdd){a.onAdd.call(this,g);}if(a.condition){c=function(j){if(a.condition.call(this,j)){return g.call(this,j); +}return true;};}f=a.base||f;}var d=function(){return g.call(i);};var b=Element.NativeEvents[f];if(b){if(b==2){d=function(j){j=new Event(j,i.getWindow()); +if(c.call(i,j)===false){j.stop();}};}this.addListener(f,d);}h[e].values.push(d);return this;},removeEvent:function(c,b){var a=this.retrieve("events");if(!a||!a[c]){return this; +}var f=a[c].keys.indexOf(b);if(f==-1){return this;}a[c].keys.splice(f,1);var e=a[c].values.splice(f,1)[0];var d=Element.Events.get(c);if(d){if(d.onRemove){d.onRemove.call(this,b); +}c=d.base||c;}return(Element.NativeEvents[c])?this.removeListener(c,e):this;},addEvents:function(a){for(var b in a){this.addEvent(b,a[b]);}return this; +},removeEvents:function(a){var c;if($type(a)=="object"){for(c in a){this.removeEvent(c,a[c]);}return this;}var b=this.retrieve("events");if(!b){return this; +}if(!a){for(c in b){this.removeEvents(c);}this.eliminate("events");}else{if(b[a]){while(b[a].keys[0]){this.removeEvent(a,b[a].keys[0]);}b[a]=null;}}return this; +},fireEvent:function(d,b,a){var c=this.retrieve("events");if(!c||!c[d]){return this;}c[d].keys.each(function(e){e.create({bind:this,delay:a,"arguments":b})(); +},this);return this;},cloneEvents:function(d,a){d=document.id(d);var c=d.retrieve("events");if(!c){return this;}if(!a){for(var b in c){this.cloneEvents(d,b); +}}else{if(c[a]){c[a].keys.each(function(e){this.addEvent(a,e);},this);}}return this;}});Element.NativeEvents={click:2,dblclick:2,mouseup:2,mousedown:2,contextmenu:2,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:1,unload:1,beforeunload:2,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1}; +(function(){var a=function(b){var c=b.relatedTarget;if(c==undefined){return true;}if(c===false){return false;}return($type(this)!="document"&&c!=this&&c.prefix!="xul"&&!this.hasChild(c)); +};Element.Events=new Hash({mouseenter:{base:"mouseover",condition:a},mouseleave:{base:"mouseout",condition:a},mousewheel:{base:(Browser.Engine.gecko)?"DOMMouseScroll":"mousewheel"}}); +})();Element.Properties.styles={set:function(a){this.setStyles(a);}};Element.Properties.opacity={set:function(a,b){if(!b){if(a==0){if(this.style.visibility!="hidden"){this.style.visibility="hidden"; +}}else{if(this.style.visibility!="visible"){this.style.visibility="visible";}}}if(!this.currentStyle||!this.currentStyle.hasLayout){this.style.zoom=1;}if(Browser.Engine.trident){this.style.filter=(a==1)?"":"alpha(opacity="+a*100+")"; +}this.style.opacity=a;this.store("opacity",a);},get:function(){return this.retrieve("opacity",1);}};Element.implement({setOpacity:function(a){return this.set("opacity",a,true); +},getOpacity:function(){return this.get("opacity");},setStyle:function(b,a){switch(b){case"opacity":return this.set("opacity",parseFloat(a));case"float":b=(Browser.Engine.trident)?"styleFloat":"cssFloat"; +}b=b.camelCase();if($type(a)!="string"){var c=(Element.Styles.get(b)||"@").split(" ");a=$splat(a).map(function(e,d){if(!c[d]){return"";}return($type(e)=="number")?c[d].replace("@",Math.round(e)):e; +}).join(" ");}else{if(a==String(Number(a))){a=Math.round(a);}}this.style[b]=a;return this;},getStyle:function(g){switch(g){case"opacity":return this.get("opacity"); +case"float":g=(Browser.Engine.trident)?"styleFloat":"cssFloat";}g=g.camelCase();var a=this.style[g];if(!$chk(a)){a=[];for(var f in Element.ShortStyles){if(g!=f){continue; +}for(var e in Element.ShortStyles[f]){a.push(this.getStyle(e));}return a.join(" ");}a=this.getComputedStyle(g);}if(a){a=String(a);var c=a.match(/rgba?\([\d\s,]+\)/); +if(c){a=a.replace(c[0],c[0].rgbToHex());}}if(Browser.Engine.presto||(Browser.Engine.trident&&!$chk(parseInt(a,10)))){if(g.test(/^(height|width)$/)){var b=(g=="width")?["left","right"]:["top","bottom"],d=0; +b.each(function(h){d+=this.getStyle("border-"+h+"-width").toInt()+this.getStyle("padding-"+h).toInt();},this);return this["offset"+g.capitalize()]-d+"px"; +}if((Browser.Engine.presto)&&String(a).test("px")){return a;}if(g.test(/(border(.+)Width|margin|padding)/)){return"0px";}}return a;},setStyles:function(b){for(var a in b){this.setStyle(a,b[a]); +}return this;},getStyles:function(){var a={};Array.flatten(arguments).each(function(b){a[b]=this.getStyle(b);},this);return a;}});Element.Styles=new Hash({left:"@px",top:"@px",bottom:"@px",right:"@px",width:"@px",height:"@px",maxWidth:"@px",maxHeight:"@px",minWidth:"@px",minHeight:"@px",backgroundColor:"rgb(@, @, @)",backgroundPosition:"@px @px",color:"rgb(@, @, @)",fontSize:"@px",letterSpacing:"@px",lineHeight:"@px",clip:"rect(@px @px @px @px)",margin:"@px @px @px @px",padding:"@px @px @px @px",border:"@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",borderWidth:"@px @px @px @px",borderStyle:"@ @ @ @",borderColor:"rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",zIndex:"@",zoom:"@",fontWeight:"@",textIndent:"@px",opacity:"@"}); +Element.ShortStyles={margin:{},padding:{},border:{},borderWidth:{},borderStyle:{},borderColor:{}};["Top","Right","Bottom","Left"].each(function(g){var f=Element.ShortStyles; +var b=Element.Styles;["margin","padding"].each(function(h){var i=h+g;f[h][i]=b[i]="@px";});var e="border"+g;f.border[e]=b[e]="@px @ rgb(@, @, @)";var d=e+"Width",a=e+"Style",c=e+"Color"; +f[e]={};f.borderWidth[d]=f[e][d]=b[d]="@px";f.borderStyle[a]=f[e][a]=b[a]="@";f.borderColor[c]=f[e][c]=b[c]="rgb(@, @, @)";});(function(){Element.implement({scrollTo:function(h,i){if(b(this)){this.getWindow().scrollTo(h,i); +}else{this.scrollLeft=h;this.scrollTop=i;}return this;},getSize:function(){if(b(this)){return this.getWindow().getSize();}return{x:this.offsetWidth,y:this.offsetHeight}; +},getScrollSize:function(){if(b(this)){return this.getWindow().getScrollSize();}return{x:this.scrollWidth,y:this.scrollHeight};},getScroll:function(){if(b(this)){return this.getWindow().getScroll(); +}return{x:this.scrollLeft,y:this.scrollTop};},getScrolls:function(){var i=this,h={x:0,y:0};while(i&&!b(i)){h.x+=i.scrollLeft;h.y+=i.scrollTop;i=i.parentNode; +}return h;},getOffsetParent:function(){var h=this;if(b(h)){return null;}if(!Browser.Engine.trident){return h.offsetParent;}while((h=h.parentNode)&&!b(h)){if(d(h,"position")!="static"){return h; +}}return null;},getOffsets:function(){if(this.getBoundingClientRect){var j=this.getBoundingClientRect(),m=document.id(this.getDocument().documentElement),p=m.getScroll(),k=this.getScrolls(),i=this.getScroll(),h=(d(this,"position")=="fixed"); +return{x:j.left.toInt()+k.x-i.x+((h)?0:p.x)-m.clientLeft,y:j.top.toInt()+k.y-i.y+((h)?0:p.y)-m.clientTop};}var l=this,n={x:0,y:0};if(b(this)){return n; +}while(l&&!b(l)){n.x+=l.offsetLeft;n.y+=l.offsetTop;if(Browser.Engine.gecko){if(!f(l)){n.x+=c(l);n.y+=g(l);}var o=l.parentNode;if(o&&d(o,"overflow")!="visible"){n.x+=c(o); +n.y+=g(o);}}else{if(l!=this&&Browser.Engine.webkit){n.x+=c(l);n.y+=g(l);}}l=l.offsetParent;}if(Browser.Engine.gecko&&!f(this)){n.x-=c(this);n.y-=g(this); +}return n;},getPosition:function(k){if(b(this)){return{x:0,y:0};}var l=this.getOffsets(),i=this.getScrolls();var h={x:l.x-i.x,y:l.y-i.y};var j=(k&&(k=document.id(k)))?k.getPosition():{x:0,y:0}; +return{x:h.x-j.x,y:h.y-j.y};},getCoordinates:function(j){if(b(this)){return this.getWindow().getCoordinates();}var h=this.getPosition(j),i=this.getSize(); +var k={left:h.x,top:h.y,width:i.x,height:i.y};k.right=k.left+k.width;k.bottom=k.top+k.height;return k;},computePosition:function(h){return{left:h.x-e(this,"margin-left"),top:h.y-e(this,"margin-top")}; +},setPosition:function(h){return this.setStyles(this.computePosition(h));}});Native.implement([Document,Window],{getSize:function(){if(Browser.Engine.presto||Browser.Engine.webkit){var i=this.getWindow(); +return{x:i.innerWidth,y:i.innerHeight};}var h=a(this);return{x:h.clientWidth,y:h.clientHeight};},getScroll:function(){var i=this.getWindow(),h=a(this); +return{x:i.pageXOffset||h.scrollLeft,y:i.pageYOffset||h.scrollTop};},getScrollSize:function(){var i=a(this),h=this.getSize();return{x:Math.max(i.scrollWidth,h.x),y:Math.max(i.scrollHeight,h.y)}; +},getPosition:function(){return{x:0,y:0};},getCoordinates:function(){var h=this.getSize();return{top:0,left:0,bottom:h.y,right:h.x,height:h.y,width:h.x}; +}});var d=Element.getComputedStyle;function e(h,i){return d(h,i).toInt()||0;}function f(h){return d(h,"-moz-box-sizing")=="border-box";}function g(h){return e(h,"border-top-width"); +}function c(h){return e(h,"border-left-width");}function b(h){return(/^(?:body|html)$/i).test(h.tagName);}function a(h){var i=h.getDocument();return(!i.compatMode||i.compatMode=="CSS1Compat")?i.html:i.body; +}})();Element.alias("setPosition","position");Native.implement([Window,Document,Element],{getHeight:function(){return this.getSize().y;},getWidth:function(){return this.getSize().x; +},getScrollTop:function(){return this.getScroll().y;},getScrollLeft:function(){return this.getScroll().x;},getScrollHeight:function(){return this.getScrollSize().y; +},getScrollWidth:function(){return this.getScrollSize().x;},getTop:function(){return this.getPosition().y;},getLeft:function(){return this.getPosition().x; +}});Native.implement([Document,Element],{getElements:function(h,g){h=h.split(",");var c,e={};for(var d=0,b=h.length;d1),cash:!g});}});Element.implement({match:function(b){if(!b||(b==this)){return true; +}var d=Selectors.Utils.parseTagAndID(b);var a=d[0],e=d[1];if(!Selectors.Filters.byID(this,e)||!Selectors.Filters.byTag(this,a)){return false;}var c=Selectors.Utils.parseSelector(b); +return(c)?Selectors.Utils.filter(this,c,{}):true;}});var Selectors={Cache:{nth:{},parsed:{}}};Selectors.RegExps={id:(/#([\w-]+)/),tag:(/^(\w+|\*)/),quick:(/^(\w+|\*)$/),splitter:(/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g),combined:(/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)(["']?)([^\4]*?)\4)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g)}; +Selectors.Utils={chk:function(b,c){if(!c){return true;}var a=$uid(b);if(!c[a]){return c[a]=true;}return false;},parseNthArgument:function(h){if(Selectors.Cache.nth[h]){return Selectors.Cache.nth[h]; +}var e=h.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/);if(!e){return false;}var g=parseInt(e[1],10);var d=(g||g===0)?g:1;var f=e[2]||false;var c=parseInt(e[3],10)||0; +if(d!=0){c--;while(c<1){c+=d;}while(c>=d){c-=d;}}else{d=c;f="index";}switch(f){case"n":e={a:d,b:c,special:"n"};break;case"odd":e={a:2,b:0,special:"n"}; +break;case"even":e={a:2,b:1,special:"n"};break;case"first":e={a:0,special:"index"};break;case"last":e={special:"last-child"};break;case"only":e={special:"only-child"}; +break;default:e={a:(d-1),special:"index"};}return Selectors.Cache.nth[h]=e;},parseSelector:function(e){if(Selectors.Cache.parsed[e]){return Selectors.Cache.parsed[e]; +}var d,h={classes:[],pseudos:[],attributes:[]};while((d=Selectors.RegExps.combined.exec(e))){var i=d[1],g=d[2],f=d[3],b=d[5],c=d[6],j=d[7];if(i){h.classes.push(i); +}else{if(c){var a=Selectors.Pseudo.get(c);if(a){h.pseudos.push({parser:a,argument:j});}else{h.attributes.push({name:c,operator:"=",value:j});}}else{if(g){h.attributes.push({name:g,operator:f,value:b}); +}}}}if(!h.classes.length){delete h.classes;}if(!h.attributes.length){delete h.attributes;}if(!h.pseudos.length){delete h.pseudos;}if(!h.classes&&!h.attributes&&!h.pseudos){h=null; +}return Selectors.Cache.parsed[e]=h;},parseTagAndID:function(b){var a=b.match(Selectors.RegExps.tag);var c=b.match(Selectors.RegExps.id);return[(a)?a[1]:"*",(c)?c[1]:false]; +},filter:function(f,c,e){var d;if(c.classes){for(d=c.classes.length;d--;d){var g=c.classes[d];if(!Selectors.Filters.byClass(f,g)){return false;}}}if(c.attributes){for(d=c.attributes.length; +d--;d){var b=c.attributes[d];if(!Selectors.Filters.byAttribute(f,b.name,b.operator,b.value)){return false;}}}if(c.pseudos){for(d=c.pseudos.length;d--;d){var a=c.pseudos[d]; +if(!Selectors.Filters.byPseudo(f,a.parser,a.argument,e)){return false;}}}return true;},getByTagAndID:function(b,a,d){if(d){var c=(b.getElementById)?b.getElementById(d,true):Element.getElementById(b,d,true); +return(c&&Selectors.Filters.byTag(c,a))?[c]:[];}else{return b.getElementsByTagName(a);}},search:function(o,h,t){var b=[];var c=h.trim().replace(Selectors.RegExps.splitter,function(k,j,i){b.push(j); +return":)"+i;}).split(":)");var p,e,A;for(var z=0,v=c.length;z":function(h,g,j,a,f){var c=Selectors.Utils.getByTagAndID(g,j,a);for(var e=0,d=c.length;ea){return false;}}return(c==a);},even:function(b,a){return Selectors.Pseudo["nth-child"].call(this,"2n+1",a); +},odd:function(b,a){return Selectors.Pseudo["nth-child"].call(this,"2n",a);},selected:function(){return this.selected;},enabled:function(){return(this.disabled===false); +}});Element.Events.domready={onAdd:function(a){if(Browser.loaded){a.call(this);}}};(function(){var b=function(){if(Browser.loaded){return;}Browser.loaded=true; +window.fireEvent("domready");document.fireEvent("domready");};window.addEvent("load",b);if(Browser.Engine.trident){var a=document.createElement("div"); +(function(){($try(function(){a.doScroll();return document.id(a).inject(document.body).set("html","temp").dispose();}))?b():arguments.callee.delay(50);})(); +}else{if(Browser.Engine.webkit&&Browser.Engine.version<525){(function(){(["loaded","complete"].contains(document.readyState))?b():arguments.callee.delay(50); +})();}else{document.addEvent("DOMContentLoaded",b);}}})();var JSON=new Hash(this.JSON&&{stringify:JSON.stringify,parse:JSON.parse}).extend({$specialChars:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},$replaceChars:function(a){return JSON.$specialChars[a]||"\\u00"+Math.floor(a.charCodeAt()/16).toString(16)+(a.charCodeAt()%16).toString(16); +},encode:function(b){switch($type(b)){case"string":return'"'+b.replace(/[\x00-\x1f\\"]/g,JSON.$replaceChars)+'"';case"array":return"["+String(b.map(JSON.encode).clean())+"]"; +case"object":case"hash":var a=[];Hash.each(b,function(e,d){var c=JSON.encode(e);if(c){a.push(JSON.encode(d)+":"+c);}});return"{"+a+"}";case"number":case"boolean":return String(b); +case false:return"null";}return null;},decode:function(string,secure){if($type(string)!="string"||!string.length){return null;}if(secure&&!(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"/g,""))){return null; +}return eval("("+string+")");}});Native.implement([Hash,Array,String,Number],{toJSON:function(){return JSON.encode(this);}});var Cookie=new Class({Implements:Options,options:{path:false,domain:false,duration:false,secure:false,document:document},initialize:function(b,a){this.key=b; +this.setOptions(a);},write:function(b){b=encodeURIComponent(b);if(this.options.domain){b+="; domain="+this.options.domain;}if(this.options.path){b+="; path="+this.options.path; +}if(this.options.duration){var a=new Date();a.setTime(a.getTime()+this.options.duration*24*60*60*1000);b+="; expires="+a.toGMTString();}if(this.options.secure){b+="; secure"; +}this.options.document.cookie=this.key+"="+b;return this;},read:function(){var a=this.options.document.cookie.match("(?:^|;)\\s*"+this.key.escapeRegExp()+"=([^;]*)"); +return(a)?decodeURIComponent(a[1]):null;},dispose:function(){new Cookie(this.key,$merge(this.options,{duration:-1})).write("");return this;}});Cookie.write=function(b,c,a){return new Cookie(b,a).write(c); +};Cookie.read=function(a){return new Cookie(a).read();};Cookie.dispose=function(b,a){return new Cookie(b,a).dispose();};var Swiff=new Class({Implements:[Options],options:{id:null,height:1,width:1,container:null,properties:{},params:{quality:"high",allowScriptAccess:"always",wMode:"transparent",swLiveConnect:true},callBacks:{},vars:{}},toElement:function(){return this.object; +},initialize:function(l,m){this.instance="Swiff_"+$time();this.setOptions(m);m=this.options;var b=this.id=m.id||this.instance;var a=document.id(m.container); +Swiff.CallBacks[this.instance]={};var e=m.params,g=m.vars,f=m.callBacks;var h=$extend({height:m.height,width:m.width},m.properties);var k=this;for(var d in f){Swiff.CallBacks[this.instance][d]=(function(n){return function(){return n.apply(k.object,arguments); +};})(f[d]);g[d]="Swiff.CallBacks."+this.instance+"."+d;}e.flashVars=Hash.toQueryString(g);if(Browser.Engine.trident){h.classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"; +e.movie=l;}else{h.type="application/x-shockwave-flash";h.data=l;}var j=''; +}}j+="";this.object=((a)?a.empty():new Element("div")).set("html",j).firstChild;},replaces:function(a){a=document.id(a,true);a.parentNode.replaceChild(this.toElement(),a); +return this;},inject:function(a){document.id(a,true).appendChild(this.toElement());return this;},remote:function(){return Swiff.remote.apply(Swiff,[this.toElement()].extend(arguments)); +}});Swiff.CallBacks={};Swiff.remote=function(obj,fn){var rs=obj.CallFunction(''+__flash__argumentsToXML(arguments,2)+""); +return eval(rs);};var Fx=new Class({Implements:[Chain,Events,Options],options:{fps:50,unit:false,duration:500,link:"ignore"},initialize:function(a){this.subject=this.subject||this; +this.setOptions(a);this.options.duration=Fx.Durations[this.options.duration]||this.options.duration.toInt();var b=this.options.wait;if(b===false){this.options.link="cancel"; +}},getTransition:function(){return function(a){return -(Math.cos(Math.PI*a)-1)/2;};},step:function(){var a=$time();if(a=(7-4*d)/11){e=c*c-Math.pow((11-6*d-11*f)/4,2); +break;}}return e;},Elastic:function(b,a){return Math.pow(2,10*--b)*Math.cos(20*b*Math.PI*(a[0]||1)/3);}});["Quad","Cubic","Quart","Quint"].each(function(b,a){Fx.Transitions[b]=new Fx.Transition(function(c){return Math.pow(c,[a+2]); +});});var Request=new Class({Implements:[Chain,Events,Options],options:{url:"",data:"",headers:{"X-Requested-With":"XMLHttpRequest",Accept:"text/javascript, text/html, application/xml, text/xml, */*"},async:true,format:false,method:"post",link:"ignore",isSuccess:null,emulation:true,urlEncoded:true,encoding:"utf-8",evalScripts:false,evalResponse:false,noCache:false},initialize:function(a){this.xhr=new Browser.Request(); +this.setOptions(a);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers=new Hash(this.options.headers);},onStateChange:function(){if(this.xhr.readyState!=4||!this.running){return; +}this.running=false;this.status=0;$try(function(){this.status=this.xhr.status;}.bind(this));this.xhr.onreadystatechange=$empty;if(this.options.isSuccess.call(this,this.status)){this.response={text:this.xhr.responseText,xml:this.xhr.responseXML}; +this.success(this.response.text,this.response.xml);}else{this.response={text:null,xml:null};this.failure();}},isSuccess:function(){return((this.status>=200)&&(this.status<300)); +},processScripts:function(a){if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){return $exec(a);}return a.stripScripts(this.options.evalScripts); +},success:function(b,a){this.onSuccess(this.processScripts(b),a);},onSuccess:function(){this.fireEvent("complete",arguments).fireEvent("success",arguments).callChain(); +},failure:function(){this.onFailure();},onFailure:function(){this.fireEvent("complete").fireEvent("failure",this.xhr);},setHeader:function(a,b){this.headers.set(a,b); +return this;},getHeader:function(a){return $try(function(){return this.xhr.getResponseHeader(a);}.bind(this));},check:function(){if(!this.running){return true; +}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(this.caller.bind(this,arguments));return false;}return false;},send:function(k){if(!this.check(k)){return this; +}this.running=true;var i=$type(k);if(i=="string"||i=="element"){k={data:k};}var d=this.options;k=$extend({data:d.data,url:d.url,method:d.method},k);var g=k.data,b=String(k.url),a=k.method.toLowerCase(); +switch($type(g)){case"element":g=document.id(g).toQueryString();break;case"object":case"hash":g=Hash.toQueryString(g);}if(this.options.format){var j="format="+this.options.format; +g=(g)?j+"&"+g:j;}if(this.options.emulation&&!["get","post"].contains(a)){var h="_method="+a;g=(g)?h+"&"+g:h;a="post";}if(this.options.urlEncoded&&a=="post"){var c=(this.options.encoding)?"; charset="+this.options.encoding:""; +this.headers.set("Content-type","application/x-www-form-urlencoded"+c);}if(this.options.noCache){var f="noCache="+new Date().getTime();g=(g)?f+"&"+g:f; +}var e=b.lastIndexOf("/");if(e>-1&&(e=b.indexOf("#"))>-1){b=b.substr(0,e);}if(g&&a=="get"){b=b+(b.contains("?")?"&":"?")+g;g=null;}this.xhr.open(a.toUpperCase(),b,this.options.async); +this.xhr.onreadystatechange=this.onStateChange.bind(this);this.headers.each(function(m,l){try{this.xhr.setRequestHeader(l,m);}catch(n){this.fireEvent("exception",[l,m]); +}},this);this.fireEvent("request");this.xhr.send(g);if(!this.options.async){this.onStateChange();}return this;},cancel:function(){if(!this.running){return this; +}this.running=false;this.xhr.abort();this.xhr.onreadystatechange=$empty;this.xhr=new Browser.Request();this.fireEvent("cancel");return this;}});(function(){var a={}; +["get","post","put","delete","GET","POST","PUT","DELETE"].each(function(b){a[b]=function(){var c=Array.link(arguments,{url:String.type,data:$defined}); +return this.send($extend(c,{method:b}));};});Request.implement(a);})();Element.Properties.send={set:function(a){var b=this.retrieve("send");if(b){b.cancel(); +}return this.eliminate("send").store("send:options",$extend({data:this,link:"cancel",method:this.get("method")||"post",url:this.get("action")},a));},get:function(a){if(a||!this.retrieve("send")){if(a||!this.retrieve("send:options")){this.set("send",a); +}this.store("send",new Request(this.retrieve("send:options")));}return this.retrieve("send");}};Element.implement({send:function(a){var b=this.get("send"); +b.send({data:this,url:a||b.options.url});return this;}});Request.HTML=new Class({Extends:Request,options:{update:false,append:false,evalScripts:true,filter:false},processHTML:function(c){var b=c.match(/]*>([\s\S]*?)<\/body>/i); +c=(b)?b[1]:c;var a=new Element("div");return $try(function(){var d=""+c+"",g;if(Browser.Engine.trident){g=new ActiveXObject("Microsoft.XMLDOM"); +g.async=false;g.loadXML(d);}else{g=new DOMParser().parseFromString(d,"text/xml");}d=g.getElementsByTagName("root")[0];if(!d){return null;}for(var f=0,e=d.childNodes.length; +f. Copyright (c) 2006-2009 Aaron Newton , Valerio Proietti & the MooTools team , MIT Style License. + +MooTools.More={version:"1.2.4.4",build:"6f6057dc645fdb7547689183b2311063bd653ddf"};(function(){var a={language:"en-US",languages:{"en-US":{}},cascades:["en-US"]}; +var b;MooTools.lang=new Events();$extend(MooTools.lang,{setLanguage:function(c){if(!a.languages[c]){return this;}a.language=c;this.load();this.fireEvent("langChange",c); +return this;},load:function(){var c=this.cascade(this.getCurrentLanguage());b={};$each(c,function(e,d){b[d]=this.lambda(e);},this);},getCurrentLanguage:function(){return a.language; +},addLanguage:function(c){a.languages[c]=a.languages[c]||{};return this;},cascade:function(e){var c=(a.languages[e]||{}).cascades||[];c.combine(a.cascades); +c.erase(e).push(e);var d=c.map(function(f){return a.languages[f];},this);return $merge.apply(this,d);},lambda:function(c){(c||{}).get=function(e,d){return $lambda(c[e]).apply(this,$splat(d)); +};return c;},get:function(e,d,c){if(b&&b[e]){return(d?b[e].get(d,c):b[e]);}},set:function(d,e,c){this.addLanguage(d);langData=a.languages[d];if(!langData[e]){langData[e]={}; +}$extend(langData[e],c);if(d==this.getCurrentLanguage()){this.load();this.fireEvent("langChange",d);}return this;},list:function(){return Hash.getKeys(a.languages); +}});})();(function(){var c=this;var b=function(){if(c.console&&console.log){try{console.log.apply(console,arguments);}catch(d){console.log(Array.slice(arguments)); +}}else{Log.logged.push(arguments);}return this;};var a=function(){this.logged.push(arguments);return this;};this.Log=new Class({logged:[],log:a,resetLog:function(){this.logged.empty(); +return this;},enableLog:function(){this.log=b;this.logged.each(function(d){this.log.apply(this,d);},this);return this.resetLog();},disableLog:function(){this.log=a; +return this;}});Log.extend(new Log).enableLog();Log.logger=function(){return this.log.apply(this,arguments);};})();Class.refactor=function(b,a){$each(a,function(e,d){var c=b.prototype[d]; +if(c&&(c=c._origin)&&typeof e=="function"){b.implement(d,function(){var f=this.previous;this.previous=c;var g=e.apply(this,arguments);this.previous=f;return g; +});}else{b.implement(d,e);}});return b;};Class.Mutators.Binds=function(a){return a;};Class.Mutators.initialize=function(a){return function(){$splat(this.Binds).each(function(b){var c=this[b]; +if(c){this[b]=c.bind(this);}},this);return a.apply(this,arguments);};};Class.Occlude=new Class({occlude:function(c,b){b=document.id(b||this.element);var a=b.retrieve(c||this.property); +if(a&&!$defined(this.occluded)){return this.occluded=a;}this.occluded=false;b.store(c||this.property,this);return this.occluded;}});(function(){var i=this.Date; +if(!i.now){i.now=$time;}i.Methods={ms:"Milliseconds",year:"FullYear",min:"Minutes",mo:"Month",sec:"Seconds",hr:"Hours"};["Date","Day","FullYear","Hours","Milliseconds","Minutes","Month","Seconds","Time","TimezoneOffset","Week","Timezone","GMTOffset","DayOfYear","LastMonth","LastDayOfMonth","UTCDate","UTCDay","UTCFullYear","AMPM","Ordinal","UTCHours","UTCMilliseconds","UTCMinutes","UTCMonth","UTCSeconds"].each(function(p){i.Methods[p.toLowerCase()]=p; +});var d=function(q,p){return new Array(p-String(q).length+1).join("0")+q;};i.implement({set:function(t,r){switch($type(t)){case"object":for(var s in t){this.set(s,t[s]); +}break;case"string":t=t.toLowerCase();var q=i.Methods;if(q[t]){this["set"+q[t]](r);}}return this;},get:function(q){q=q.toLowerCase();var p=i.Methods;if(p[q]){return this["get"+p[q]](); +}return null;},clone:function(){return new i(this.get("time"));},increment:function(p,r){p=p||"day";r=$pick(r,1);switch(p){case"year":return this.increment("month",r*12); +case"month":var q=this.get("date");this.set("date",1).set("mo",this.get("mo")+r);return this.set("date",q.min(this.get("lastdayofmonth")));case"week":return this.increment("day",r*7); +case"day":return this.set("date",this.get("date")+r);}if(!i.units[p]){throw new Error(p+" is not a supported interval");}return this.set("time",this.get("time")+r*i.units[p]()); +},decrement:function(p,q){return this.increment(p,-1*$pick(q,1));},isLeapYear:function(){return i.isLeapYear(this.get("year"));},clearTime:function(){return this.set({hr:0,min:0,sec:0,ms:0}); +},diff:function(q,p){if($type(q)=="string"){q=i.parse(q);}return((q-this)/i.units[p||"day"](3,3)).toInt();},getLastDayOfMonth:function(){return i.daysInMonth(this.get("mo"),this.get("year")); +},getDayOfYear:function(){return(i.UTC(this.get("year"),this.get("mo"),this.get("date")+1)-i.UTC(this.get("year"),0,1))/i.units.day();},getWeek:function(){return(this.get("dayofyear")/7).ceil(); +},getOrdinal:function(p){return i.getMsg("ordinal",p||this.get("date"));},getTimezone:function(){return this.toString().replace(/^.*? ([A-Z]{3}).[0-9]{4}.*$/,"$1").replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/,"$1$2$3"); +},getGMTOffset:function(){var p=this.get("timezoneOffset");return((p>0)?"-":"+")+d((p.abs()/60).floor(),2)+d(p%60,2);},setAMPM:function(p){p=p.toUpperCase(); +var q=this.get("hr");if(q>11&&p=="AM"){return this.decrement("hour",12);}else{if(q<12&&p=="PM"){return this.increment("hour",12);}}return this;},getAMPM:function(){return(this.get("hr")<12)?"AM":"PM"; +},parse:function(p){this.set("time",i.parse(p));return this;},isValid:function(p){return !!(p||this).valueOf();},format:function(p){if(!this.isValid()){return"invalid date"; +}p=p||"%x %X";p=k[p.toLowerCase()]||p;var q=this;return p.replace(/%([a-z%])/gi,function(s,r){switch(r){case"a":return i.getMsg("days")[q.get("day")].substr(0,3); +case"A":return i.getMsg("days")[q.get("day")];case"b":return i.getMsg("months")[q.get("month")].substr(0,3);case"B":return i.getMsg("months")[q.get("month")]; +case"c":return q.toString();case"d":return d(q.get("date"),2);case"H":return d(q.get("hr"),2);case"I":return((q.get("hr")%12)||12);case"j":return d(q.get("dayofyear"),3); +case"m":return d((q.get("mo")+1),2);case"M":return d(q.get("min"),2);case"o":return q.get("ordinal");case"p":return i.getMsg(q.get("ampm"));case"S":return d(q.get("seconds"),2); +case"U":return d(q.get("week"),2);case"w":return q.get("day");case"x":return q.format(i.getMsg("shortDate"));case"X":return q.format(i.getMsg("shortTime")); +case"y":return q.get("year").toString().substr(2);case"Y":return q.get("year");case"T":return q.get("GMTOffset");case"Z":return q.get("Timezone");}return r; +});},toISOString:function(){return this.format("iso8601");}});i.alias("toISOString","toJSON");i.alias("diff","compare");i.alias("format","strftime");var k={db:"%Y-%m-%d %H:%M:%S",compact:"%Y%m%dT%H%M%S",iso8601:"%Y-%m-%dT%H:%M:%S%T",rfc822:"%a, %d %b %Y %H:%M:%S %Z","short":"%d %b %H:%M","long":"%B %d, %Y %H:%M"}; +var g=[];var e=i.parse;var n=function(s,u,r){var q=-1;var t=i.getMsg(s+"s");switch($type(u)){case"object":q=t[u.get(s)];break;case"number":q=t[month-1]; +if(!q){throw new Error("Invalid "+s+" index: "+index);}break;case"string":var p=t.filter(function(v){return this.test(v);},new RegExp("^"+u,"i"));if(!p.length){throw new Error("Invalid "+s+" string"); +}if(p.length>1){throw new Error("Ambiguous "+s);}q=p[0];}return(r)?t.indexOf(q):q;};i.extend({getMsg:function(q,p){return MooTools.lang.get("Date",q,p); +},units:{ms:$lambda(1),second:$lambda(1000),minute:$lambda(60000),hour:$lambda(3600000),day:$lambda(86400000),week:$lambda(608400000),month:function(q,p){var r=new i; +return i.daysInMonth($pick(q,r.get("mo")),$pick(p,r.get("year")))*86400000;},year:function(p){p=p||new i().get("year");return i.isLeapYear(p)?31622400000:31536000000; +}},daysInMonth:function(q,p){return[31,i.isLeapYear(p)?29:28,31,30,31,30,31,31,30,31,30,31][q];},isLeapYear:function(p){return((p%4===0)&&(p%100!==0))||(p%400===0); +},parse:function(r){var q=$type(r);if(q=="number"){return new i(r);}if(q!="string"){return r;}r=r.clean();if(!r.length){return null;}var p;g.some(function(t){var s=t.re.exec(r); +return(s)?(p=t.handler(s)):false;});return p||new i(e(r));},parseDay:function(p,q){return n("day",p,q);},parseMonth:function(q,p){return n("month",q,p); +},parseUTC:function(q){var p=new i(q);var r=i.UTC(p.get("year"),p.get("mo"),p.get("date"),p.get("hr"),p.get("min"),p.get("sec"));return new i(r);},orderIndex:function(p){return i.getMsg("dateOrder").indexOf(p)+1; +},defineFormat:function(p,q){k[p]=q;},defineFormats:function(p){for(var q in p){i.defineFormat(q,p[q]);}},parsePatterns:g,defineParser:function(p){g.push((p.re&&p.handler)?p:l(p)); +},defineParsers:function(){Array.flatten(arguments).each(i.defineParser);},define2DigitYearStart:function(p){h=p%100;m=p-h;}});var m=1900;var h=70;var j=function(p){return new RegExp("(?:"+i.getMsg(p).map(function(q){return q.substr(0,3); +}).join("|")+")[a-z]*");};var a=function(p){switch(p){case"x":return((i.orderIndex("month")==1)?"%m[.-/]%d":"%d[.-/]%m")+"([.-/]%y)?";case"X":return"%H([.:]%M)?([.:]%S([.:]%s)?)? ?%p? ?%T?"; +}return null;};var o={d:/[0-2]?[0-9]|3[01]/,H:/[01]?[0-9]|2[0-3]/,I:/0?[1-9]|1[0-2]/,M:/[0-5]?\d/,s:/\d+/,o:/[a-z]*/,p:/[ap]\.?m\.?/,y:/\d{2}|\d{4}/,Y:/\d{4}/,T:/Z|[+-]\d{2}(?::?\d{2})?/}; +o.m=o.I;o.S=o.M;var c;var b=function(p){c=p;o.a=o.A=j("days");o.b=o.B=j("months");g.each(function(r,q){if(r.format){g[q]=l(r.format);}});};var l=function(r){if(!c){return{format:r}; +}var p=[];var q=(r.source||r).replace(/%([a-z])/gi,function(t,s){return a(s)||t;}).replace(/\((?!\?)/g,"(?:").replace(/ (?!\?|\*)/g,",? ").replace(/%([a-z%])/gi,function(t,s){var u=o[s]; +if(!u){return s;}p.push(s);return"("+u.source+")";}).replace(/\[a-z\]/gi,"[a-z\\u00c0-\\uffff]");return{format:r,re:new RegExp("^"+q+"$","i"),handler:function(u){u=u.slice(1).associate(p); +var s=new i().clearTime();if("d" in u){f.call(s,"d",1);}if("m" in u||"b" in u||"B" in u){f.call(s,"m",1);}for(var t in u){f.call(s,t,u[t]);}return s;}}; +};var f=function(p,q){if(!q){return this;}switch(p){case"a":case"A":return this.set("day",i.parseDay(q,true));case"b":case"B":return this.set("mo",i.parseMonth(q,true)); +case"d":return this.set("date",q);case"H":case"I":return this.set("hr",q);case"m":return this.set("mo",q-1);case"M":return this.set("min",q);case"p":return this.set("ampm",q.replace(/\./g,"")); +case"S":return this.set("sec",q);case"s":return this.set("ms",("0."+q)*1000);case"w":return this.set("day",q);case"Y":return this.set("year",q);case"y":q=+q; +if(q<100){q+=m+(q]*>([\\s\\S]*?)":"]+)?>";reg=new RegExp(g,"gi");return reg;};String.implement({standardize:function(){var e=this; +b.each(function(g,f){e=e.replace(new RegExp(g,"g"),a[f]);});return e;},repeat:function(e){return new Array(e+1).join(this);},pad:function(f,h,e){if(this.length>=f){return this; +}var g=(h==null?" ":""+h).repeat(f-this.length).substr(0,f-this.length);if(!e||e=="right"){return this+g;}if(e=="left"){return g+this;}return g.substr(0,(g.length/2).floor())+this+g.substr(0,(g.length/2).ceil()); +},getTags:function(e,f){return this.match(c(e,f))||[];},stripTags:function(e,f){return this.replace(c(e,f),"");},tidy:function(){var e=this.toString(); +$each(d,function(g,f){e=e.replace(new RegExp(f,"g"),g);});return e;}});})();String.implement({parseQueryString:function(){var b=this.split(/[&;]/),a={}; +if(b.length){b.each(function(g){var c=g.indexOf("="),d=c<0?[""]:g.substr(0,c).match(/[^\]\[]+/g),e=decodeURIComponent(g.substr(c+1)),f=a;d.each(function(j,h){var k=f[j]; +if(h0){a.pop(); +}else{if(d!="."){a.push(d);}}});return a.join("/")+"/";},combine:function(a){return a.value||a.scheme+"://"+(a.user?a.user+(a.password?":"+a.password:"")+"@":"")+(a.host||"")+(a.port&&a.port!=this.schemes[a.scheme]?":"+a.port:"")+(a.directory||"/")+(a.file||"")+(a.query?"?"+a.query:"")+(a.fragment?"#"+a.fragment:""); +},set:function(b,d,c){if(b=="value"){var a=d.match(URI.regs.scheme);if(a){a=a[1];}if(a&&!$defined(this.schemes[a.toLowerCase()])){this.parsed={scheme:a,value:d}; +}else{this.parsed=this.parse(d,(c||this).parsed)||(a?{scheme:a,value:d}:{value:d});}}else{if(b=="data"){this.setData(d);}else{this.parsed[b]=d;}}return this; +},get:function(a,b){switch(a){case"value":return this.combine(this.parsed,b?b.parsed:false);case"data":return this.getData();}return this.parsed[a]||""; +},go:function(){document.location.href=this.toString();},toURI:function(){return this;},getData:function(c,b){var a=this.get(b||"query");if(!$chk(a)){return c?null:{}; +}var d=a.parseQueryString();return c?d[c]:d;},setData:function(a,c,b){if(typeof a=="string"){data=this.getData();data[arguments[0]]=arguments[1];a=data; +}else{if(c){a=$merge(this.getData(),a);}}return this.set(b||"query",Hash.toQueryString(a));},clearData:function(a){return this.set(a||"query","");}});URI.prototype.toString=URI.prototype.valueOf=function(){return this.get("value"); +};URI.regs={endSlash:/\/$/,scheme:/^(\w+):/,directoryDot:/\.\/|\.$/};URI.base=new URI(document.getElements("base[href]",true).getLast(),{base:document.location}); +String.implement({toURI:function(a){return new URI(this,a);}});URI=Class.refactor(URI,{combine:function(f,e){if(!e||f.scheme!=e.scheme||f.host!=e.host||f.port!=e.port){return this.previous.apply(this,arguments); +}var a=f.file+(f.query?"?"+f.query:"")+(f.fragment?"#"+f.fragment:"");if(!e.directory){return(f.directory||(f.file?"":"./"))+a;}var d=e.directory.split("/"),c=f.directory.split("/"),g="",h; +var b=0;for(h=0;h~\s]/,f=function(g){var h=g.match(c);return !h?{event:g}:{event:h[1],selector:h[2]};},a=function(m,g){var k=m.target; +if(b.test(g=g.trim())){var j=this.getElements(g);for(var h=j.length;h--;){var l=j[h];if(k==l||l.hasChild(k)){return l;}}}else{for(;k&&k!=this;k=k.parentNode){if(Element.match(k,g)){return document.id(k); +}}}return null;};Element.implement({addEvent:function(j,i){var k=f(j);if(k.selector){var h=this.retrieve("$moo:delegateMonitors",{});if(!h[j]){var g=function(m){var l=a.call(this,m,k.selector); +if(l){this.fireEvent(j,[m,l],0,l);}}.bind(this);h[j]=g;d.call(this,k.event,g);}}return d.apply(this,arguments);},removeEvent:function(j,i){var k=f(j);if(k.selector){var h=this.retrieve("events"); +if(!h||!h[j]||(i&&!h[j].keys.contains(i))){return this;}if(i){e.apply(this,[j,i]);}else{e.apply(this,j);}h=this.retrieve("events");if(h&&h[j]&&h[j].keys.length==0){var g=this.retrieve("$moo:delegateMonitors",{}); +e.apply(this,[k.event,g[j]]);delete g[j];}return this;}return e.apply(this,arguments);},fireEvent:function(j,h,g,k){var i=this.retrieve("events");if(!i||!i[j]){return this; +}i[j].keys.each(function(l){l.create({bind:k||this,delay:g,arguments:h})();},this);return this;}});})(Element.prototype.addEvent,Element.prototype.removeEvent); +Element.implement({measure:function(e){var g=function(h){return !!(!h||h.offsetHeight||h.offsetWidth);};if(g(this)){return e.apply(this);}var d=this.getParent(),f=[],b=[]; +while(!g(d)&&d!=document.body){b.push(d.expose());d=d.getParent();}var c=this.expose();var a=e.apply(this);c();b.each(function(h){h();});return a;},expose:function(){if(this.getStyle("display")!="none"){return $empty; +}var a=this.style.cssText;this.setStyles({display:"block",position:"absolute",visibility:"hidden"});return function(){this.style.cssText=a;}.bind(this); +},getDimensions:function(a){a=$merge({computeSize:false},a);var f={};var d=function(g,e){return(e.computeSize)?g.getComputedSize(e):g.getSize();};var b=this.getParent("body"); +if(b&&this.getStyle("display")=="none"){f=this.measure(function(){return d(this,a);});}else{if(b){try{f=d(this,a);}catch(c){}}else{f={x:0,y:0};}}return $chk(f.x)?$extend(f,{width:f.x,height:f.y}):$extend(f,{x:f.width,y:f.height}); +},getComputedSize:function(a){a=$merge({styles:["padding","border"],plains:{height:["top","bottom"],width:["left","right"]},mode:"both"},a);var c={width:0,height:0}; +switch(a.mode){case"vertical":delete c.width;delete a.plains.width;break;case"horizontal":delete c.height;delete a.plains.height;break;}var b=[];$each(a.plains,function(g,f){g.each(function(h){a.styles.each(function(i){b.push((i=="border")?i+"-"+h+"-width":i+"-"+h); +});});});var e={};b.each(function(f){e[f]=this.getComputedStyle(f);},this);var d=[];$each(a.plains,function(g,f){var h=f.capitalize();c["total"+h]=c["computed"+h]=0; +g.each(function(i){c["computed"+i.capitalize()]=0;b.each(function(k,j){if(k.test(i)){e[k]=e[k].toInt()||0;c["total"+h]=c["total"+h]+e[k];c["computed"+i.capitalize()]=c["computed"+i.capitalize()]+e[k]; +}if(k.test(i)&&f!=k&&(k.test("border")||k.test("padding"))&&!d.contains(k)){d.push(k);c["computed"+h]=c["computed"+h]-e[k];}});});});["Width","Height"].each(function(g){var f=g.toLowerCase(); +if(!$chk(c[f])){return;}c[f]=c[f]+this["offset"+g]+c["computed"+g];c["total"+g]=c[f]+c["total"+g];delete c["computed"+g];},this);return $extend(e,c);}}); +(function(){var a=Element.prototype.position;Element.implement({position:function(g){if(g&&($defined(g.x)||$defined(g.y))){return a?a.apply(this,arguments):this; +}$each(g||{},function(u,t){if(!$defined(u)){delete g[t];}});g=$merge({relativeTo:document.body,position:{x:"center",y:"center"},edge:false,offset:{x:0,y:0},returnPos:false,relFixedPosition:false,ignoreMargins:false,ignoreScroll:false,allowNegative:false},g); +var r={x:0,y:0},e=false;var c=this.measure(function(){return document.id(this.getOffsetParent());});if(c&&c!=this.getDocument().body){r=c.measure(function(){return this.getPosition(); +});e=c!=document.id(g.relativeTo);g.offset.x=g.offset.x-r.x;g.offset.y=g.offset.y-r.y;}var s=function(t){if($type(t)!="string"){return t;}t=t.toLowerCase(); +var u={};if(t.test("left")){u.x="left";}else{if(t.test("right")){u.x="right";}else{u.x="center";}}if(t.test("upper")||t.test("top")){u.y="top";}else{if(t.test("bottom")){u.y="bottom"; +}else{u.y="center";}}return u;};g.edge=s(g.edge);g.position=s(g.position);if(!g.edge){if(g.position.x=="center"&&g.position.y=="center"){g.edge={x:"center",y:"center"}; +}else{g.edge={x:"left",y:"top"};}}this.setStyle("position","absolute");var f=document.id(g.relativeTo)||document.body,d=f==document.body?window.getScroll():f.getPosition(),l=d.y,h=d.x; +var n=this.getDimensions({computeSize:true,styles:["padding","border","margin"]});var j={},o=g.offset.y,q=g.offset.x,k=window.getSize();switch(g.position.x){case"left":j.x=h+q; +break;case"right":j.x=h+q+f.offsetWidth;break;default:j.x=h+((f==document.body?k.x:f.offsetWidth)/2)+q;break;}switch(g.position.y){case"top":j.y=l+o;break; +case"bottom":j.y=l+o+f.offsetHeight;break;default:j.y=l+((f==document.body?k.y:f.offsetHeight)/2)+o;break;}if(g.edge){var b={};switch(g.edge.x){case"left":b.x=0; +break;case"right":b.x=-n.x-n.computedRight-n.computedLeft;break;default:b.x=-(n.totalWidth/2);break;}switch(g.edge.y){case"top":b.y=0;break;case"bottom":b.y=-n.y-n.computedTop-n.computedBottom; +break;default:b.y=-(n.totalHeight/2);break;}j.x+=b.x;j.y+=b.y;}j={left:((j.x>=0||e||g.allowNegative)?j.x:0).toInt(),top:((j.y>=0||e||g.allowNegative)?j.y:0).toInt()}; +var i={left:"x",top:"y"};["minimum","maximum"].each(function(t){["left","top"].each(function(u){var v=g[t]?g[t][i[u]]:null;if(v!=null&&j[u]0&&b>0)?true:this.isDisplayed();},toggle:function(){return this[this.isDisplayed()?"hide":"show"](); +},hide:function(){var b;try{b=this.getStyle("display");}catch(a){}return this.store("originalDisplay",b||"").setStyle("display","none");},show:function(a){a=a||this.retrieve("originalDisplay")||"block"; +return this.setStyle("display",(a=="none")?"block":a);},swapClass:function(a,b){return this.removeClass(a).addClass(b);}});Fx.Elements=new Class({Extends:Fx.CSS,initialize:function(b,a){this.elements=this.subject=$$(b); +this.parent(a);},compute:function(g,h,j){var c={};for(var d in g){var a=g[d],e=h[d],f=c[d]={};for(var b in a){f[b]=this.parent(a[b],e[b],j);}}return c; +},set:function(b){for(var c in b){var a=b[c];for(var d in a){this.render(this.elements[c],d,a[d],this.options.unit);}}return this;},start:function(c){if(!this.check(c)){return this; +}var h={},j={};for(var d in c){var f=c[d],a=h[d]={},g=j[d]={};for(var b in f){var e=this.prepare(this.elements[d],b,f[b]);a[b]=e.from;g[b]=e.to;}}return this.parent(h,j); +}});Fx.Accordion=new Class({Extends:Fx.Elements,options:{display:0,show:false,height:true,width:false,opacity:true,alwaysHide:false,trigger:"click",initialDisplayFx:true,returnHeightToAuto:true},initialize:function(){var c=Array.link(arguments,{container:Element.type,options:Object.type,togglers:$defined,elements:$defined}); +this.parent(c.elements,c.options);this.togglers=$$(c.togglers);this.previous=-1;this.internalChain=new Chain();if(this.options.alwaysHide){this.options.wait=true; +}if($chk(this.options.show)){this.options.display=false;this.previous=this.options.show;}if(this.options.start){this.options.display=false;this.options.show=false; +}this.effects={};if(this.options.opacity){this.effects.opacity="fullOpacity";}if(this.options.width){this.effects.width=this.options.fixedWidth?"fullWidth":"offsetWidth"; +}if(this.options.height){this.effects.height=this.options.fixedHeight?"fullHeight":"scrollHeight";}for(var b=0,a=this.togglers.length;b0&&this.options.height)||h.offsetWidth>0&&this.options.width)){f=true; +this.selfHidden=true;}}this.fireEvent(f?"background":"active",[this.togglers[g],h]);for(var j in this.effects){e[g][j]=f?0:h[this.effects[j]];}},this); +this.internalChain.chain(function(){if(this.options.returnHeightToAuto&&!this.selfHidden){var f=this.elements[a];if(f){f.setStyle("height","auto");}}}.bind(this)); +return b?this.start(e):this.set(e);}});var Accordion=new Class({Extends:Fx.Accordion,initialize:function(){this.parent.apply(this,arguments);var a=Array.link(arguments,{container:Element.type}); +this.container=a.container;},addSection:function(c,b,e){c=document.id(c);b=document.id(b);var d=this.togglers.contains(c);var a=this.togglers.length;if(a&&(!d||e)){e=$pick(e,a-1); +c.inject(this.togglers[e],"before");b.inject(c,"after");}else{if(this.container&&!d){c.inject(this.container);b.inject(this.container);}}return this.parent.apply(this,arguments); +}});Fx.Move=new Class({Extends:Fx.Morph,options:{relativeTo:document.body,position:"center",edge:false,offset:{x:0,y:0}},start:function(a){return this.parent(this.element.position($merge(this.options,a,{returnPos:true}))); +}});Element.Properties.move={set:function(a){var b=this.retrieve("move");if(b){b.cancel();}return this.eliminate("move").store("move:options",$extend({link:"cancel"},a)); +},get:function(a){if(a||!this.retrieve("move")){if(a||!this.retrieve("move:options")){this.set("move",a);}this.store("move",new Fx.Move(this,this.retrieve("move:options"))); +}return this.retrieve("move");}};Element.implement({move:function(a){this.get("move").start(a);return this;}});Fx.Reveal=new Class({Extends:Fx.Morph,options:{link:"cancel",styles:["padding","border","margin"],transitionOpacity:!Browser.Engine.trident4,mode:"vertical",display:"block",hideInputs:Browser.Engine.trident?"select, input, textarea, object, embed":false},dissolve:function(){try{if(!this.hiding&&!this.showing){if(this.element.getStyle("display")!="none"){this.hiding=true; +this.showing=false;this.hidden=true;this.cssText=this.element.style.cssText;var d=this.element.getComputedSize({styles:this.options.styles,mode:this.options.mode}); +this.element.setStyle("display",this.options.display);if(this.options.transitionOpacity){d.opacity=1;}var b={};$each(d,function(f,e){b[e]=[f,0];},this); +this.element.setStyle("overflow","hidden");var a=this.options.hideInputs?this.element.getElements(this.options.hideInputs):null;this.$chain.unshift(function(){if(this.hidden){this.hiding=false; +$each(d,function(f,e){d[e]=f;},this);this.element.style.cssText=this.cssText;this.element.setStyle("display","none");if(a){a.setStyle("visibility","visible"); +}}this.fireEvent("hide",this.element);this.callChain();}.bind(this));if(a){a.setStyle("visibility","hidden");}this.start(b);}else{this.callChain.delay(10,this); +this.fireEvent("complete",this.element);this.fireEvent("hide",this.element);}}else{if(this.options.link=="chain"){this.chain(this.dissolve.bind(this)); +}else{if(this.options.link=="cancel"&&!this.hiding){this.cancel();this.dissolve();}}}}catch(c){this.hiding=false;this.element.setStyle("display","none"); +this.callChain.delay(10,this);this.fireEvent("complete",this.element);this.fireEvent("hide",this.element);}return this;},reveal:function(){try{if(!this.showing&&!this.hiding){if(this.element.getStyle("display")=="none"||this.element.getStyle("visiblity")=="hidden"||this.element.getStyle("opacity")==0){this.showing=true; +this.hiding=this.hidden=false;var d;this.cssText=this.element.style.cssText;this.element.measure(function(){d=this.element.getComputedSize({styles:this.options.styles,mode:this.options.mode}); +}.bind(this));$each(d,function(f,e){d[e]=f;});if($chk(this.options.heightOverride)){d.height=this.options.heightOverride.toInt();}if($chk(this.options.widthOverride)){d.width=this.options.widthOverride.toInt(); +}if(this.options.transitionOpacity){this.element.setStyle("opacity",0);d.opacity=1;}var b={height:0,display:this.options.display};$each(d,function(f,e){b[e]=0; +});this.element.setStyles($merge(b,{overflow:"hidden"}));var a=this.options.hideInputs?this.element.getElements(this.options.hideInputs):null;if(a){a.setStyle("visibility","hidden"); +}this.start(d);this.$chain.unshift(function(){this.element.style.cssText=this.cssText;this.element.setStyle("display",this.options.display);if(!this.hidden){this.showing=false; +}if(a){a.setStyle("visibility","visible");}this.callChain();this.fireEvent("show",this.element);}.bind(this));}else{this.callChain();this.fireEvent("complete",this.element); +this.fireEvent("show",this.element);}}else{if(this.options.link=="chain"){this.chain(this.reveal.bind(this));}else{if(this.options.link=="cancel"&&!this.showing){this.cancel(); +this.reveal();}}}}catch(c){this.element.setStyles({display:this.options.display,visiblity:"visible",opacity:1});this.showing=false;this.callChain.delay(10,this); +this.fireEvent("complete",this.element);this.fireEvent("show",this.element);}return this;},toggle:function(){if(this.element.getStyle("display")=="none"||this.element.getStyle("visiblity")=="hidden"||this.element.getStyle("opacity")==0){this.reveal(); +}else{this.dissolve();}return this;},cancel:function(){this.parent.apply(this,arguments);this.element.style.cssText=this.cssText;this.hidding=false;this.showing=false; +}});Element.Properties.reveal={set:function(a){var b=this.retrieve("reveal");if(b){b.cancel();}return this.eliminate("reveal").store("reveal:options",a); +},get:function(a){if(a||!this.retrieve("reveal")){if(a||!this.retrieve("reveal:options")){this.set("reveal",a);}this.store("reveal",new Fx.Reveal(this,this.retrieve("reveal:options"))); +}return this.retrieve("reveal");}};Element.Properties.dissolve=Element.Properties.reveal;Element.implement({reveal:function(a){this.get("reveal",a).reveal(); +return this;},dissolve:function(a){this.get("reveal",a).dissolve();return this;},nix:function(){var a=Array.link(arguments,{destroy:Boolean.type,options:Object.type}); +this.get("reveal",a.options).dissolve().chain(function(){this[a.destroy?"destroy":"dispose"]();}.bind(this));return this;},wink:function(){var b=Array.link(arguments,{duration:Number.type,options:Object.type}); +var a=this.get("reveal",b.options);a.reveal().chain(function(){(function(){a.dissolve();}).delay(b.duration||2000);});}});Fx.Scroll=new Class({Extends:Fx,options:{offset:{x:0,y:0},wheelStops:true},initialize:function(b,a){this.element=this.subject=document.id(b); +this.parent(a);var d=this.cancel.bind(this,false);if($type(this.element)!="element"){this.element=document.id(this.element.getDocument().body);}var c=this.element; +if(this.options.wheelStops){this.addEvent("start",function(){c.addEvent("mousewheel",d);},true);this.addEvent("complete",function(){c.removeEvent("mousewheel",d); +},true);}},set:function(){var a=Array.flatten(arguments);if(Browser.Engine.gecko){a=[Math.round(a[0]),Math.round(a[1])];}this.element.scrollTo(a[0],a[1]); +},compute:function(c,b,a){return[0,1].map(function(d){return Fx.compute(c[d],b[d],a);});},start:function(c,g){if(!this.check(c,g)){return this;}var e=this.element.getScrollSize(),b=this.element.getScroll(),d={x:c,y:g}; +for(var f in d){var a=e[f];if($chk(d[f])){d[f]=($type(d[f])=="number")?d[f]:a;}else{d[f]=b[f];}d[f]+=this.options.offset[f];}return this.parent([b.x,b.y],[d.x,d.y]); +},toTop:function(){return this.start(false,0);},toLeft:function(){return this.start(0,false);},toRight:function(){return this.start("right",false);},toBottom:function(){return this.start(false,"bottom"); +},toElement:function(b){var a=document.id(b).getPosition(this.element);return this.start(a.x,a.y);},scrollIntoView:function(c,e,d){e=e?$splat(e):["x","y"]; +var h={};c=document.id(c);var f=c.getPosition(this.element);var i=c.getSize();var g=this.element.getScroll();var a=this.element.getSize();var b={x:f.x+i.x,y:f.y+i.y}; +["x","y"].each(function(j){if(e.contains(j)){if(b[j]>g[j]+a[j]){h[j]=b[j]-a[j];}if(f[j]this.elements.length){e.splice(this.elements.length-1,e.length-this.elements.length); +}}var b=i=a=0;e.each(function(l,j){var k={};if(d){k.top=i-f[l].top-b;i+=f[l].height;}else{k.left=a-f[l].left;a+=f[l].width;}b=b+f[l].margin;c[l]=k;},this); +var g={};$A(e).sort().each(function(j){g[j]=c[j];});this.start(g);this.currentOrder=e;return this;},rearrangeDOM:function(a){a=a||this.currentOrder;var b=this.elements[0].getParent(); +var c=[];this.elements.setStyle("opacity",0);a.each(function(d){c.push(this.elements[d].inject(b).setStyles({top:0,left:0}));},this);this.elements.setStyle("opacity",1); +this.elements=$$(c);this.setDefaultOrder();return this;},getDefaultOrder:function(){return this.elements.map(function(b,a){return a;});},forward:function(){return this.sort(this.getDefaultOrder()); +},backward:function(){return this.sort(this.getDefaultOrder().reverse());},reverse:function(){return this.sort(this.currentOrder.reverse());},sortByElements:function(a){return this.sort(a.map(function(b){return this.elements.indexOf(b); +},this));},swap:function(c,b){if($type(c)=="element"){c=this.elements.indexOf(c);}if($type(b)=="element"){b=this.elements.indexOf(b);}var a=$A(this.currentOrder); +a[this.currentOrder.indexOf(c)]=b;a[this.currentOrder.indexOf(b)]=c;return this.sort(a);}});var Drag=new Class({Implements:[Events,Options],options:{snap:6,unit:"px",grid:false,style:true,limit:false,handle:false,invert:false,preventDefault:false,stopPropagation:false,modifiers:{x:"left",y:"top"}},initialize:function(){var b=Array.link(arguments,{options:Object.type,element:$defined}); +this.element=document.id(b.element);this.document=this.element.getDocument();this.setOptions(b.options||{});var a=$type(this.options.handle);this.handles=((a=="array"||a=="collection")?$$(this.options.handle):document.id(this.options.handle))||this.element; +this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.selection=(Browser.Engine.trident)?"selectstart":"mousedown";this.bound={start:this.start.bind(this),check:this.check.bind(this),drag:this.drag.bind(this),stop:this.stop.bind(this),cancel:this.cancel.bind(this),eventStop:$lambda(false)}; +this.attach();},attach:function(){this.handles.addEvent("mousedown",this.bound.start);return this;},detach:function(){this.handles.removeEvent("mousedown",this.bound.start); +return this;},start:function(c){if(c.rightClick){return;}if(this.options.preventDefault){c.preventDefault();}if(this.options.stopPropagation){c.stopPropagation(); +}this.mouse.start=c.page;this.fireEvent("beforeStart",this.element);var a=this.options.limit;this.limit={x:[],y:[]};for(var d in this.options.modifiers){if(!this.options.modifiers[d]){continue; +}if(this.options.style){this.value.now[d]=this.element.getStyle(this.options.modifiers[d]).toInt();}else{this.value.now[d]=this.element[this.options.modifiers[d]]; +}if(this.options.invert){this.value.now[d]*=-1;}this.mouse.pos[d]=c.page[d]-this.value.now[d];if(a&&a[d]){for(var b=2;b--;b){if($chk(a[d][b])){this.limit[d][b]=$lambda(a[d][b])(); +}}}}if($type(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid};}this.document.addEvents({mousemove:this.bound.check,mouseup:this.bound.cancel}); +this.document.addEvent(this.selection,this.bound.eventStop);},check:function(a){if(this.options.preventDefault){a.preventDefault();}var b=Math.round(Math.sqrt(Math.pow(a.page.x-this.mouse.start.x,2)+Math.pow(a.page.y-this.mouse.start.y,2))); +if(b>this.options.snap){this.cancel();this.document.addEvents({mousemove:this.bound.drag,mouseup:this.bound.stop});this.fireEvent("start",[this.element,a]).fireEvent("snap",this.element); +}},drag:function(a){if(this.options.preventDefault){a.preventDefault();}this.mouse.now=a.page;for(var b in this.options.modifiers){if(!this.options.modifiers[b]){continue; +}this.value.now[b]=this.mouse.now[b]-this.mouse.pos[b];if(this.options.invert){this.value.now[b]*=-1;}if(this.options.limit&&this.limit[b]){if($chk(this.limit[b][1])&&(this.value.now[b]>this.limit[b][1])){this.value.now[b]=this.limit[b][1]; +}else{if($chk(this.limit[b][0])&&(this.value.now[b]c.left&&a.xc.top);},checkDroppables:function(){var a=this.droppables.filter(this.checkAgainst,this).getLast(); +if(this.overed!=a){if(this.overed){this.fireEvent("leave",[this.element,this.overed]);}if(a){this.fireEvent("enter",[this.element,a]);}this.overed=a;}},drag:function(a){this.parent(a); +if(this.options.checkDroppables&&this.droppables.length){this.checkDroppables();}},stop:function(a){this.checkDroppables();this.fireEvent("drop",[this.element,this.overed,a]); +this.overed=null;return this.parent(a);}});Element.implement({makeDraggable:function(a){var b=new Drag.Move(this,a);this.store("dragger",b);return b;}}); +var Slider=new Class({Implements:[Events,Options],Binds:["clickedElement","draggedKnob","scrolledElement"],options:{onTick:function(a){if(this.options.snap){a=this.toPosition(this.step); +}this.knob.setStyle(this.property,a);},initialStep:0,snap:false,offset:0,range:false,wheel:false,steps:100,mode:"horizontal"},initialize:function(f,a,e){this.setOptions(e); +this.element=document.id(f);this.knob=document.id(a);this.previousChange=this.previousEnd=this.step=-1;var g,b={},d={x:false,y:false};switch(this.options.mode){case"vertical":this.axis="y"; +this.property="top";g="offsetHeight";break;case"horizontal":this.axis="x";this.property="left";g="offsetWidth";}this.full=this.element.measure(function(){this.half=this.knob[g]/2; +return this.element[g]-this.knob[g]+(this.options.offset*2);}.bind(this));this.min=$chk(this.options.range[0])?this.options.range[0]:0;this.max=$chk(this.options.range[1])?this.options.range[1]:this.options.steps; +this.range=this.max-this.min;this.steps=this.options.steps||this.full;this.stepSize=Math.abs(this.range)/this.steps;this.stepWidth=this.stepSize*this.full/Math.abs(this.range); +this.knob.setStyle("position","relative").setStyle(this.property,this.options.initialStep?this.toPosition(this.options.initialStep):-this.options.offset); +d[this.axis]=this.property;b[this.axis]=[-this.options.offset,this.full-this.options.offset];var c={snap:0,limit:b,modifiers:d,onDrag:this.draggedKnob,onStart:this.draggedKnob,onBeforeStart:(function(){this.isDragging=true; +}).bind(this),onCancel:function(){this.isDragging=false;}.bind(this),onComplete:function(){this.isDragging=false;this.draggedKnob();this.end();}.bind(this)}; +if(this.options.snap){c.grid=Math.ceil(this.stepWidth);c.limit[this.axis][1]=this.full;}this.drag=new Drag(this.knob,c);this.attach();},attach:function(){this.element.addEvent("mousedown",this.clickedElement); +if(this.options.wheel){this.element.addEvent("mousewheel",this.scrolledElement);}this.drag.attach();return this;},detach:function(){this.element.removeEvent("mousedown",this.clickedElement); +this.element.removeEvent("mousewheel",this.scrolledElement);this.drag.detach();return this;},set:function(a){if(!((this.range>0)^(a0)^(a>this.max))){a=this.max;}this.step=Math.round(a);this.checkStep();this.fireEvent("tick",this.toPosition(this.step));this.end();return this; +},clickedElement:function(c){if(this.isDragging||c.target==this.knob){return;}var b=this.range<0?-1:1;var a=c.page[this.axis]-this.element.getPosition()[this.axis]-this.half; +a=a.limit(-this.options.offset,this.full-this.options.offset);this.step=Math.round(this.min+b*this.toStep(a));this.checkStep();this.fireEvent("tick",a); +this.end();},scrolledElement:function(a){var b=(this.options.mode=="horizontal")?(a.wheel<0):(a.wheel>0);this.set(b?this.step-this.stepSize:this.step+this.stepSize); +a.stop();},draggedKnob:function(){var b=this.range<0?-1:1;var a=this.drag.value.now[this.axis];a=a.limit(-this.options.offset,this.full-this.options.offset); +this.step=Math.round(this.min+b*this.toStep(a));this.checkStep();},checkStep:function(){if(this.previousChange!=this.step){this.previousChange=this.step; +this.fireEvent("change",this.step);}},end:function(){if(this.previousEnd!==this.step){this.previousEnd=this.step;this.fireEvent("complete",this.step+""); +}},toStep:function(a){var b=(a+this.options.offset)*this.stepSize/this.full*this.steps;return this.options.steps?Math.round(b-=b%this.stepSize):b;},toPosition:function(a){return(this.full*Math.abs(this.min-a))/(this.steps*this.stepSize)-this.options.offset; +}});var Sortables=new Class({Implements:[Events,Options],options:{snap:4,opacity:1,clone:false,revert:false,handle:false,constrain:false},initialize:function(a,b){this.setOptions(b); +this.elements=[];this.lists=[];this.idle=true;this.addLists($$(document.id(a)||a));if(!this.options.clone){this.options.revert=false;}if(this.options.revert){this.effect=new Fx.Morph(null,$merge({duration:250,link:"cancel"},this.options.revert)); +}},attach:function(){this.addLists(this.lists);return this;},detach:function(){this.lists=this.removeLists(this.lists);return this;},addItems:function(){Array.flatten(arguments).each(function(a){this.elements.push(a); +var b=a.retrieve("sortables:start",this.start.bindWithEvent(this,a));(this.options.handle?a.getElement(this.options.handle)||a:a).addEvent("mousedown",b); +},this);return this;},addLists:function(){Array.flatten(arguments).each(function(a){this.lists.push(a);this.addItems(a.getChildren());},this);return this; +},removeItems:function(){return $$(Array.flatten(arguments).map(function(a){this.elements.erase(a);var b=a.retrieve("sortables:start");(this.options.handle?a.getElement(this.options.handle)||a:a).removeEvent("mousedown",b); +return a;},this));},removeLists:function(){return $$(Array.flatten(arguments).map(function(a){this.lists.erase(a);this.removeItems(a.getChildren());return a; +},this));},getClone:function(b,a){if(!this.options.clone){return new Element("div").inject(document.body);}if($type(this.options.clone)=="function"){return this.options.clone.call(this,b,a,this.list); +}var c=a.clone(true).setStyles({margin:"0px",position:"absolute",visibility:"hidden",width:a.getStyle("width")});if(c.get("html").test("radio")){c.getElements("input[type=radio]").each(function(d,e){d.set("name","clone_"+e); +});}return c.inject(this.list).setPosition(a.getPosition(a.getOffsetParent()));},getDroppables:function(){var a=this.list.getChildren();if(!this.options.constrain){a=this.lists.concat(a).erase(this.list); +}return a.erase(this.clone).erase(this.element);},insert:function(c,b){var a="inside";if(this.lists.contains(b)){this.list=b;this.drag.droppables=this.getDroppables(); +}else{a=this.element.getAllPrevious().contains(b)?"before":"after";}this.element.inject(b,a);this.fireEvent("sort",[this.element,this.clone]);},start:function(b,a){if(!this.idle){return; +}this.idle=false;this.element=a;this.opacity=a.get("opacity");this.list=a.getParent();this.clone=this.getClone(b,a);this.drag=new Drag.Move(this.clone,{snap:this.options.snap,container:this.options.constrain&&this.element.getParent(),droppables:this.getDroppables(),onSnap:function(){b.stop(); +this.clone.setStyle("visibility","visible");this.element.set("opacity",this.options.opacity||0);this.fireEvent("start",[this.element,this.clone]);}.bind(this),onEnter:this.insert.bind(this),onCancel:this.reset.bind(this),onComplete:this.end.bind(this)}); +this.clone.inject(this.element,"before");this.drag.start(b);},end:function(){this.drag.detach();this.element.set("opacity",this.opacity);if(this.effect){var a=this.element.getStyles("width","height"); +var b=this.clone.computePosition(this.element.getPosition(this.clone.offsetParent));this.effect.element=this.clone;this.effect.start({top:b.top,left:b.left,width:a.width,height:a.height,opacity:0.25}).chain(this.reset.bind(this)); +}else{this.reset();}},reset:function(){this.idle=true;this.clone.destroy();this.fireEvent("complete",this.element);},serialize:function(){var c=Array.link(arguments,{modifier:Function.type,index:$defined}); +var b=this.lists.map(function(d){return d.getChildren().map(c.modifier||function(e){return e.get("id");},this);},this);var a=c.index;if(this.lists.length==1){a=0; +}return $chk(a)&&a>=0&&a=3){c="rgb"; +b=Array.slice(arguments,0,3);}else{if(typeof b=="string"){if(b.match(/rgb/)){b=b.rgbToHex().hexToRgb(true);}else{if(b.match(/hsb/)){b=b.hsbToRgb();}else{b=b.hexToRgb(true); +}}}}c=c||"rgb";switch(c){case"hsb":var a=b;b=b.hsbToRgb();b.hsb=a;break;case"hex":b=b.hexToRgb(true);break;}b.rgb=b.slice(0,3);b.hsb=b.hsb||b.rgbToHsb(); +b.hex=b.rgbToHex();return $extend(b,this);}});Color.implement({mix:function(){var a=Array.slice(arguments);var c=($type(a.getLast())=="number")?a.pop():50; +var b=this.slice();a.each(function(d){d=new Color(d);for(var e=0;e<3;e++){b[e]=Math.round((b[e]/100*(100-c))+(d[e]/100*c));}});return new Color(b,"rgb"); +},invert:function(){return new Color(this.map(function(a){return 255-a;}));},setHue:function(a){return new Color([a,this.hsb[1],this.hsb[2]],"hsb");},setSaturation:function(a){return new Color([this.hsb[0],a,this.hsb[2]],"hsb"); +},setBrightness:function(a){return new Color([this.hsb[0],this.hsb[1],a],"hsb");}});var $RGB=function(d,c,a){return new Color([d,c,a],"rgb");};var $HSB=function(d,c,a){return new Color([d,c,a],"hsb"); +};var $HEX=function(a){return new Color(a,"hex");};Array.implement({rgbToHsb:function(){var b=this[0],c=this[1],j=this[2],g=0;var i=Math.max(b,c,j),e=Math.min(b,c,j); +var k=i-e;var h=i/255,f=(i!=0)?k/i:0;if(f!=0){var d=(i-b)/k;var a=(i-c)/k;var l=(i-j)/k;if(b==i){g=l-a;}else{if(c==i){g=2+d-l;}else{g=4+a-d;}}g/=6;if(g<0){g++; +}}return[Math.round(g*360),Math.round(f*100),Math.round(h*100)];},hsbToRgb:function(){var c=Math.round(this[2]/100*255);if(this[1]==0){return[c,c,c];}else{var a=this[0]%360; +var e=a%60;var g=Math.round((this[2]*(100-this[1]))/10000*255);var d=Math.round((this[2]*(6000-this[1]*e))/600000*255);var b=Math.round((this[2]*(6000-this[1]*(60-e)))/600000*255); +switch(Math.floor(a/60)){case 0:return[c,b,g];case 1:return[d,c,g];case 2:return[g,c,b];case 3:return[g,d,c];case 4:return[b,g,c];case 5:return[c,g,d]; +}}return false;}});String.implement({rgbToHsb:function(){var a=this.match(/\d{1,3}/g);return(a)?a.rgbToHsb():null;},hsbToRgb:function(){var a=this.match(/\d{1,3}/g); +return(a)?a.hsbToRgb():null;}});Hash.Cookie=new Class({Extends:Cookie,options:{autoSave:true},initialize:function(b,a){this.parent(b,a);this.load();},save:function(){var a=JSON.encode(this.hash); +if(!a||a.length>4096){return false;}if(a=="{}"){this.dispose();}else{this.write(a);}return true;},load:function(){this.hash=new Hash(JSON.decode(this.read(),true)); +return this;}});Hash.each(Hash.prototype,function(b,a){if(typeof b=="function"){Hash.Cookie.implement(a,function(){var c=b.apply(this.hash,arguments);if(this.options.autoSave){this.save(); +}return c;});}});var HtmlTable=new Class({Implements:[Options,Events,Class.Occlude],options:{properties:{cellpadding:0,cellspacing:0,border:0},rows:[],headers:[],footers:[]},property:"HtmlTable",initialize:function(){var a=Array.link(arguments,{options:Object.type,table:Element.type}); +this.setOptions(a.options);this.element=a.table||new Element("table",this.options.properties);if(this.occlude()){return this.occluded;}this.build();},build:function(){this.element.store("HtmlTable",this); +this.body=document.id(this.element.tBodies[0])||new Element("tbody").inject(this.element);$$(this.body.rows);if(this.options.headers.length){this.setHeaders(this.options.headers); +}else{this.thead=document.id(this.element.tHead);}if(this.thead){this.head=document.id(this.thead.rows[0]);}if(this.options.footers.length){this.setFooters(this.options.footers); +}this.tfoot=document.id(this.element.tFoot);if(this.tfoot){this.foot=document.id(this.thead.rows[0]);}this.options.rows.each(function(a){this.push(a);},this); +["adopt","inject","wraps","grab","replaces","dispose"].each(function(a){this[a]=this.element[a].bind(this.element);},this);},toElement:function(){return this.element; +},empty:function(){this.body.empty();return this;},set:function(d,a){var c=(d=="headers")?"tHead":"tFoot";this[c.toLowerCase()]=(document.id(this.element[c])||new Element(c.toLowerCase()).inject(this.element,"top")).empty(); +var b=this.push(a,{},this[c.toLowerCase()],d=="headers"?"th":"td");if(d=="headers"){this.head=document.id(this.thead.rows[0]);}else{this.foot=document.id(this.thead.rows[0]); +}return b;},setHeaders:function(a){this.set("headers",a);return this;},setFooters:function(a){this.set("footers",a);return this;},push:function(e,b,d,a){var c=e.map(function(h){var i=new Element(a||"td",h.properties),g=h.content||h||"",f=document.id(g); +if($type(g)!="string"&&f){i.adopt(f);}else{i.set("html",g);}return i;});return{tr:new Element("tr",b).inject(d||this.body).adopt(c),tds:c};}});HtmlTable=Class.refactor(HtmlTable,{options:{classZebra:"table-tr-odd",zebra:true},initialize:function(){this.previous.apply(this,arguments); +if(this.occluded){return this.occluded;}if(this.options.zebra){this.updateZebras();}},updateZebras:function(){Array.each(this.body.rows,this.zebra,this); +},zebra:function(b,a){return b[((a%2)?"remove":"add")+"Class"](this.options.classZebra);},push:function(){var a=this.previous.apply(this,arguments);if(this.options.zebra){this.updateZebras(); +}return a;}});HtmlTable=Class.refactor(HtmlTable,{options:{sortIndex:0,sortReverse:false,parsers:[],defaultParser:"string",classSortable:"table-sortable",classHeadSort:"table-th-sort",classHeadSortRev:"table-th-sort-rev",classNoSort:"table-th-nosort",classGroupHead:"table-tr-group-head",classGroup:"table-tr-group",classCellSort:"table-td-sort",classSortSpan:"table-th-sort-span",sortable:false},initialize:function(){this.previous.apply(this,arguments); +if(this.occluded){return this.occluded;}this.sorted={index:null,dir:1};this.bound={headClick:this.headClick.bind(this)};this.sortSpans=new Elements();if(this.options.sortable){this.enableSort(); +if(this.options.sortIndex!=null){this.sort(this.options.sortIndex,this.options.sortReverse);}}},attachSorts:function(a){this.element.removeEvents("click:relay(th)"); +this.element[$pick(a,true)?"addEvent":"removeEvent"]("click:relay(th)",this.bound.headClick);},setHeaders:function(){this.previous.apply(this,arguments); +if(this.sortEnabled){this.detectParsers();}},detectParsers:function(c){if(!this.head){return;}var a=this.options.parsers,b=this.body.rows;this.parsers=$$(this.head.cells).map(function(d,e){if(!c&&(d.hasClass(this.options.classNoSort)||d.retrieve("htmltable-parser"))){return d.retrieve("htmltable-parser"); +}var f=new Element("div");$each(d.childNodes,function(j){f.adopt(j);});f.inject(d);var h=new Element("span",{html:" ","class":this.options.classSortSpan}).inject(f,"top"); +this.sortSpans.push(h);var i=a[e],g;switch($type(i)){case"function":i={convert:i};g=true;break;case"string":i=i;g=true;break;}if(!g){HtmlTable.Parsers.some(function(n){var l=n.match; +if(!l){return false;}for(var m=0,k=b.length;mi.value?1:-1; +});if(!this.sorted.reverse){s.reverse(true);}var p=s.length,k=this.body;var n,r,a,g;while(p){var q=s[--p];r=q.position;var e=k.rows[r];if(e.disabled){continue; +}if(!m){if(g===q.value){e.removeClass(t).addClass(o);}else{g=q.value;e.removeClass(o).addClass(t);}if(this.zebra){this.zebra(e,p);}e.cells[f].addClass(l); +}k.appendChild(e);for(n=0;nr){s[n].position--;}}}s=null;if(b){b.grab(k);}return this.fireEvent("sort",[k,f]);},reSort:function(){if(this.sortEnabled){this.sort.call(this,this.sorted.index,this.sorted.reverse); +}return this;},enableSort:function(){this.element.addClass(this.options.classSortable);this.attachSorts(true);this.detectParsers();this.sortEnabled=true; +return this;},disableSort:function(){this.element.removeClass(this.options.classSortable);this.attachSorts(false);this.sortSpans.each(function(a){a.destroy(); +});this.sortSpans.empty();this.sortEnabled=false;return this;}});HtmlTable.Parsers=new Hash({date:{match:/^\d{2}[-\/ ]\d{2}[-\/ ]\d{2,4}$/,convert:function(){return Date.parse(this.get("text")).format("db"); +},type:"date"},"input-checked":{match:/ type="(radio|checkbox)" /,convert:function(){return this.getElement("input").checked;}},"input-value":{match:/=this.body.rows.length){b=this.body.rows.length-1;}if(this.hover==this.body.rows[b]){return this; +}this.enterRow(this.body.rows[b]);},leaveRow:function(a){a.removeClass(this.options.classRowHovered);},focusRow:function(){var b=arguments[1]||arguments[0]; +if(!this.body.getChildren().contains(b)){return;}var a=function(c){this.selectedRows.erase(c);c.removeClass(this.options.classRowSelected);this.fireEvent("rowUnfocus",[c,this.selectedRows]); +}.bind(this);if(!this.options.allowMultiSelect){this.selectedRows.each(a);}if(!this.selectedRows.contains(b)){this.selectedRows.push(b);b.addClass(this.options.classRowSelected); +this.fireEvent("rowFocus",[b,this.selectedRows]);}else{a(b);}return false;},selectAll:function(a){a=$pick(a,true);if(!this.options.allowMultiSelect&&a){return; +}if(!a){this.selectedRows.removeClass(this.options.classRowSelected).empty();}else{this.selectedRows.combine(this.body.rows).addClass(this.options.classRowSelected); +}return this;},selectNone:function(){return this.selectAll(false);}});(function(){var a=this.Keyboard=new Class({Extends:Events,Implements:[Options,Log],options:{defaultEventType:"keydown",active:false,events:{},nonParsedEvents:["activate","deactivate","onactivate","ondeactivate","changed","onchanged"]},initialize:function(f){this.setOptions(f); +this.setup();},setup:function(){this.addEvents(this.options.events);if(a.manager&&!this.manager){a.manager.manage(this);}if(this.options.active){this.activate(); +}},handle:function(h,g){if(h.preventKeyboardPropagation){return;}var f=!!this.manager;if(f&&this.activeKB){this.activeKB.handle(h,g);if(h.preventKeyboardPropagation){return; +}}this.fireEvent(g,h);if(!f&&this.activeKB){this.activeKB.handle(h,g);}},addEvent:function(h,g,f){return this.parent(a.parse(h,this.options.defaultEventType,this.options.nonParsedEvents),g,f); +},removeEvent:function(g,f){return this.parent(a.parse(g,this.options.defaultEventType,this.options.nonParsedEvents),f);},toggleActive:function(){return this[this.active?"deactivate":"activate"](); +},activate:function(f){if(f){if(f!=this.activeKB){this.previous=this.activeKB;}this.activeKB=f.fireEvent("activate");a.manager.fireEvent("changed");}else{if(this.manager){this.manager.activate(this); +}}return this;},deactivate:function(f){if(f){if(f===this.activeKB){this.activeKB=null;f.fireEvent("deactivate");a.manager.fireEvent("changed");}}else{if(this.manager){this.manager.deactivate(this); +}}return this;},relenquish:function(){if(this.previous){this.activate(this.previous);}},manage:function(f){if(f.manager){f.manager.drop(f);}this.instances.push(f); +f.manager=this;if(!this.activeKB){this.activate(f);}else{this._disable(f);}},_disable:function(f){if(this.activeKB==f){this.activeKB=null;}},drop:function(f){this._disable(f); +this.instances.erase(f);},instances:[],trace:function(){a.trace(this);},each:function(f){a.each(this,f);}});var b={};var c=["shift","control","alt","meta"]; +var e=/^(?:shift|control|ctrl|alt|meta)$/;a.parse=function(h,g,k){if(k&&k.contains(h.toLowerCase())){return h;}h=h.toLowerCase().replace(/^(keyup|keydown):/,function(m,l){g=l; +return"";});if(!b[h]){var f,j={};h.split("+").each(function(l){if(e.test(l)){j[l]=true;}else{f=l;}});j.control=j.control||j.ctrl;var i=[];c.each(function(l){if(j[l]){i.push(l); +}});if(f){i.push(f);}b[h]=i.join("+");}return g+":"+b[h];};a.each=function(f,g){var h=f||a.manager;while(h){g.run(h);h=h.activeKB;}};a.stop=function(f){f.preventKeyboardPropagation=true; +};a.manager=new a({active:true});a.trace=function(f){f=f||a.manager;f.enableLog();f.log("the following items have focus: ");a.each(f,function(g){f.log(document.id(g.widget)||g.wiget||g); +});};var d=function(g){var f=[];c.each(function(h){if(g[h]){f.push(h);}});if(!e.test(g.key)){f.push(g.key);}a.manager.handle(g,g.type+":"+f.join("+")); +};document.addEvents({keyup:d,keydown:d});Event.Keys.extend({shift:16,control:17,alt:18,capslock:20,pageup:33,pagedown:34,end:35,home:36,numlock:144,scrolllock:145,";":186,"=":187,",":188,"-":Browser.Engine.Gecko?109:189,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222}); +})();MooTools.lang.set("en-US","Date",{months:["January","February","March","April","May","June","July","August","September","October","November","December"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dateOrder:["month","date","year"],shortDate:"%m/%d/%Y",shortTime:"%I:%M%p",AM:"AM",PM:"PM",ordinal:function(a){return(a>3&&a<21)?"th":["th","st","nd","rd","th"][Math.min(a%10,4)]; +},lessThanMinuteAgo:"less than a minute ago",minuteAgo:"about a minute ago",minutesAgo:"{delta} minutes ago",hourAgo:"about an hour ago",hoursAgo:"about {delta} hours ago",dayAgo:"1 day ago",daysAgo:"{delta} days ago",weekAgo:"1 week ago",weeksAgo:"{delta} weeks ago",monthAgo:"1 month ago",monthsAgo:"{delta} months ago",yearAgo:"1 year ago",yearsAgo:"{delta} years ago",lessThanMinuteUntil:"less than a minute from now",minuteUntil:"about a minute from now",minutesUntil:"{delta} minutes from now",hourUntil:"about an hour from now",hoursUntil:"about {delta} hours from now",dayUntil:"1 day from now",daysUntil:"{delta} days from now",weekUntil:"1 week from now",weeksUntil:"{delta} weeks from now",monthUntil:"1 month from now",monthsUntil:"{delta} months from now",yearUntil:"1 year from now",yearsUntil:"{delta} years from now"}); diff --git a/src/webui/scripts/parametrics.js b/src/webui/scripts/parametrics.js new file mode 100644 index 000000000..3454202ef --- /dev/null +++ b/src/webui/scripts/parametrics.js @@ -0,0 +1,191 @@ +/* + +Script: Parametrics.js + Initializes the GUI property sliders. + +Copyright: + Copyright (c) 2007-2008 Greg Houston, . + +License: + MIT-style license. + +Requires: + Core.js, Window.js + +*/ + +MochaUI.extend({ + addUpLimitSlider: function(hash){ + if ($('uplimitSliderarea')) { + var windowOptions = MochaUI.Windows.windowOptions; + var sliderFirst = true; + // Get global upload limit + var maximum = 500; + var req = new Request({ + url: '/command/getGlobalUpLimit', + method: 'post', + data: {}, + onSuccess: function(data) { + if(data){ + var tmp = data.toInt(); + if(tmp > 0) { + maximum = tmp / 1024. + } else { + maximum = 0 + } + } + // Get torrent upload limit + // And create slider + if(hash == 'global') { + var up_limit = maximum; + if(up_limit < 0) up_limit = 0; + maximum = 1000; + var mochaSlide = new Slider($('uplimitSliderarea'), $('uplimitSliderknob'), { + steps: maximum, + offset: 0, + initialStep: up_limit.round(), + onChange: function(pos){ + if(pos > 0) { + $('uplimitUpdatevalue').set('html', pos); + $('upLimitUnit').set('html', "_(KiB/s)"); + } else { + $('uplimitUpdatevalue').set('html', '∞'); + $('upLimitUnit').set('html', ""); + } + }.bind(this) + }); + // Set default value + if(up_limit == 0) { + $('uplimitUpdatevalue').set('html', '∞'); + $('upLimitUnit').set('html', ""); + } else { + $('uplimitUpdatevalue').set('html', up_limit.round()); + $('upLimitUnit').set('html', "_(KiB/s)"); + } + } else { + var req = new Request({ + url: '/command/getTorrentUpLimit', + method: 'post', + data: {hash: hash}, + onSuccess: function(data) { + if(data){ + var up_limit = data.toInt(); + if(up_limit < 0) up_limit = 0; + var mochaSlide = new Slider($('uplimitSliderarea'), $('uplimitSliderknob'), { + steps: maximum, + offset: 0, + initialStep: (up_limit/1024.).round(), + onChange: function(pos){ + if(pos > 0) { + $('uplimitUpdatevalue').set('html', pos); + $('upLimitUnit').set('html', "_(KiB/s)"); + } else { + $('uplimitUpdatevalue').set('html', '∞'); + $('upLimitUnit').set('html', ""); + } + }.bind(this) + }); + // Set default value + if(up_limit == 0) { + $('uplimitUpdatevalue').set('html', '∞'); + $('upLimitUnit').set('html', ""); + } else { + $('uplimitUpdatevalue').set('html', (up_limit/1024.).round()); + $('upLimitUnit').set('html', "_(KiB/s)"); + } + } + } + }).send(); + } + } + }).send(); + } + }, + + addDlLimitSlider: function(hash){ + if ($('dllimitSliderarea')) { + var windowOptions = MochaUI.Windows.windowOptions; + var sliderFirst = true; + // Get global upload limit + var maximum = 500; + var req = new Request({ + url: '/command/getGlobalDlLimit', + method: 'post', + data: {}, + onSuccess: function(data) { + if(data){ + var tmp = data.toInt(); + if(tmp > 0) { + maximum = tmp / 1024. + } else { + maximum = 0 + } + } + // Get torrent download limit + // And create slider + if(hash == "global") { + var dl_limit = maximum; + if(dl_limit < 0) dl_limit = 0; + maximum = 10000; + var mochaSlide = new Slider($('dllimitSliderarea'), $('dllimitSliderknob'), { + steps: maximum, + offset: 0, + initialStep: dl_limit.round(), + onChange: function(pos){ + if(pos > 0) { + $('dllimitUpdatevalue').set('html', pos); + $('dlLimitUnit').set('html', "_(KiB/s)"); + } else { + $('dllimitUpdatevalue').set('html', '∞'); + $('dlLimitUnit').set('html', ""); + } + }.bind(this) + }); + // Set default value + if(dl_limit == 0) { + $('dllimitUpdatevalue').set('html', '∞'); + $('dlLimitUnit').set('html', ""); + } else { + $('dllimitUpdatevalue').set('html', dl_limit.round()); + $('dlLimitUnit').set('html', "_(KiB/s)"); + } + } else { + var req = new Request({ + url: '/command/getTorrentDlLimit', + method: 'post', + data: {hash: hash}, + onSuccess: function(data) { + if(data){ + var dl_limit = data.toInt(); + if(dl_limit < 0) dl_limit = 0; + var mochaSlide = new Slider($('dllimitSliderarea'), $('dllimitSliderknob'), { + steps: maximum, + offset: 0, + initialStep: (dl_limit/1024.).round(), + onChange: function(pos){ + if(pos > 0) { + $('dllimitUpdatevalue').set('html', pos); + $('dlLimitUnit').set('html', "_(KiB/s)"); + } else { + $('dllimitUpdatevalue').set('html', '∞'); + $('dlLimitUnit').set('html', ""); + } + }.bind(this) + }); + // Set default value + if(dl_limit == 0) { + $('dllimitUpdatevalue').set('html', '∞'); + $('dlLimitUnit').set('html', ""); + } else { + $('dllimitUpdatevalue').set('html', (dl_limit/1024.).round()); + $('dlLimitUnit').set('html', "_(KiB/s)"); + } + } + } + }).send(); + } + } + }).send(); + } + } +}); diff --git a/src/webui/scripts/progressbar.js b/src/webui/scripts/progressbar.js new file mode 100644 index 000000000..bd577879d --- /dev/null +++ b/src/webui/scripts/progressbar.js @@ -0,0 +1,96 @@ +var ProgressBar=new Class({ + initialize:function(value,parameters){ + var vals={ + 'id':'progressbar_'+(ProgressBars++), + 'value':$pick(value,0), + 'width':0, + 'height':0, + 'darkbg':'#006', + 'darkfg':'#fff', + 'lightbg':'#fff', + 'lightfg':'#000' + }; + if(parameters && $type(parameters)=='object')$extend(vals,parameters); + if(vals.height<12)vals.height=12; + var obj=new Element('div',{ + 'id':vals.id, + 'class':'progressbar_wrapper', + 'styles':{ + 'border':'1px solid #000', + 'width':vals.width, + 'height':vals.height, + 'position':'relative' + } + }); + obj.vals=vals; + obj.vals.value = $pick(value, 0); // Fix by Chris + obj.vals.dark=new Element('div',{ + 'id':vals.id+'_dark', + 'class':'progressbar_dark', + 'styles':{ + 'width':vals.width, + 'height':vals.height, + 'background':vals.darkbg, + 'color':vals.darkfg, + 'position':'absolute', + 'text-align':'center', + 'left':0, + 'top':0, + 'line-height':vals.height-2 + } + }); + obj.vals.light=new Element('div',{ + 'id':vals.id+'_light', + 'class':'progressbar_light', + 'styles':{ + 'width':vals.width, + 'height':vals.height, + 'background':vals.lightbg, + 'color':vals.lightfg, + 'position':'absolute', + 'text-align':'center', + 'left':0, + 'top':0, + 'line-height':vals.height-2 + } + }); + obj.appendChild(obj.vals.dark); + obj.appendChild(obj.vals.light); + obj.getValue=ProgressBar_getValue; + obj.setValue=ProgressBar_setValue; + if(vals.width)obj.setValue(vals.value); + else setTimeout('ProgressBar_checkForParent("'+obj.id+'")',1); + return obj; + } +}); + +function ProgressBar_getValue(){ + return this.vals.value; +} + +function ProgressBar_setValue(value){ + value=parseFloat(value); + if(isNaN(value))value=0; + if(value>100)value=100; + if(value<0)value=0; + this.vals.value=value; + this.vals.dark.empty(); + this.vals.light.empty(); + this.vals.dark.appendText(value+'%'); + this.vals.light.appendText(value+'%'); + var r=parseInt(this.vals.width*(value/100)); + this.vals.dark.setStyle('clip','rect(0,'+r+'px,'+this.vals.height+'px,0)'); + this.vals.light.setStyle('clip','rect(0,'+this.vals.width+'px,'+this.vals.height+'px,'+r+'px)'); +} +function ProgressBar_checkForParent(id){ + var obj=$(id); + if(!obj)return; + if(!obj.parentNode)return setTimeout('ProgressBar_checkForParent("'+id+'")',1); + obj.setStyle('width','100%'); + var w=obj.offsetWidth; + obj.vals.dark.setStyle('width',w); + obj.vals.light.setStyle('width',w); + obj.vals.width=w; + obj.setValue(obj.vals.value); +} +var ProgressBars=0; diff --git a/src/webui/webui.pri b/src/webui/webui.pri new file mode 100644 index 000000000..da7eea482 --- /dev/null +++ b/src/webui/webui.pri @@ -0,0 +1,16 @@ +INCLUDEPATH += $$PWD + +HEADERS += $$PWD/httpserver.h \ + $$PWD/httpconnection.h \ + $$PWD/httprequestparser.h \ + $$PWD/httpresponsegenerator.h \ + $$PWD/eventmanager.h \ + $$PWD/json.h + +SOURCES += $$PWD/httpserver.cpp \ + $$PWD/httpconnection.cpp \ + $$PWD/httprequestparser.cpp \ + $$PWD/httpresponsegenerator.cpp \ + $$PWD/eventmanager.cpp + +RESOURCES += $$PWD/webui.qrc \ No newline at end of file diff --git a/src/webui/webui.qrc b/src/webui/webui.qrc new file mode 100644 index 000000000..3aefdb824 --- /dev/null +++ b/src/webui/webui.qrc @@ -0,0 +1,38 @@ + + + html/index.html + html/download.html + html/addtrackers.html + html/upload.html + html/uploadframe.html + html/about.html + html/filters.html + html/transferlist.html + html/prop-general.html + html/prop-trackers.html + html/prop-files.html + html/properties.html + html/uploadlimit.html + html/downloadlimit.html + html/preferences.html + html/preferences_content.html + html/confirmdeletion.html + css/Core.css + css/Layout.css + css/Window.css + css/Tabs.css + css/dynamicTable.css + css/style.css + scripts/excanvas-compressed.js + scripts/mocha-yc.js + scripts/mocha-init.js + scripts/mootools-1.2-core-yc.js + scripts/mootools-1.2-more.js + scripts/dynamicTable.js + scripts/client.js + scripts/download.js + scripts/progressbar.js + scripts/contextmenu.js + scripts/parametrics.js + + diff --git a/unixconf.pri b/unixconf.pri new file mode 100644 index 000000000..a27c0620b --- /dev/null +++ b/unixconf.pri @@ -0,0 +1,83 @@ +# Generated by the configure file +include(conf.pri) + +# COMPILATION SPECIFIC +!nox:dbus { + QT += dbus +} + +QMAKE_CXXFLAGS += -Wformat -Wformat-security +QMAKE_LFLAGS_APP += -rdynamic +CONFIG += link_pkgconfig +PKGCONFIG += libtorrent-rasterbar +LIBS += -lssl -lcrypto + +# Man page +nox { + man.files = ../doc/qbittorrent-nox.1 +} else { + man.files = ../doc/qbittorrent.1 +} + +man.path = $$MANPREFIX/man/man1/ +INSTALLS += man + +# Menu Icon +!nox { + menuicon.files = Icons/qBittorrent.desktop + menuicon.path = $$PREFIX/share/applications/ + INSTALLS += menuicon + icon16.files = menuicons/16x16/apps/qbittorrent.png + icon16.path = $$PREFIX/share/icons/hicolor/16x16/apps/ + icon22.files = menuicons/22x22/apps/qbittorrent.png + icon22.path = $$PREFIX/share/icons/hicolor/22x22/apps/ + icon24.files = menuicons/24x24/apps/qbittorrent.png + icon24.path = $$PREFIX/share/icons/hicolor/24x24/apps/ + icon32.files = menuicons/32x32/apps/qbittorrent.png + icon32.path = $$PREFIX/share/icons/hicolor/32x32/apps/ + icon36.files = menuicons/36x36/apps/qbittorrent.png + icon36.path = $$PREFIX/share/icons/hicolor/36x36/apps/ + icon48.files = menuicons/48x48/apps/qbittorrent.png + icon48.path = $$PREFIX/share/icons/hicolor/48x48/apps/ + icon64.files = menuicons/64x64/apps/qbittorrent.png + icon64.path = $$PREFIX/share/icons/hicolor/64x64/apps/ + icon72.files = menuicons/72x72/apps/qbittorrent.png + icon72.path = $$PREFIX/share/icons/hicolor/72x72/apps/ + icon96.files = menuicons/96x96/apps/qbittorrent.png + icon96.path = $$PREFIX/share/icons/hicolor/96x96/apps/ + icon128.files = menuicons/128x128/apps/qbittorrent.png + icon128.path = $$PREFIX/share/icons/hicolor/128x128/apps/ + icon192.files = menuicons/192x192/apps/qbittorrent.png + icon192.path = $$PREFIX/share/icons/hicolor/192x192/apps/ + + INSTALLS += icon16 \ + icon22 \ + icon24 \ + icon32 \ + icon36 \ + icon48 \ + icon64 \ + icon72 \ + icon96 \ + icon128 \ + icon192 + + pixmap.files = menuicons/128x128/apps/qbittorrent.png + pixmap.path = $$PREFIX/share/pixmaps/ + INSTALLS += pixmap +} + +# INSTALL +target.path = $$PREFIX/bin/ +INSTALLS += target + +dbus { + include(src/qtnotify/qtnotify.pri) +} + +!nox { + # DEFINE added by configure + contains(DEFINES, WITH_GEOIP_EMBEDDED) { + message("You chose to embed GeoIP database in qBittorrent executable.") + } +} diff --git a/version.pri b/version.pri new file mode 100644 index 000000000..375976664 --- /dev/null +++ b/version.pri @@ -0,0 +1,11 @@ +os2 { + DEFINES += VERSION=\'\"v2.8.1\"\' +} else { + DEFINES += VERSION=\\\"v2.8.1\\\" +} +DEFINES += VERSION_MAJOR=2 +DEFINES += VERSION_MINOR=8 +DEFINES += VERSION_BUGFIX=0 + +# NORMAL,ALPHA,BETA,RELEASE_CANDIDATE,DEVEL +DEFINES += VERSION_TYPE=NORMAL diff --git a/winconf-mingw.pri b/winconf-mingw.pri new file mode 100644 index 000000000..8b160521a --- /dev/null +++ b/winconf-mingw.pri @@ -0,0 +1,22 @@ +RC_FILE = qbittorrent_mingw.rc + +#You need to link with libtorrent > 0.15.5 (or svn) and you must +#configure libtorrent to use iconv in the building process. This is +#needed for correct Unicode support. + +#Adapt the lib names/versions accordingly +CONFIG(debug, debug|release) { + LIBS += libtorrent \ + libboost_system-mgw45-mt-d-1_46_1 \ + libboost_filesystem-mgw45-mt-d-1_46_1 \ + libboost_thread-mgw45-mt-d-1_46_1 +} else { + LIBS += libtorrent \ + libboost_system-mgw45-mt-1_46_1 \ + libboost_filesystem-mgw45-mt-1_46_1 \ + libboost_thread-mgw45-mt-1_46_1 +} + +LIBS += libadvapi32 libshell32 +LIBS += libcrypto.dll libssl.dll libwsock32 libws2_32 libz libiconv.dll +LIBS += libpowrprof diff --git a/winconf-msvc.pri b/winconf-msvc.pri new file mode 100644 index 000000000..40c0be093 --- /dev/null +++ b/winconf-msvc.pri @@ -0,0 +1,21 @@ +RC_FILE = qbittorrent.rc + +# Enable Wide characters +DEFINES += TORRENT_USE_WPATH + +#Adapt the lib names/versions accordingly +CONFIG(debug, debug|release) { + LIBS += libtorrentd.lib \ + libboost_system-vc90-mt-gd.lib \ + libboost_filesystem-vc90-mt-gd.lib \ + libboost_thread-vc90-mt-gd.lib +} else { + LIBS += libtorrent.lib \ + libboost_system-vc90-mt.lib \ + libboost_filesystem-vc90-mt.lib \ + libboost_thread-vc90-mt.lib +} + +LIBS += advapi32.lib shell32.lib +LIBS += libeay32MD.lib ssleay32MD.lib +LIBS += PowrProf.lib diff --git a/winconf.pri b/winconf.pri new file mode 100644 index 000000000..dfbb87249 --- /dev/null +++ b/winconf.pri @@ -0,0 +1,54 @@ +# Adapt these paths on Windows + +#Point this to the boost include folder +INCLUDEPATH += $$quote(C:/qBittorrent/boost_1_46_0) +#Point this to the libtorrent include folser +INCLUDEPATH += $$quote(C:/qBittorrent/RC_0_15/include) +#Point this to the zlib include folder(libtorrent's if you used that) +INCLUDEPATH += $$quote(C:/qBittorrent/RC_0_15/zlib) +#Point this to the openssl include folder +INCLUDEPATH += $$quote(C:/OpenSSL/include) + +#Point this to the openssl lib folder +LIBS += $$quote(-LC:/OpenSSL/lib/VC) +#Point this to the libtorrent lib folder +LIBS += $$quote(-LC:/qBittorrent/RC_0_15/bin/) +#Point this to the boost lib folder +LIBS += $$quote(-LC:/qBittorrent/boost_1_46_0/stage/lib) + +# LIBTORRENT DEFINES +DEFINES += BOOST_ALL_NO_LIB +DEFINES += BOOST_ASIO_HASH_MAP_BUCKETS=1021 +DEFINES += BOOST_EXCEPTION_DISABLE +DEFINES += BOOST_SYSTEM_STATIC_LINK=1 +DEFINES += BOOST_THREAD_USE_LIB +DEFINES += BOOST_THREAD_USE_LIB=1 +DEFINES += TORRENT_USE_OPENSSL +DEFINES += UNICODE +DEFINES += WIN32 +DEFINES += WIN32_LEAN_AND_MEAN +DEFINES += _CRT_SECURE_NO_DEPRECATE +DEFINES += _FILE_OFFSET_BITS=64 +DEFINES += _SCL_SECURE_NO_DEPRECATE +DEFINES += _UNICODE +DEFINES += _WIN32 +DEFINES += _WIN32_WINNT=0x0500 +DEFINES += _WIN32_IE=0x0500 +DEFINES += __USE_W32_SOCKETS +DEFINES += WITH_SHIPPED_GEOIP_H + +CONFIG(debug, debug|release) { + DEFINES += TORRENT_DEBUG +} else { + DEFINES += NDEBUG +} + +win32-g++ { + include(winconf-mingw.pri) +} +else { + include(winconf-msvc.pri) +} + +DEFINES += WITH_GEOIP_EMBEDDED +message("On Windows, GeoIP database must be embedded.")

+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 literal 0 HcmV?d00001 diff --git a/src/menuicons/72x72/apps/qbittorrent.png b/src/menuicons/72x72/apps/qbittorrent.png new file mode 100644 index 0000000000000000000000000000000000000000..2b0c1f21f315c1a533cc8ea60c31e22e81d4be84 GIT binary patch literal 9397 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%0AT#313* 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 +#include +#include +#include +#include +#include + +#ifdef DISABLE_GUI +#include +#else +#include +#include +#endif + +#ifdef Q_WS_WIN +#include +#include +#include +const int UNLEN = 256; +#else +#include +#include +#endif + +#ifdef Q_WS_MAC +#include +#include +#endif + +#ifndef Q_WS_WIN +#if defined(Q_WS_MAC) || defined(Q_OS_FREEBSD) +#include +#include +#else +#include +#endif +#else +#include +#endif + +#ifndef DISABLE_GUI +#if defined(Q_WS_X11) && defined(QT_DBUS_LIB) +#include +#include +#endif +#endif // DISABLE_GUI + +using namespace libtorrent; + +const int MAX_FILENAME_LENGTH = 255; + +static struct { const char *source; const char *comment; } units[] = { + QT_TRANSLATE_NOOP3("misc", "B", "bytes"), + QT_TRANSLATE_NOOP3("misc", "KiB", "kibibytes (1024 bytes)"), + QT_TRANSLATE_NOOP3("misc", "MiB", "mebibytes (1024 kibibytes)"), + QT_TRANSLATE_NOOP3("misc", "GiB", "gibibytes (1024 mibibytes)"), + QT_TRANSLATE_NOOP3("misc", "TiB", "tebibytes (1024 gibibytes)") +}; + +QString misc::QDesktopServicesDataLocation() { +#ifdef Q_WS_WIN + LPWSTR path=new WCHAR[256]; + QString result; +#if defined Q_WS_WINCE + if (SHGetSpecialFolderPath(0, path, CSIDL_APPDATA, FALSE)) +#else + if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE)) +#endif + result = QString::fromWCharArray(path); + if (!QCoreApplication::applicationName().isEmpty()) + result = result + QLatin1String("\\") + qApp->applicationName(); + if(!result.endsWith("\\")) + result += "\\"; + return result; +#else +#ifdef Q_WS_MAC + // http://developer.apple.com/documentation/Carbon/Reference/Folder_Manager/Reference/reference.html + FSRef ref; + OSErr err = FSFindFolder(kUserDomain, kApplicationSupportFolderType, false, &ref); + if (err) + return QString(); + QString path; + QByteArray ba(2048, 0); + if (FSRefMakePath(&ref, reinterpret_cast(ba.data()), ba.size()) == noErr) + path = QString::fromUtf8(ba).normalized(QString::NormalizationForm_C); + path += QLatin1Char('/') + qApp->applicationName(); + return path; +#else + QString xdgDataHome = QLatin1String(qgetenv("XDG_DATA_HOME")); + if (xdgDataHome.isEmpty()) + xdgDataHome = QDir::homePath() + QLatin1String("/.local/share"); + xdgDataHome += QLatin1String("/data/") + + qApp->applicationName(); + return xdgDataHome; +#endif +#endif +} + +QString misc::QDesktopServicesCacheLocation() { +#ifdef Q_WS_WIN + return QDesktopServicesDataLocation() + QLatin1String("\\cache"); +#else +#ifdef Q_WS_MAC + // http://developer.apple.com/documentation/Carbon/Reference/Folder_Manager/Reference/reference.html + FSRef ref; + OSErr err = FSFindFolder(kUserDomain, kCachedDataFolderType, false, &ref); + if (err) + return QString(); + QString path; + QByteArray ba(2048, 0); + if (FSRefMakePath(&ref, reinterpret_cast(ba.data()), ba.size()) == noErr) + path = QString::fromUtf8(ba).normalized(QString::NormalizationForm_C); + path += QLatin1Char('/') + qApp->applicationName(); + return path; +#else + QString xdgCacheHome = QLatin1String(qgetenv("XDG_CACHE_HOME")); + if (xdgCacheHome.isEmpty()) + xdgCacheHome = QDir::homePath() + QLatin1String("/.cache"); + xdgCacheHome += QLatin1Char('/') + QCoreApplication::applicationName(); + return xdgCacheHome; +#endif +#endif +} + +long long misc::freeDiskSpaceOnPath(QString path) { + if(path.isEmpty()) return -1; + path = path.replace("\\", "/"); + QDir dir_path(path); + if(!dir_path.exists()) { + QStringList parts = path.split("/"); + while (parts.size() > 1 && !QDir(parts.join("/")).exists()) { + parts.removeLast(); + } + dir_path = QDir(parts.join("/")); + if(!dir_path.exists()) return -1; + } + Q_ASSERT(dir_path.exists()); +#ifndef Q_WS_WIN + unsigned long long available; + struct statfs stats; + const QString statfs_path = dir_path.path()+"/."; + const int ret = statfs (qPrintable(statfs_path), &stats) ; + if(ret == 0) { + available = ((unsigned long long)stats.f_bavail) * + ((unsigned long long)stats.f_bsize) ; + return available; + } else { + return -1; + } +#else + typedef BOOL (WINAPI *GetDiskFreeSpaceEx_t)(LPCTSTR, + PULARGE_INTEGER, + PULARGE_INTEGER, + PULARGE_INTEGER); + GetDiskFreeSpaceEx_t + pGetDiskFreeSpaceEx = (GetDiskFreeSpaceEx_t)::GetProcAddress + ( + ::GetModuleHandle(TEXT("kernel32.dll")), + "GetDiskFreeSpaceExW" + ); + if ( pGetDiskFreeSpaceEx ) + { + ULARGE_INTEGER bytesFree, bytesTotal; + unsigned long long *ret; + if (pGetDiskFreeSpaceEx((LPCTSTR)path.utf16(), &bytesFree, &bytesTotal, NULL)) { + ret = (unsigned long long*)&bytesFree; + return *ret; + } else { + return -1; + } + } else { + return -1; + } +#endif +} + +#ifndef DISABLE_GUI +void misc::shutdownComputer(bool sleep) { +#if defined(Q_WS_X11) && defined(QT_DBUS_LIB) + // Use dbus to power off / suspend the system + if(sleep) { + // Recent systems use UPower + QDBusInterface upowerIface("org.freedesktop.UPower", "/org/freedesktop/UPower", + "org.freedesktop.UPower", QDBusConnection::systemBus()); + if(upowerIface.isValid()) { + upowerIface.call("Suspend"); + return; + } + // HAL (older systems) + QDBusInterface halIface("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer", + "org.freedesktop.Hal.Device.SystemPowerManagement", + QDBusConnection::systemBus()); + halIface.call("Suspend", 5); + } else { + // Recent systems use ConsoleKit + QDBusInterface consolekitIface("org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", QDBusConnection::systemBus()); + if(consolekitIface.isValid()) { + consolekitIface.call("Stop"); + return; + } + // HAL (older systems) + QDBusInterface halIface("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer", + "org.freedesktop.Hal.Device.SystemPowerManagement", + QDBusConnection::systemBus()); + halIface.call("Shutdown"); + } +#endif +#ifdef Q_WS_MAC + AEEventID EventToSend; + if(sleep) + EventToSend = kAESleep; + else + EventToSend = kAEShutDown; + AEAddressDesc targetDesc; + static const ProcessSerialNumber kPSNOfSystemProcess = { 0, kSystemProcess }; + AppleEvent eventReply = {typeNull, NULL}; + AppleEvent appleEventToSend = {typeNull, NULL}; + + OSStatus error = noErr; + + error = AECreateDesc(typeProcessSerialNumber, &kPSNOfSystemProcess, + sizeof(kPSNOfSystemProcess), &targetDesc); + + if (error != noErr) + { + return; + } + + error = AECreateAppleEvent(kCoreEventClass, EventToSend, &targetDesc, + kAutoGenerateReturnID, kAnyTransactionID, &appleEventToSend); + + AEDisposeDesc(&targetDesc); + if (error != noErr) + { + return; + } + + error = AESend(&appleEventToSend, &eventReply, kAENoReply, + kAENormalPriority, kAEDefaultTimeout, NULL, NULL); + + AEDisposeDesc(&appleEventToSend); + if (error != noErr) + { + return; + } + + AEDisposeDesc(&eventReply); +#endif +#ifdef Q_WS_WIN + HANDLE hToken; // handle to process token + TOKEN_PRIVILEGES tkp; // pointer to token structure + if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) + return; + // Get the LUID for shutdown privilege. + LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, + &tkp.Privileges[0].Luid); + + tkp.PrivilegeCount = 1; // one privilege to set + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + // Get shutdown privilege for this process. + + AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, + (PTOKEN_PRIVILEGES) NULL, 0); + + // Cannot test the return value of AdjustTokenPrivileges. + + if (GetLastError() != ERROR_SUCCESS) + return; + bool ret; + if(sleep) + SetSuspendState(false, false, false); + else + InitiateSystemShutdownA(0, tr("qBittorrent will shutdown the computer now because all downloads are complete.").toLocal8Bit().data(), 10, true, false); + + // Disable shutdown privilege. + tkp.Privileges[0].Attributes = 0; + AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, + (PTOKEN_PRIVILEGES) NULL, 0); +#endif +} +#endif // DISABLE_GUI + +QString misc::fixFileNames(QString path) { + //qDebug() << Q_FUNC_INFO << path; + path.replace("\\", "/"); + QStringList parts = path.split("/", QString::SkipEmptyParts); + if(parts.isEmpty()) return path; + QString last_part = parts.takeLast(); + QList::iterator it; + for(it = parts.begin(); it != parts.end(); it++) { + QByteArray raw_filename = it->toLocal8Bit(); + // Make sure the filename is not too long + if(raw_filename.size() > MAX_FILENAME_LENGTH) { + qDebug() << "Folder" << *it << "was cut because it was too long"; + raw_filename.resize(MAX_FILENAME_LENGTH); + *it = QString::fromLocal8Bit(raw_filename.constData()); + qDebug() << "New folder name is" << *it; + Q_ASSERT(it->length() == MAX_FILENAME_LENGTH); + } + } + // Fix the last part (file name) + QByteArray raw_lastPart = last_part.toLocal8Bit(); + qDebug() << "Last part length:" << raw_lastPart.length(); + if(raw_lastPart.length() > MAX_FILENAME_LENGTH) { + qDebug() << "Filename" << last_part << "was cut because it was too long"; + // Shorten the name, keep the file extension + int point_index = raw_lastPart.lastIndexOf("."); + QByteArray extension = ""; + if(point_index >= 0) { + extension = raw_lastPart.mid(point_index); + raw_lastPart = raw_lastPart.left(point_index); + } + raw_lastPart = raw_lastPart.left(MAX_FILENAME_LENGTH-extension.length()) + extension; + Q_ASSERT(raw_lastPart.length() == MAX_FILENAME_LENGTH); + last_part = QString::fromLocal8Bit(raw_lastPart.constData()); + qDebug() << "New file name is" << last_part; + } + parts << last_part; + return parts.join("/"); +} + +QString misc::truncateRootFolder(boost::intrusive_ptr t) { + if(t->num_files() == 1) { + // Single file torrent +#if LIBTORRENT_VERSION_MINOR > 15 + QString path = QString::fromUtf8(t->file_at(0).path.c_str()); +#else + QString path = QString::fromUtf8(t->file_at(0).path.string().c_str()); +#endif + // Remove possible subfolders + path = fixFileNames(fileName(path)); + t->rename_file(0, path.toUtf8().data()); + return QString(); + } + QString root_folder; + for(int i=0; inum_files(); ++i) { +#if LIBTORRENT_VERSION_MINOR > 15 + QString path = QString::fromUtf8(t->file_at(i).path.c_str()); +#else + QString path = QString::fromUtf8(t->file_at(i).path.string().c_str()); +#endif + QStringList path_parts = path.split("/", QString::SkipEmptyParts); + if(path_parts.size() > 1) { + root_folder = path_parts.takeFirst(); + } + path = fixFileNames(path_parts.join("/")); + t->rename_file(i, path.toUtf8().data()); + } + return root_folder; +} + +QString misc::truncateRootFolder(libtorrent::torrent_handle h) { + torrent_info t = h.get_torrent_info(); + if(t.num_files() == 1) { + // Single file torrent + // Remove possible subfolders +#if LIBTORRENT_VERSION_MINOR > 15 + QString path = QString::fromUtf8(t.file_at(0).path.c_str()); +#else + QString path = QString::fromUtf8(t.file_at(0).path.string().c_str()); +#endif + path = fixFileNames(fileName(path)); + t.rename_file(0, path.toUtf8().data()); + return QString(); + } + QString root_folder; + for(int i=0; i 15 + QString path = QString::fromUtf8(t.file_at(i).path.c_str()); +#else + QString path = QString::fromUtf8(t.file_at(i).path.string().c_str()); +#endif + QStringList path_parts = path.split("/", QString::SkipEmptyParts); + if(path_parts.size() > 1) { + root_folder = path_parts.takeFirst(); + } + path = fixFileNames(path_parts.join("/")); + h.rename_file(i, path.toUtf8().data()); + } + return root_folder; +} + +bool misc::sameFiles(const QString &path1, const QString &path2) { + QFile f1(path1), f2(path2); + if(!f1.exists() || !f2.exists()) return false; + if(f1.size() != f2.size()) return false; + if(!f1.open(QIODevice::ReadOnly)) return false; + if(!f2.open(QIODevice::ReadOnly)) { + f1.close(); + return false; + } + bool same = true; + while(!f1.atEnd() && !f2.atEnd()) { + if(f1.read(5) != f2.read(5)) { + same = false; + break; + } + } + f1.close(); f2.close(); + return same; +} + +void misc::copyDir(QString src_path, QString dst_path) { + QDir sourceDir(src_path); + if(!sourceDir.exists()) return; + // Create destination directory + QDir destDir(dst_path); + if(!destDir.exists()) { + if(!destDir.mkpath(destDir.absolutePath())) return; + } + // List source directory + const QFileInfoList content = sourceDir.entryInfoList(); + foreach(const QFileInfo& child, content) { + if(child.fileName()[0] == '.') continue; + if(child.isDir()) { + copyDir(child.absoluteFilePath(), dst_path+QDir::separator()+QDir(child.absoluteFilePath()).dirName()); + continue; + } + const QString src_child_path = child.absoluteFilePath(); + const QString dest_child_path = destDir.absoluteFilePath(child.fileName()); + // Copy the file from src to dest + QFile::copy(src_child_path, dest_child_path); + // Remove source file + safeRemove(src_child_path); + } + // Remove source folder + const QString dir_name = sourceDir.dirName(); + if(sourceDir.cdUp()) { + sourceDir.rmdir(dir_name); + } +} + +void misc::chmod644(const QDir& folder) { + qDebug("chmod644(%s)", qPrintable(folder.absolutePath())); + if(!folder.exists()) return; + foreach(const QFileInfo &fi, folder.entryInfoList(QDir::Dirs|QDir::Files|QDir::NoSymLinks)) { + if(fi.fileName().startsWith(".")) continue; + if(fi.isDir()) { + misc::chmod644(QDir(fi.absoluteFilePath())); + } else { + QFile f(fi.absoluteFilePath()); + f.setPermissions(f.permissions()|QFile::ReadUser|QFile::WriteUser|QFile::ReadGroup|QFile::ReadOther); + } + } +} + +QString misc::updateLabelInSavePath(QString defaultSavePath, QString save_path, const QString &old_label, const QString &new_label) { + if(old_label == new_label) return save_path; +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + defaultSavePath.replace("\\", "/"); + save_path.replace("\\", "/"); +#endif + qDebug("UpdateLabelInSavePath(%s, %s, %s)", qPrintable(save_path), qPrintable(old_label), qPrintable(new_label)); + if(!save_path.startsWith(defaultSavePath)) return save_path; + QString new_save_path = save_path; + new_save_path.replace(defaultSavePath, ""); + QStringList path_parts = new_save_path.split("/", QString::SkipEmptyParts); + if(path_parts.empty()) { + if(!new_label.isEmpty()) + path_parts << new_label; + } else { + if(old_label.isEmpty() || path_parts.first() != old_label) { + if(path_parts.first() != new_label) + path_parts.prepend(new_label); + } else { + if(new_label.isEmpty()) { + path_parts.removeAt(0); + } else { + if(path_parts.first() != new_label) + path_parts.replace(0, new_label); + } + } + } + new_save_path = defaultSavePath; + if(!new_save_path.endsWith(QDir::separator())) new_save_path += QDir::separator(); + new_save_path += path_parts.join(QDir::separator()); + qDebug("New save path is %s", qPrintable(new_save_path)); + return new_save_path; +} + +QString misc::toValidFileSystemName(QString filename) { + qDebug("toValidFSName: %s", qPrintable(filename)); + filename = filename.replace("\\", "/").trimmed(); + const QRegExp regex("[/:?\"*<>|]"); + filename = filename.replace(regex, " ").trimmed(); + qDebug("toValidFSName, result: %s", qPrintable(filename)); + return filename; +} + +bool misc::isValidFileSystemName(QString filename) { + filename = filename.replace("\\", "/").trimmed(); + if(filename.isEmpty()) return false; + const QRegExp regex("[/:?\"*<>|]"); + if(filename.contains(regex)) + return false; + return true; +} + +#ifndef DISABLE_GUI +// Get screen center +QPoint misc::screenCenter(QWidget *win) { + int scrn = 0; + const QWidget *w = win->window(); + + if(w) + scrn = QApplication::desktop()->screenNumber(w); + else if(QApplication::desktop()->isVirtualDesktop()) + scrn = QApplication::desktop()->screenNumber(QCursor::pos()); + else + scrn = QApplication::desktop()->screenNumber(win); + + QRect desk(QApplication::desktop()->availableGeometry(scrn)); + return QPoint((desk.width() - win->frameGeometry().width()) / 2, (desk.height() - win->frameGeometry().height()) / 2); +} +#endif + +QString misc::searchEngineLocation() { + const QString location = QDir::cleanPath(QDesktopServicesDataLocation() + + QDir::separator() + "nova"); + QDir locationDir(location); + if(!locationDir.exists()) + locationDir.mkpath(locationDir.absolutePath()); + return location; +} + +QString misc::BTBackupLocation() { + const QString location = QDir::cleanPath(QDesktopServicesDataLocation() + + QDir::separator() + "BT_backup"); + QDir locationDir(location); + if(!locationDir.exists()) + locationDir.mkpath(locationDir.absolutePath()); + return location; +} + +QString misc::cacheLocation() { + QString location = QDir::cleanPath(QDesktopServicesCacheLocation()); + QDir locationDir(location); + if(!locationDir.exists()) + locationDir.mkpath(locationDir.absolutePath()); + return location; +} + +// return best userfriendly storage unit (B, KiB, MiB, GiB, TiB) +// use Binary prefix standards from IEC 60027-2 +// see http://en.wikipedia.org/wiki/Kilobyte +// value must be given in bytes +QString misc::friendlyUnit(qreal val) { + if(val < 0) + return tr("Unknown", "Unknown (size)"); + int i = 0; + while(val >= 1024. && i++<6) + val /= 1024.; + if(i == 0) + return QString::number((long)val) + " " + tr(units[0].source, units[0].comment); + return QString::number(val, 'f', 1) + " " + tr(units[i].source, units[i].comment); +} + +bool misc::isPreviewable(QString extension){ + if(extension.isEmpty()) return false; + extension = extension.toUpper(); + if(extension == "AVI") return true; + if(extension == "MP3") return true; + if(extension == "OGG") return true; + if(extension == "OGV") return true; + if(extension == "OGM") return true; + if(extension == "WMV") return true; + if(extension == "WMA") return true; + if(extension == "MPEG") return true; + if(extension == "MPG") return true; + if(extension == "ASF") return true; + if(extension == "QT") return true; + if(extension == "RM") return true; + if(extension == "RMVB") return true; + if(extension == "RMV") return true; + if(extension == "SWF") return true; + if(extension == "FLV") return true; + if(extension == "WAV") return true; + if(extension == "MOV") return true; + if(extension == "VOB") return true; + if(extension == "MID") return true; + if(extension == "AC3") return true; + if(extension == "MP4") return true; + if(extension == "MP2") return true; + if(extension == "AVI") return true; + if(extension == "FLAC") return true; + if(extension == "AU") return true; + if(extension == "MPE") return true; + if(extension == "MOV") return true; + if(extension == "MKV") return true; + if(extension == "AIF") return true; + if(extension == "AIFF") return true; + if(extension == "AIFC") return true; + if(extension == "RA") return true; + if(extension == "RAM") return true; + if(extension == "M4P") return true; + if(extension == "M4A") return true; + if(extension == "3GP") return true; + if(extension == "AAC") return true; + if(extension == "SWA") return true; + if(extension == "MPC") return true; + if(extension == "MPP") return true; + if(extension == "M3U") return true; + return false; +} + +QString misc::bcLinkToMagnet(QString bc_link) { + QByteArray raw_bc = bc_link.toUtf8(); + raw_bc = raw_bc.mid(8); // skip bc://bt/ + raw_bc = QByteArray::fromBase64(raw_bc); // Decode base64 + // Format is now AA/url_encoded_filename/size_bytes/info_hash/ZZ + QStringList parts = QString(raw_bc).split("/"); + if(parts.size() != 5) return QString::null; + QString filename = parts.at(1); + QString hash = parts.at(3); + QString magnet = "magnet:?xt=urn:btih:" + hash; + magnet += "&dn=" + filename; + return magnet; +} + +QString misc::magnetUriToName(QString magnet_uri) { + QString name = ""; + QRegExp regHex("dn=([^&]+)"); + const int pos = regHex.indexIn(magnet_uri); + if(pos > -1) { + const QString found = regHex.cap(1); + // URL decode + name = QUrl::fromPercentEncoding(found.toLocal8Bit()).replace("+", " "); + } + return name; +} + +QString misc::magnetUriToHash(QString magnet_uri) { + QString hash = ""; + QRegExp regHex("urn:btih:([0-9A-Za-z]+)"); + // Hex + int pos = regHex.indexIn(magnet_uri); + if(pos > -1) { + const QString found = regHex.cap(1); + qDebug() << Q_FUNC_INFO << "regex found: " << found; + if(found.length() == 40) { + const sha1_hash sha1(QByteArray::fromHex(found.toAscii()).constData()); + qDebug("magnetUriToHash (Hex): hash: %s", qPrintable(misc::toQString(sha1))); + return misc::toQString(sha1); + } + } + // Base 32 + QRegExp regBase32("urn:btih:([A-Za-z2-7=]+)"); + pos = regBase32.indexIn(magnet_uri); + if(pos > -1) { + const QString found = regBase32.cap(1); + if(found.length() > 20 && (found.length()*5)%40 == 0) { + const sha1_hash sha1(base32decode(regBase32.cap(1).toStdString())); + hash = misc::toQString(sha1); + } + } + qDebug("magnetUriToHash (base32): hash: %s", qPrintable(hash)); + return hash; +} + +QString misc::boostTimeToQString(const boost::optional &boostDate) { + if(!boostDate || !boostDate.is_initialized() || boostDate->is_not_a_date_time()) return tr("Unknown"); + struct std::tm tm; + try { + tm = boost::posix_time::to_tm(*boostDate); + } catch(std::exception e) { + return tr("Unknown"); + } + const time_t t = mktime(&tm); + if(t < 0) + return tr("Unknown"); + const QDateTime dt = QDateTime::fromTime_t(t); + if(dt.isNull() || !dt.isValid()) + return tr("Unknown"); + return dt.toString(Qt::DefaultLocaleLongDate); +} + +QString misc::time_tToQString(const boost::optional &t) { + if(!t.is_initialized() || *t < 0) return tr("Unknown"); + QDateTime dt = QDateTime::fromTime_t(*t); + if(dt.isNull() || !dt.isValid()) + return tr("Unknown"); + return dt.toString(Qt::DefaultLocaleLongDate); +} + +// Replace ~ in path +QString misc::expandPath(QString path) { + path = path.trimmed(); + if(path.isEmpty()) return path; + if(path.length() == 1) { + if(path[0] == '~' ) return QDir::homePath(); + } + if(path[0] == '~' && path[1] == QDir::separator()) { + path = path.replace(0, 1, QDir::homePath()); + } else { + if(QDir::isAbsolutePath(path)) { + path = QDir(path).absolutePath(); + } + } + return QDir::cleanPath(path); +} + +// Take a number of seconds and return an user-friendly +// time duration like "1d 2h 10m". +QString misc::userFriendlyDuration(qlonglong seconds) { + if(seconds < 0 || seconds >= MAX_ETA) { + return QString::fromUtf8("∞"); + } + if(seconds == 0) { + return "0"; + } + if(seconds < 60) { + return tr("< 1m", "< 1 minute"); + } + int minutes = seconds / 60; + if(minutes < 60) { + return tr("%1m","e.g: 10minutes").arg(QString::number(minutes)); + } + int hours = minutes / 60; + minutes = minutes - hours*60; + if(hours < 24) { + return tr("%1h %2m", "e.g: 3hours 5minutes").arg(QString::number(hours)).arg(QString::number(minutes)); + } + int days = hours / 24; + hours = hours - days * 24; + if(days < 100) { + return tr("%1d %2h", "e.g: 2days 10hours").arg(QString::number(days)).arg(QString::number(hours)); + } + return QString::fromUtf8("∞"); +} + +QString misc::getUserIDString() { + QString uid = "0"; +#ifdef Q_WS_WIN + char buffer[UNLEN+1] = {0}; + DWORD buffer_len = UNLEN + 1; + if (!GetUserNameA(buffer, &buffer_len)) + uid = QString(buffer); +#else + uid = QString::number(getuid()); +#endif + return uid; +} + +QStringList misc::toStringList(const QList &l) { + QStringList ret; + foreach(const bool &b, l) { + ret << (b ? "1" : "0"); + } + return ret; +} + +QList misc::intListfromStringList(const QStringList &l) { + QList ret; + foreach(const QString &s, l) { + ret << s.toInt(); + } + return ret; +} + +QList misc::boolListfromStringList(const QStringList &l) { + QList ret; + foreach(const QString &s, l) { + ret << (s=="1"); + } + return ret; +} + +quint64 misc::computePathSize(QString path) +{ + // Check if it is a file + QFileInfo fi(path); + if(!fi.exists()) return 0; + if(fi.isFile()) return fi.size(); + // Compute folder size + quint64 size = 0; + foreach(const QFileInfo &subfi, QDir(path).entryInfoList(QDir::Dirs|QDir::Files)) { + if(subfi.fileName().startsWith(".")) continue; + if(subfi.isDir()) + size += misc::computePathSize(subfi.absoluteFilePath()); + else + size += subfi.size(); + } + return size; +} + +bool misc::isValidTorrentFile(const QString &torrent_path) { + try { + boost::intrusive_ptr t = new torrent_info(torrent_path.toUtf8().constData()); + if(!t->is_valid() || t->num_files() == 0) + throw std::exception(); + } catch(std::exception&) { + return false; + } + return true; +} + +QString misc::branchPath(QString file_path, bool uses_slashes) +{ + if(!uses_slashes) + file_path.replace("\\", "/"); + Q_ASSERT(!file_path.contains("\\")); + if(file_path.endsWith("/")) + file_path.chop(1); // Remove trailing slash + qDebug() << Q_FUNC_INFO << "before:" << file_path; + if(file_path.contains("/")) + return file_path.left(file_path.lastIndexOf('/')); + return ""; +} + +bool misc::isUrl(const QString &s) +{ + const QString scheme = QUrl(s).scheme(); + QRegExp is_url("http[s]?|ftp", Qt::CaseInsensitive); + return is_url.exactMatch(scheme); +} + +QString misc::fileName(QString file_path) +{ + file_path.replace("\\", "/"); + const int slash_index = file_path.lastIndexOf('/'); + if(slash_index == -1) + return file_path; + return file_path.mid(slash_index+1); +} + +bool misc::removeEmptyFolder(const QString &dirpath) +{ + QDir savedir(dirpath); + const QString dirname = savedir.dirName(); + if(savedir.exists() && savedir.cdUp()) { + return savedir.rmdir(dirname); + } + return false; +} + +QString misc::parseHtmlLinks(const QString &raw_text) +{ + QString result = raw_text; + QRegExp reURL("(\\s|^)" //start with whitespace or beginning of line + "(" + "(" //case 1 -- URL with scheme + "(http(s?))\\://" //start with scheme + "([a-zA-Z0-9_-]+\\.)+" // domainpart. at least one of these must exist + "([a-zA-Z0-9\\?%=&/_\\.:#;-]+)" // everything to 1st non-URI char, must be at least one char after the previous dot (cannot use ".*" because it can be too greedy) + ")" + "|" + "(" //case 2a -- no scheme, contains common TLD example.com + "([a-zA-Z0-9_-]+\\.)+" // domainpart. at least one of these must exist + "(?=" // must be followed by TLD + "AERO|aero|" //N.B. assertions are non-capturing + "ARPA|arpa|" + "ASIA|asia|" + "BIZ|biz|" + "CAT|cat|" + "COM|com|" + "COOP|coop|" + "EDU|edu|" + "GOV|gov|" + "INFO|info|" + "INT|int|" + "JOBS|jobs|" + "MIL|mil|" + "MOBI|mobi|" + "MUSEUM|museum|" + "NAME|name|" + "NET|net|" + "ORG|org|" + "PRO|pro|" + "RO|ro|" + "RU|ru|" + "TEL|tel|" + "TRAVEL|travel" + ")" + "([a-zA-Z0-9\\?%=&/_\\.:#;-]+)" // everything to 1st non-URI char, must be at least one char after the previous dot (cannot use ".*" because it can be too greedy) + ")" + "|" + "(" // case 2b no scheme, no TLD, must have at least 2 aphanum strings plus uncommon TLD string --> del.icio.us + "([a-zA-Z0-9_-]+\\.){2,}" //2 or more domainpart. --> del.icio. + "[a-zA-Z]{2,}" //one ab (2 char or longer) --> us + "([a-zA-Z0-9\\?%=&/_\\.:#;-]*)" // everything to 1st non-URI char, maybe nothing in case of del.icio.us/path + ")" + ")" + ); + + + // Capture links + result.replace(reURL, "\\1\\2"); + + // Capture links without scheme + QRegExp reNoScheme(""); + result.replace(reNoScheme, ""); + + return result; +} diff --git a/src/misc.h b/src/misc.h new file mode 100644 index 000000000..df4f30190 --- /dev/null +++ b/src/misc.h @@ -0,0 +1,195 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef MISC_H +#define MISC_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef DISABLE_GUI +#include +#endif + +const qlonglong MAX_ETA = 8640000; + +/* Miscellaneaous functions that can be useful */ +class misc : public QObject{ + Q_OBJECT + +private: + misc(); // Forbidden + +public: + static inline QString toQString(const std::string &str) { + return QString::fromLocal8Bit(str.c_str()); + } + + static inline QString toQString(const char* str) { + return QString::fromLocal8Bit(str); + } + + static inline QString toQStringU(const std::string &str) { + return QString::fromUtf8(str.c_str()); + } + + static inline QString toQStringU(const char* str) { + return QString::fromUtf8(str); + } + + static inline QString toQString(const libtorrent::sha1_hash &hash) { + std::ostringstream o; + o << hash; + return QString(o.str().c_str()); + } + + static inline libtorrent::sha1_hash toSha1Hash(const QString &hash) { + return libtorrent::sha1_hash(hash.toAscii().constData()); + } + + static void chmod644(const QDir& folder); + + static inline QString removeLastPathPart(QString path) { + if(path.isEmpty()) return path; + path = path.replace("\\", "/"); + QStringList tmp = path.split("/"); + tmp.removeLast(); + return tmp.join("/"); + } + + static inline libtorrent::sha1_hash QStringToSha1(const QString& s) { + std::string str(s.toLocal8Bit().data()); + std::istringstream i(str); + libtorrent::sha1_hash x; + i>>x; + return x; + } + + static inline QString file_extension(const QString &filename) { + QString extension; + int point_index = filename.lastIndexOf("."); + if(point_index >= 0) { + extension = filename.mid(point_index+1); + } + return extension; + } + +#ifndef DISABLE_GUI + static void shutdownComputer(bool sleep=false); +#endif + + static bool safeRemove(QString file_path) { + QFile MyFile(file_path); + if(!MyFile.exists()) return true; + // Make sure the permissions are ok + MyFile.setPermissions(MyFile.permissions()|QFile::ReadOwner|QFile::WriteOwner|QFile::ReadUser|QFile::WriteUser); + // Actually remove the file + return MyFile.remove(); + } + + static QString parseHtmlLinks(const QString &raw_text); + + static bool removeEmptyFolder(const QString &dirpath); + + static quint64 computePathSize(QString path); + + static QString truncateRootFolder(boost::intrusive_ptr t); + static QString truncateRootFolder(libtorrent::torrent_handle h); + static QString fixFileNames(QString path); + + static QString updateLabelInSavePath(QString defaultSavePath, QString save_path, const QString &old_label, const QString &new_label); + + static bool sameFiles(const QString &path1, const QString &path2); + static bool isUrl(const QString &s); + static void copyDir(QString src_path, QString dst_path); + static QString toValidFileSystemName(QString filename); + static bool isValidFileSystemName(QString filename); + + /* Ported from Qt4 to drop dependency on QtGui */ + static QString QDesktopServicesDataLocation(); + static QString QDesktopServicesCacheLocation(); + /* End of Qt4 code */ + +#ifndef DISABLE_GUI + // Get screen center + static QPoint screenCenter(QWidget *win); +#endif + static QString searchEngineLocation(); + static QString BTBackupLocation(); + static QString cacheLocation(); + static long long freeDiskSpaceOnPath(QString path); + // return best userfriendly storage unit (B, KiB, MiB, GiB, TiB) + // use Binary prefix standards from IEC 60027-2 + // see http://en.wikipedia.org/wiki/Kilobyte + // value must be given in bytes + static QString friendlyUnit(qreal val); + static bool isPreviewable(QString extension); + static QString branchPath(QString file_path, bool uses_slashes=false); + static QString fileName(QString file_path); + static QString magnetUriToName(QString magnet_uri); + static QString magnetUriToHash(QString magnet_uri); + static QString bcLinkToMagnet(QString bc_link); + static QString boostTimeToQString(const boost::optional &boostDate); + static QString time_tToQString(const boost::optional &t); + // Replace ~ in path + static QString expandPath(QString path); + // Take a number of seconds and return an user-friendly + // time duration like "1d 2h 10m". + static QString userFriendlyDuration(qlonglong seconds); + static QString getUserIDString(); + + // Convert functions + static QStringList toStringList(const QList &l); + static QList intListfromStringList(const QStringList &l); + static QList boolListfromStringList(const QStringList &l); + + static bool isValidTorrentFile(const QString &path); +}; + +// Trick to get a portable sleep() function +class SleeperThread : public QThread { +public: + static void msleep(unsigned long msecs) + { + QThread::msleep(msecs); + } +}; + +#endif diff --git a/src/powermanagement/powermanagement.cpp b/src/powermanagement/powermanagement.cpp new file mode 100644 index 000000000..dcbd8ad8f --- /dev/null +++ b/src/powermanagement/powermanagement.cpp @@ -0,0 +1,90 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Vladimir Golovnev + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include + +#if defined(Q_WS_X11) && defined(QT_DBUS_LIB) +#include "powermanagement_x11.h" +#endif +#include "powermanagement.h" + +#ifdef Q_WS_MAC +#include +#endif + +#ifdef Q_WS_WIN +#include +#endif + +PowerManagement::PowerManagement(QObject *parent) : QObject(parent), m_busy(false) +{ +#if defined(Q_WS_X11) && defined(QT_DBUS_LIB) + m_inhibitor = new PowerManagementInhibitor(this); +#endif +} + +PowerManagement::~PowerManagement() +{ +} + +void PowerManagement::setActivityState(bool busy) +{ + if(busy) setBusy(); + else setIdle(); +} + +void PowerManagement::setBusy() +{ + if(m_busy) return; + m_busy = true; + +#ifdef Q_WS_WIN + SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); +#elif defined(Q_WS_X11) && defined(QT_DBUS_LIB) + m_inhibitor->RequestBusy(); +#elif defined(Q_WS_MAC) + IOReturn success = IOPMAssertionCreate(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, &m_assertionID); + if(success != kIOReturnSuccess) m_busy = false; +#endif +} + +void PowerManagement::setIdle() +{ + if(!m_busy) return; + m_busy = false; + +#ifdef Q_WS_WIN + SetThreadExecutionState(ES_CONTINUOUS); +#elif defined(Q_WS_X11) && defined(QT_DBUS_LIB) + m_inhibitor->RequestIdle(); +#elif defined(Q_WS_MAC) + IOPMAssertionRelease(m_assertionID); +#endif +} diff --git a/src/powermanagement/powermanagement.h b/src/powermanagement/powermanagement.h new file mode 100644 index 000000000..3234d22b1 --- /dev/null +++ b/src/powermanagement/powermanagement.h @@ -0,0 +1,70 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Vladimir Golovnev + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef POWERMANAGEMENT_H +#define POWERMANAGEMENT_H + +#include + +#ifdef Q_WS_MAC +// Require Mac OS X >= 10.5 +#include +#endif + +#if defined(Q_WS_X11) && defined(QT_DBUS_LIB) +// Require DBus +class PowerManagementInhibitor; +#endif + +class PowerManagement : public QObject +{ + Q_OBJECT + +public: + PowerManagement(QObject *parent = 0); + virtual ~PowerManagement(); + + void setActivityState(bool busy); + +private: + bool m_busy; + + void setBusy(); + void setIdle(); + +#if defined(Q_WS_X11) && defined(QT_DBUS_LIB) + PowerManagementInhibitor *m_inhibitor; +#endif +#ifdef Q_WS_MAC + IOPMAssertionID m_assertionID; +#endif +}; + +#endif // POWERMANAGEMENT_H diff --git a/src/powermanagement/powermanagement.pri b/src/powermanagement/powermanagement.pri new file mode 100644 index 000000000..d5834d935 --- /dev/null +++ b/src/powermanagement/powermanagement.pri @@ -0,0 +1,9 @@ +INCLUDEPATH += $$PWD + +HEADERS += $$PWD/powermanagement.h +SOURCES += $$PWD/powermanagement.cpp + +unix:!macx:dbus { + HEADERS += $$PWD/powermanagement_x11.h + SOURCES += $$PWD/powermanagement_x11.cpp +} diff --git a/src/powermanagement/powermanagement_x11.cpp b/src/powermanagement/powermanagement_x11.cpp new file mode 100644 index 000000000..2e90c32ee --- /dev/null +++ b/src/powermanagement/powermanagement_x11.cpp @@ -0,0 +1,185 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Vladimir Golovnev + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include + +#include "powermanagement_x11.h" + +PowerManagementInhibitor::PowerManagementInhibitor(QObject *parent) : QObject(parent) +{ + if(!QDBusConnection::sessionBus().isConnected()) + { + qDebug("D-Bus: Could not connect to session bus"); + m_state = error; + } + else + { + m_state = idle; + } + + m_intended_state = idle; + m_cookie = 0; + m_use_gsm = false; +} + +PowerManagementInhibitor::~PowerManagementInhibitor() +{ +} + +void PowerManagementInhibitor::RequestIdle() +{ + m_intended_state = idle; + if (m_state == error || m_state == idle || m_state == request_idle || m_state == request_busy) + return; + + qDebug("D-Bus: PowerManagementInhibitor: Requesting idle"); + + QDBusMessage call; + if (!m_use_gsm) + call = QDBusMessage::createMethodCall( + "org.freedesktop.PowerManagement", + "/org/freedesktop/PowerManagement/Inhibit", + "org.freedesktop.PowerManagement.Inhibit", + "UnInhibit"); + else + call = QDBusMessage::createMethodCall( + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + "Uninhibit"); + + m_state = request_idle; + + QList args; + args << m_cookie; + call.setArguments(args); + + QDBusPendingCall pcall = QDBusConnection::sessionBus().asyncCall(call, 1000); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(OnAsyncReply(QDBusPendingCallWatcher*))); +} + + +void PowerManagementInhibitor::RequestBusy() +{ + m_intended_state = busy; + if (m_state == error || m_state == busy || m_state == request_busy || m_state == request_idle) + return; + + qDebug("D-Bus: PowerManagementInhibitor: Requesting busy"); + + QDBusMessage call; + if (!m_use_gsm) + call = QDBusMessage::createMethodCall( + "org.freedesktop.PowerManagement", + "/org/freedesktop/PowerManagement/Inhibit", + "org.freedesktop.PowerManagement.Inhibit", + "Inhibit"); + else + call = QDBusMessage::createMethodCall( + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + "Inhibit"); + + m_state = request_busy; + + QList args; + args << "qBittorrent"; + if (m_use_gsm) args << (uint)0; + args << "Active torrents are presented"; + if (m_use_gsm) args << (uint)8; + call.setArguments(args); + + QDBusPendingCall pcall = QDBusConnection::sessionBus().asyncCall(call, 1000); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(OnAsyncReply(QDBusPendingCallWatcher*))); +} + +void PowerManagementInhibitor::OnAsyncReply(QDBusPendingCallWatcher *call) +{ + if (m_state == request_idle) + { + QDBusPendingReply<> reply = *call; + + if(reply.isError()) + { + qDebug("D-Bus: Reply: Error: %s", qPrintable(reply.error().message())); + m_state = error; + } + else + { + m_state = idle; + qDebug("D-Bus: PowerManagementInhibitor: Request successful"); + if (m_intended_state == busy) RequestBusy(); + } + } + else if (m_state == request_busy) + { + QDBusPendingReply reply = *call; + + if(reply.isError()) + { + qDebug("D-Bus: Reply: Error: %s", qPrintable(reply.error().message())); + + if (!m_use_gsm) + { + qDebug("D-Bus: Falling back to org.gnome.SessionManager"); + m_use_gsm = true; + m_state = idle; + if (m_intended_state == busy) + RequestBusy(); + } + else + { + m_state = error; + } + } + else + { + m_state = busy; + m_cookie = reply.value(); + qDebug("D-Bus: PowerManagementInhibitor: Request successful, cookie is %d", m_cookie); + if (m_intended_state == idle) RequestIdle(); + } + } + else + { + qDebug("D-Bus: Unexpected reply in state %d", m_state); + m_state = error; + } + + call->deleteLater(); +} diff --git a/src/powermanagement/powermanagement_x11.h b/src/powermanagement/powermanagement_x11.h new file mode 100644 index 000000000..963d57581 --- /dev/null +++ b/src/powermanagement/powermanagement_x11.h @@ -0,0 +1,71 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Vladimir Golovnev + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef POWERMANAGEMENTINHIBITOR_H +#define POWERMANAGEMENTINHIBITOR_H + +#include + +QT_BEGIN_NAMESPACE +class QDBusPendingCallWatcher; +QT_END_NAMESPACE + +class PowerManagementInhibitor : public QObject +{ + Q_OBJECT + +public: + PowerManagementInhibitor(QObject *parent = 0); + virtual ~PowerManagementInhibitor(); + + void RequestIdle(); + void RequestBusy(); + +private slots: + void OnAsyncReply(QDBusPendingCallWatcher *call); + +private: + enum _state + { + error, + idle, + request_busy, + busy, + request_idle + }; + + enum _state m_state; + enum _state m_intended_state; + unsigned int m_cookie; + + bool m_use_gsm; +}; + +#endif // POWERMANAGEMENTINHIBITOR_H diff --git a/src/preferences/advancedsettings.h b/src/preferences/advancedsettings.h new file mode 100644 index 000000000..5441a4673 --- /dev/null +++ b/src/preferences/advancedsettings.h @@ -0,0 +1,245 @@ +#ifndef ADVANCEDSETTINGS_H +#define ADVANCEDSETTINGS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "preferences.h" + +enum AdvSettingsCols {PROPERTY, VALUE}; +enum AdvSettingsRows {DISK_CACHE, OUTGOING_PORT_MIN, OUTGOING_PORT_MAX, IGNORE_LIMIT_LAN, RECHECK_COMPLETED, LIST_REFRESH, RESOLVE_COUNTRIES, RESOLVE_HOSTS, MAX_HALF_OPEN, SUPER_SEEDING, NETWORK_IFACE, NETWORK_ADDRESS, PROGRAM_NOTIFICATIONS, TRACKER_STATUS, TRACKER_PORT, + #if defined(Q_WS_WIN) || defined(Q_WS_MAC) + UPDATE_CHECK, + #endif + #if defined(Q_WS_X11) && (QT_VERSION >= QT_VERSION_CHECK(4,6,0)) + USE_ICON_THEME, + #endif + CONFIRM_DELETE_TORRENT, TRACKER_EXCHANGE, + ROW_COUNT}; + +class AdvancedSettings: public QTableWidget { + Q_OBJECT + +private: + QSpinBox spin_cache, outgoing_ports_min, outgoing_ports_max, spin_list_refresh, spin_maxhalfopen, spin_tracker_port; + QCheckBox cb_ignore_limits_lan, cb_recheck_completed, cb_resolve_countries, cb_resolve_hosts, + cb_super_seeding, cb_program_notifications, cb_tracker_status, cb_confirm_torrent_deletion, + cb_enable_tracker_ext; + QComboBox combo_iface; +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) + QCheckBox cb_update_check; +#endif +#if defined(Q_WS_X11) && (QT_VERSION >= QT_VERSION_CHECK(4,6,0)) + QCheckBox cb_use_icon_theme; +#endif + QLineEdit txt_network_address; + +public: + AdvancedSettings(QWidget *parent=0): QTableWidget(parent) { + // Set visual appearance + setEditTriggers(QAbstractItemView::NoEditTriggers); + setAlternatingRowColors(true); + setColumnCount(2); + QStringList header; + header << tr("Setting") << tr("Value", "Value set for this setting"); + setHorizontalHeaderLabels(header); + setColumnWidth(0, width()/2); + horizontalHeader()->setStretchLastSection(true); + verticalHeader()->setVisible(false); + setRowCount(ROW_COUNT); + // Load settings + loadAdvancedSettings(); + } + + ~AdvancedSettings() { + } + +public slots: + void saveAdvancedSettings() { + Preferences pref; + // Disk write cache + pref.setDiskCacheSize(spin_cache.value()); + // Outgoing ports + pref.setOutgoingPortsMin(outgoing_ports_min.value()); + pref.setOutgoingPortsMax(outgoing_ports_max.value()); + // Ignore limits on LAN + pref.ignoreLimitsOnLAN(cb_ignore_limits_lan.isChecked()); + // Recheck torrents on completion + pref.recheckTorrentsOnCompletion(cb_recheck_completed.isChecked()); + // Transfer list refresh interval + pref.setRefreshInterval(spin_list_refresh.value()); + // Peer resolution + pref.resolvePeerCountries(cb_resolve_countries.isChecked()); + pref.resolvePeerHostNames(cb_resolve_hosts.isChecked()); + // Max Half-Open connections + pref.setMaxHalfOpenConnections(spin_maxhalfopen.value()); +#if LIBTORRENT_VERSION_MINOR > 14 + // Super seeding + pref.enableSuperSeeding(cb_super_seeding.isChecked()); +#endif + // Network interface + if(combo_iface.currentIndex() == 0) { + // All interfaces (default) + pref.setNetworkInterface(QString::null); + } else { + pref.setNetworkInterface(combo_iface.currentText()); + } + // Network address + QHostAddress addr(txt_network_address.text().trimmed()); + if(addr.isNull()) + pref.setNetworkAddress(""); + else + pref.setNetworkAddress(addr.toString()); + // Program notification + pref.useProgramNotification(cb_program_notifications.isChecked()); + // Tracker + pref.setTrackerEnabled(cb_tracker_status.isChecked()); + pref.setTrackerPort(spin_tracker_port.value()); +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) + pref.setUpdateCheckEnabled(cb_update_check.isChecked()); +#endif + // Icon theme +#if defined(Q_WS_X11) && (QT_VERSION >= QT_VERSION_CHECK(4,6,0)) + pref.useSystemIconTheme(cb_use_icon_theme.isChecked()); +#endif + pref.setConfirmTorrentDeletion(cb_confirm_torrent_deletion.isChecked()); + // Tracker exchange + pref.setTrackerEnabled(cb_enable_tracker_ext.isChecked()); + } + +signals: + void settingsChanged(); + +private: + void setRow(int row, const QString &property, QSpinBox* editor) { + setItem(row, PROPERTY, new QTableWidgetItem(property)); + bool ok; Q_UNUSED(ok); + ok = connect(editor, SIGNAL(valueChanged(int)), SIGNAL(settingsChanged())); + Q_ASSERT(ok); + setCellWidget(row, VALUE, editor); + } + + void setRow(int row, const QString &property, QComboBox* editor) { + setItem(row, PROPERTY, new QTableWidgetItem(property)); + bool ok; Q_UNUSED(ok); + ok = connect(editor, SIGNAL(currentIndexChanged(int)), SIGNAL(settingsChanged())); + Q_ASSERT(ok); + setCellWidget(row, VALUE, editor); + } + + void setRow(int row, const QString &property, QCheckBox* editor) { + setItem(row, PROPERTY, new QTableWidgetItem(property)); + bool ok; Q_UNUSED(ok); + ok = connect(editor, SIGNAL(stateChanged(int)), SIGNAL(settingsChanged())); + Q_ASSERT(ok); + setCellWidget(row, VALUE, editor); + } + + void setRow(int row, const QString &property, QLineEdit* editor) { + setItem(row, PROPERTY, new QTableWidgetItem(property)); + bool ok; Q_UNUSED(ok); + ok = connect(editor, SIGNAL(textChanged(QString)), SIGNAL(settingsChanged())); + Q_ASSERT(ok); + setCellWidget(row, VALUE, editor); + } + +private slots: + void loadAdvancedSettings() { + const Preferences pref; + // Disk write cache + spin_cache.setMinimum(1); + spin_cache.setMaximum(200); + spin_cache.setValue(pref.diskCacheSize()); + spin_cache.setSuffix(tr(" MiB")); + setRow(DISK_CACHE, tr("Disk write cache size"), &spin_cache); + // Outgoing port Min + outgoing_ports_min.setMinimum(0); + outgoing_ports_min.setMaximum(65535); + outgoing_ports_min.setValue(pref.outgoingPortsMin()); + setRow(OUTGOING_PORT_MIN, tr("Outgoing ports (Min) [0: Disabled]"), &outgoing_ports_min); + // Outgoing port Min + outgoing_ports_max.setMinimum(0); + outgoing_ports_max.setMaximum(65535); + outgoing_ports_max.setValue(pref.outgoingPortsMax()); + setRow(OUTGOING_PORT_MAX, tr("Outgoing ports (Max) [0: Disabled]"), &outgoing_ports_max); + // Ignore transfer limits on local network + cb_ignore_limits_lan.setChecked(pref.ignoreLimitsOnLAN()); + setRow(IGNORE_LIMIT_LAN, tr("Ignore transfer limits on local network"), &cb_ignore_limits_lan); + // Recheck completed torrents + cb_recheck_completed.setChecked(pref.recheckTorrentsOnCompletion()); + setRow(RECHECK_COMPLETED, tr("Recheck torrents on completion"), &cb_recheck_completed); + // Transfer list refresh interval + spin_list_refresh.setMinimum(30); + spin_list_refresh.setMaximum(99999); + spin_list_refresh.setValue(pref.getRefreshInterval()); + spin_list_refresh.setSuffix(tr(" ms", " milliseconds")); + setRow(LIST_REFRESH, tr("Transfer list refresh interval"), &spin_list_refresh); + // Resolve Peer countries + cb_resolve_countries.setChecked(pref.resolvePeerCountries()); + setRow(RESOLVE_COUNTRIES, tr("Resolve peer countries (GeoIP)"), &cb_resolve_countries); + // Resolve peer hosts + cb_resolve_hosts.setChecked(pref.resolvePeerHostNames()); + setRow(RESOLVE_HOSTS, tr("Resolve peer host names"), &cb_resolve_hosts); + // Max Half Open connections + spin_maxhalfopen.setMinimum(0); + spin_maxhalfopen.setMaximum(99999); + spin_maxhalfopen.setValue(pref.getMaxHalfOpenConnections()); + setRow(MAX_HALF_OPEN, tr("Maximum number of half-open connections [0: Disabled]"), &spin_maxhalfopen); + // Super seeding +#if LIBTORRENT_VERSION_MINOR > 14 + cb_super_seeding.setChecked(pref.isSuperSeedingEnabled()); +#else + cb_super_seeding.setEnabled(false); +#endif + setRow(SUPER_SEEDING, tr("Strict super seeding"), &cb_super_seeding); + // Network interface + combo_iface.addItem(tr("Any interface", "i.e. Any network interface")); + const QString current_iface = pref.getNetworkInterface(); + int i = 1; + foreach(const QNetworkInterface& iface, QNetworkInterface::allInterfaces()) { + if(iface.flags() & QNetworkInterface::IsLoopBack) continue; + combo_iface.addItem(iface.name()); + if(!current_iface.isEmpty() && iface.name() == current_iface) + combo_iface.setCurrentIndex(i); + ++i; + } + setRow(NETWORK_IFACE, tr("Network Interface (requires restart)"), &combo_iface); + // Network address + txt_network_address.setText(pref.getNetworkAddress()); + setRow(NETWORK_ADDRESS, tr("IP Address to report to trackers (requires restart)"), &txt_network_address); + // Program notifications + cb_program_notifications.setChecked(pref.useProgramNotification()); + setRow(PROGRAM_NOTIFICATIONS, tr("Display program on-screen notifications"), &cb_program_notifications); + // Tracker State + cb_tracker_status.setChecked(pref.isTrackerEnabled()); + setRow(TRACKER_STATUS, tr("Enable embedded tracker"), &cb_tracker_status); + // Tracker port + spin_tracker_port.setMinimum(1); + spin_tracker_port.setMaximum(65535); + spin_tracker_port.setValue(pref.getTrackerPort()); + setRow(TRACKER_PORT, tr("Embedded tracker port"), &spin_tracker_port); +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) + cb_update_check.setChecked(pref.isUpdateCheckEnabled()); + setRow(UPDATE_CHECK, tr("Check for software updates"), &cb_update_check); +#endif +#if defined(Q_WS_X11) && (QT_VERSION >= QT_VERSION_CHECK(4,6,0)) + cb_use_icon_theme.setChecked(pref.useSystemIconTheme()); + setRow(USE_ICON_THEME, tr("Use system icon theme"), &cb_use_icon_theme); +#endif + // Torrent deletion confirmation + cb_confirm_torrent_deletion.setChecked(pref.confirmTorrentDeletion()); + setRow(CONFIRM_DELETE_TORRENT, tr("Confirm torrent deletion"), &cb_confirm_torrent_deletion); + // Tracker exchange + cb_enable_tracker_ext.setChecked(pref.trackerExchangeEnabled()); + setRow(TRACKER_EXCHANGE, tr("Exchange trackers with other peers"), &cb_enable_tracker_ext); + } + +}; + +#endif // ADVANCEDSETTINGS_H diff --git a/src/preferences/options.ui b/src/preferences/options.ui new file mode 100644 index 000000000..ce469cd39 --- /dev/null +++ b/src/preferences/options.ui @@ -0,0 +1,2766 @@ + + + Preferences + + + + 0 + 0 + 789 + 591 + + + + + 0 + 0 + + + + Options + + + + + + Qt::Horizontal + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + false + + + + 32 + 32 + + + + QListView::LeftToRight + + + true + + + QListView::Adjust + + + 4 + + + + 110 + 60 + + + + QListView::IconMode + + + false + + + false + + + -1 + + + + Behavior + + + Behavior + + + AlignHCenter|AlignVCenter|AlignCenter + + + ItemIsSelectable|ItemIsEnabled + + + + + Downloads + + + AlignHCenter|AlignVCenter|AlignCenter + + + ItemIsSelectable|ItemIsEnabled + + + + + Connection + + + AlignHCenter|AlignVCenter|AlignCenter + + + ItemIsSelectable|ItemIsEnabled + + + + + Speed + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + BitTorrent + + + AlignHCenter|AlignVCenter|AlignCenter + + + ItemIsSelectable|ItemIsEnabled + + + + + Web UI + + + AlignHCenter|AlignVCenter|AlignCenter + + + ItemIsSelectable|ItemIsEnabled + + + + + Advanced + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + + 0 + + + + + + + + 0 + 0 + + + + true + + + + + 0 + 0 + 488 + 601 + + + + + + + Language + + + + + + + + User Interface Language: + + + + + + + + 0 + 0 + + + + QComboBox::AdjustToContents + + + 0 + + + + + + + + 8 + true + + + + (Requires restart) + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Transfer List + + + + + + Use alternating row colors + + + true + + + + + + + + 50 + false + + + + Action on double-click + + + true + + + + QFormLayout::ExpandingFieldsGrow + + + 0 + + + + + Downloading torrents: + + + + + + + + 0 + 0 + + + + 0 + + + + Start / Stop Torrent + + + + + Open destination folder + + + + + No action + + + + + + + + Completed torrents: + + + + + + + + Start / Stop Torrent + + + + + Open destination folder + + + + + No action + + + + + + + + + + + + + + Desktop + + + + + + Show splash screen on start up + + + true + + + + + + + Start qBittorrent minimized + + + + + + + Ask for program exit confirmation + + + true + + + + + + + Show qBittorrent in notification area + + + true + + + + + + Minimize qBittorrent to notification area + + + false + + + + + + + Close qBittorrent to notification area + + + + + + + + + Tray icon style: + + + + + + + + Normal + + + + + Monochrome (Dark theme) + + + + + Monochrome (Light theme) + + + + + + + + + + + + + + + + Power Management + + + + + + Inhibit system sleep when torrents are active + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + true + + + + + 0 + 0 + 501 + 999 + + + + + + + + 0 + 0 + + + + When adding a torrent + + + + 9 + + + + + Display torrent content and some options + + + false + + + + + + + Do not start the download automatically + + + + + + + + + + + 0 + 0 + + + + Hard Disk + + + + 9 + + + + + Save files to location: + + + + 9 + + + + + + + + 0 + 0 + + + + + + + + + + + true + + + + 22 + 22 + + + + + 25 + 27 + + + + ... + + + + + + + + + Append the label of the torrent to the save path + + + + + + + + + + Pre-allocate disk space for all files + + + + + + + Keep incomplete torrents in: + + + true + + + false + + + + 9 + + + + + + + + + 25 + 27 + + + + + 22 + 22 + + + + + 25 + 27 + + + + ... + + + + + + + + + + Append .!qB extension to incomplete files + + + + + + + Automatically add torrents from: + + + + 9 + + + + + + + + 0 + 1 + + + + + 250 + 75 + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + true + + + 80 + + + false + + + true + + + false + + + + + + + + + Add folder... + + + + + + + false + + + Remove folder + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + 0 + 0 + + + + Copy .torrent files to: + + + true + + + false + + + + 9 + + + + + + + + + 22 + 22 + + + + + 25 + 27 + + + + ... + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Email notification upon download completion + + + true + + + false + + + + + + + + Destination email: + + + + + + + + + + SMTP server: + + + + + + + + + + Authentication + + + true + + + false + + + + + + Username: + + + + + + + + + + Password: + + + + + + + QLineEdit::Password + + + + + + + + + + This server requires a secure connection (SSL) + + + + + + + + + + + + Run an external program on torrent completion + + + true + + + false + + + + + + + + + The following parameters are supported: +<ul> +<li>%f: Torrent path</li> +<li>%n: Torrent name</li> +</ul> + + + Qt::RichText + + + + + + + + + + + + + + + + + + true + + + + + 0 + 0 + 488 + 560 + + + + + + + + + Listening Port + + + + + + + + Port used for incoming connections: + + + + + + + 1 + + + 65535 + + + 6881 + + + + + + + Random + + + + + + + Qt::Horizontal + + + + 20 + 20 + + + + + + + + + + Use UPnP / NAT-PMP port forwarding from my router + + + true + + + + + + + + + + + + Connections Limits + + + + + + Global maximum number of connections: + + + true + + + + + + + true + + + 2 + + + 2000 + + + 500 + + + + + + + Maximum number of connections per torrent: + + + true + + + + + + + 2 + + + 2000 + + + 100 + + + + + + + Maximum number of upload slots per torrent: + + + true + + + + + + + 500 + + + 4 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + true + + + Proxy Server + + + + + + + + Type: + + + + + + + + (None) + + + + + SOCKS4 + + + + + SOCKS5 + + + + + HTTP + + + + + + + + false + + + Host: + + + + + + + false + + + + + + 75 + + + QLineEdit::Normal + + + + + + + false + + + Port: + + + + + + + false + + + 1 + + + 65535 + + + 8080 + + + + + + + + + false + + + Otherwise, the proxy server is only used for tracker connections + + + Use proxy for peer connections + + + + + + + false + + + Authentication + + + true + + + false + + + + + + + + false + + + Username: + + + + + + + false + + + + + + 1000 + + + QLineEdit::Normal + + + + + + + false + + + Password: + + + + + + + false + + + + + + 1000 + + + QLineEdit::Password + + + + + + + + + + + + + + + IP Filtering + + + true + + + false + + + + + + Filter path (.dat, .p2p, .p2b): + + + + + + + + + + + 28 + 27 + + + + ... + + + + + + + + 28 + 27 + + + + Reload the filter + + + + + + + 16 + 16 + + + + + + + + + + + + + + + + + + + + + + true + + + + + 0 + 0 + 506 + 510 + + + + + + + Global Rate Limits + + + + + + + + + :/Icons/slow_off.png + + + + + + + + + Upload: + + + true + + + + + + + true + + + + + + 1 + + + 1000000 + + + 50 + + + + + + + KiB/s + + + + + + + Download: + + + + + + + false + + + + + + 1 + + + 1000000 + + + 100 + + + + + + + KiB/s + + + + + + + + + Qt::Horizontal + + + + 200 + 20 + + + + + + + + Options + + + + + + Enable bandwidth management (uTP) + + + true + + + + + + + Apply rate limit to uTP connections + + + + + + + Apply rate limit to transport overhead + + + + + + + + + + + + + Alternative Global Rate Limits + + + + + + + + + 48 + 48 + + + + + 48 + 48 + + + + + + + :/Icons/slow.png + + + false + + + + + + + + + Upload: + + + + + + + 1 + + + 1000000 + + + 10 + + + + + + + KiB/s + + + + + + + Download: + + + + + + + 1 + + + 1000000 + + + 10 + + + + + + + KiB/s + + + + + + + + + Qt::Horizontal + + + + 222 + 59 + + + + + + + + + + Schedule the use of alternative rate limits + + + true + + + false + + + + + + 5 + + + + + from + + + + + + + + + + hh:mm + + + false + + + + + + + to + + + Qt::AlignCenter + + + + + + + + + + hh:mm + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 5 + + + + + When: + + + + + + + + Every day + + + + + Week days + + + + + Week ends + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + true + + + + + 0 + 0 + 545 + 492 + + + + + + + Privacy + + + + + + Enable DHT (decentralized network) to find more peers + + + true + + + + 9 + + + + + Use a different port for DHT and BitTorrent + + + true + + + false + + + + 9 + + + + + 5 + + + + + DHT port: + + + + + + + 1 + + + 65525 + + + 6881 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + Exchange peers with compatible Bittorrent clients (µTorrent, Vuze, ...) + + + Enable Peer Exchange (PeX) to find more peers + + + true + + + + + + + Look for peers on your local network + + + Enable Local Peer Discovery to find more peers + + + true + + + + + + + + + Encryption mode: + + + + + + + + Prefer encryption + + + + + Require encryption + + + + + Disable encryption + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Torrent Queueing + + + true + + + false + + + + 9 + + + + + Maximum active downloads: + + + + + + + -1 + + + 999 + + + 3 + + + + + + + Maximum active uploads: + + + + + + + -1 + + + 999 + + + 3 + + + + + + + Maximum active torrents: + + + + + + + -1 + + + 999 + + + 5 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Share Ratio Limiting + + + + 9 + + + + + + + Seed torrents until their ratio reaches + + + + + + + false + + + Qt::AlignHCenter + + + 1 + + + 0.000000000000000 + + + 20.000000000000000 + + + 0.050000000000000 + + + 1.000000000000000 + + + + + + + then + + + + + + + false + + + + Pause them + + + + + Remove them + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + true + + + + + 0 + 0 + 488 + 594 + + + + + + + Enable Web User Interface (Remote control) + + + true + + + false + + + + + + + + Port: + + + + + + + 1 + + + 65535 + + + 8080 + + + + + + + Qt::Horizontal + + + + 21 + 29 + + + + + + + + + + Use UPnP / NAT-PMP to forward the port from my router + + + true + + + + + + + Use HTTPS instead of HTTP + + + true + + + false + + + + + + + 22 + 22 + + + + + 22 + 22 + + + + + + + + + + + Certificate: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + Import SSL Certificate + + + + + + + Qt::Horizontal + + + + 138 + 28 + + + + + + + + + + + 22 + 22 + + + + + 22 + 22 + + + + + + + + + + + Key: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + Import SSL Key + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + <a href=http://httpd.apache.org/docs/2.1/ssl/ssl_faq.html#aboutcerts>Information about certificates</a> + + + true + + + + + + + + + + Authentication + + + + + + + + + 1000 + + + QLineEdit::Normal + + + + + + + + + + 1000 + + + QLineEdit::Password + + + + + + + Bypass authentication for localhost + + + + + + + Username: + + + + + + + Password: + + + + + + + + + + Update my dynamic domain name + + + true + + + false + + + + + + Service: + + + + + + + + + + DynDNS + + + + + No-IP + + + + + + + + Register + + + + + + + + + Domain name: + + + + + + + changeme.dyndns.org + + + + + + + Username: + + + + + + + 50 + + + + + + + Password: + + + + + + + 50 + + + QLineEdit::Password + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 208 + 20 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + false + + + + + + + + + tabOption + comboI18n + textSavePath + browseSaveDirButton + checkAdditionDialog + checkStartPaused + spinPort + checkUPnP + checkLSD + comboEncryption + checkMaxRatio + spinMaxRatio + spinWebUiPort + textWebUiUsername + textWebUiPassword + + + + + + + checkUploadLimit + toggled(bool) + spinUploadLimit + setEnabled(bool) + + + 367 + 61 + + + 448 + 62 + + + + + checkDownloadLimit + toggled(bool) + spinDownloadLimit + setEnabled(bool) + + + 377 + 81 + + + 430 + 87 + + + + + checkMaxConnecs + toggled(bool) + spinMaxConnec + setEnabled(bool) + + + 496 + 157 + + + 643 + 165 + + + + + checkMaxConnecsPerTorrent + toggled(bool) + spinMaxConnecPerTorrent + setEnabled(bool) + + + 494 + 188 + + + 611 + 190 + + + + + checkMaxUploadsPerTorrent + toggled(bool) + spinMaxUploadsPerTorrent + setEnabled(bool) + + + 510 + 214 + + + 616 + 217 + + + + + checkMaxRatio + toggled(bool) + spinMaxRatio + setEnabled(bool) + + + 542 + 404 + + + 598 + 405 + + + + + checkMaxRatio + toggled(bool) + comboRatioLimitAct + setEnabled(bool) + + + 542 + 404 + + + 757 + 406 + + + + + checkuTP + toggled(bool) + checkLimituTPConnections + setEnabled(bool) + + + 421 + 147 + + + 430 + 176 + + + + + diff --git a/src/preferences/options_imp.cpp b/src/preferences/options_imp.cpp new file mode 100644 index 000000000..fef0227ff --- /dev/null +++ b/src/preferences/options_imp.cpp @@ -0,0 +1,1281 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "options_imp.h" +#include "preferences.h" +#include "misc.h" +#include "advancedsettings.h" +#include "scannedfoldersmodel.h" +#include "qinisettings.h" +#include "qbtsession.h" +#include "iconprovider.h" +#include "dnsupdater.h" + +#ifndef QT_NO_OPENSSL +#include +#include +#endif + +using namespace libtorrent; + +// Constructor +options_imp::options_imp(QWidget *parent): + QDialog(parent), m_refreshingIpFilter(false) { + qDebug("-> Constructing Options"); + setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + setModal(true); + // Icons + tabSelection->item(TAB_UI)->setIcon(IconProvider::instance()->getIcon("preferences-desktop")); + tabSelection->item(TAB_BITTORRENT)->setIcon(IconProvider::instance()->getIcon("preferences-system-network")); + tabSelection->item(TAB_CONNECTION)->setIcon(IconProvider::instance()->getIcon("network-wired")); + tabSelection->item(TAB_DOWNLOADS)->setIcon(IconProvider::instance()->getIcon("download")); + tabSelection->item(TAB_SPEED)->setIcon(IconProvider::instance()->getIcon("chronometer")); + tabSelection->item(TAB_WEBUI)->setIcon(IconProvider::instance()->getIcon("network-server")); + tabSelection->item(TAB_ADVANCED)->setIcon(IconProvider::instance()->getIcon("preferences-other")); + IpFilterRefreshBtn->setIcon(IconProvider::instance()->getIcon("view-refresh")); + + hsplitter->setCollapsible(0, false); + hsplitter->setCollapsible(1, false); + // Get apply button in button box + QList buttons = buttonBox->buttons(); + foreach(QAbstractButton *button, buttons){ + if(buttonBox->buttonRole(button) == QDialogButtonBox::ApplyRole){ + applyButton = button; + break; + } + } + + scanFoldersView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents); + scanFoldersView->setModel(ScanFoldersModel::instance()); + connect(ScanFoldersModel::instance(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(enableApplyButton())); + connect(scanFoldersView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(handleScanFolderViewSelectionChanged())); + + connect(buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(applySettings(QAbstractButton*))); + // Languages supported + initializeLanguageCombo(); + + // Load week days (scheduler) + for(uint i=1; i<=7; ++i) { +#if QT_VERSION >= 0x040500 + schedule_days->addItem(QDate::longDayName(i, QDate::StandaloneFormat)); +#else + schedule_days->addItem(QDate::longDayName(i)); +#endif + } + + // Load options + loadOptions(); + // Disable systray integration if it is not supported by the system + if(!QSystemTrayIcon::isSystemTrayAvailable()){ + checkShowSystray->setChecked(false); + checkShowSystray->setEnabled(false); + } +#if !defined(Q_WS_X11) + label_trayIconStyle->setVisible(false); + comboTrayIcon->setVisible(false); +#endif +#if defined(QT_NO_OPENSSL) + checkWebUiHttps->setVisible(false); +#endif + // Connect signals / slots + // Proxy tab + connect(comboProxyType, SIGNAL(currentIndexChanged(int)),this, SLOT(enableProxy(int))); + + // Apply button is activated when a value is changed + // General tab + connect(comboI18n, SIGNAL(currentIndexChanged(int)), this, SLOT(enableApplyButton())); + connect(checkAltRowColors, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkShowSystray, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkCloseToSystray, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkMinimizeToSysTray, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkStartMinimized, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkShowSplash, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkProgramExitConfirm, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkPreventFromSuspend, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(comboTrayIcon, SIGNAL(currentIndexChanged(int)), this, SLOT(enableApplyButton())); +#if defined(Q_WS_X11) && !defined(QT_DBUS_LIB) + checkPreventFromSuspend->setDisabled(true); +#endif + // Downloads tab + connect(textSavePath, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + connect(textTempPath, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + connect(checkAppendLabel, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkAppendqB, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkPreallocateAll, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkAdditionDialog, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkStartPaused, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkExportDir, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(textExportDir, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + connect(actionTorrentDlOnDblClBox, SIGNAL(currentIndexChanged(int)), this, SLOT(enableApplyButton())); + connect(actionTorrentFnOnDblClBox, SIGNAL(currentIndexChanged(int)), this, SLOT(enableApplyButton())); + connect(checkTempFolder, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(addScanFolderButton, SIGNAL(clicked()), this, SLOT(enableApplyButton())); + connect(removeScanFolderButton, SIGNAL(clicked()), this, SLOT(enableApplyButton())); + connect(groupMailNotification, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(dest_email_txt, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + connect(smtp_server_txt, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + connect(checkSmtpSSL, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(groupMailNotifAuth, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(mailNotifUsername, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + connect(mailNotifPassword, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + connect(autoRunBox, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(autoRun_txt, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + // Connection tab + connect(spinPort, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(checkUPnP, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkUploadLimit, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkDownloadLimit, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(spinUploadLimit, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(spinDownloadLimit, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(spinUploadLimitAlt, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(spinDownloadLimitAlt, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(check_schedule, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(schedule_from, SIGNAL(timeChanged(QTime)), this, SLOT(enableApplyButton())); + connect(schedule_to, SIGNAL(timeChanged(QTime)), this, SLOT(enableApplyButton())); + connect(schedule_days, SIGNAL(currentIndexChanged(int)), this, SLOT(enableApplyButton())); + connect(checkuTP, SIGNAL(toggled(bool)), SLOT(enableApplyButton())); + connect(checkLimituTPConnections, SIGNAL(toggled(bool)), SLOT(enableApplyButton())); + connect(checkLimitTransportOverhead, SIGNAL(toggled(bool)), SLOT(enableApplyButton())); + // Bittorrent tab + connect(checkMaxConnecs, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkMaxConnecsPerTorrent, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkMaxUploadsPerTorrent, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(spinMaxConnec, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(spinMaxConnecPerTorrent, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(spinMaxUploadsPerTorrent, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(checkDHT, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkPeX, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkDifferentDHTPort, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(spinDHTPort, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(checkLSD, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(comboEncryption, SIGNAL(currentIndexChanged(int)), this, SLOT(enableApplyButton())); + connect(checkMaxRatio, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(spinMaxRatio, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(comboRatioLimitAct, SIGNAL(currentIndexChanged(int)), this, SLOT(enableApplyButton())); + // Proxy tab + connect(comboProxyType, SIGNAL(currentIndexChanged(int)), this, SLOT(enableApplyButton())); + connect(textProxyIP, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + connect(spinProxyPort, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(checkProxyPeerConnecs, SIGNAL(toggled(bool)), SLOT(enableApplyButton())); + connect(checkProxyAuth, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(textProxyUsername, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + connect(textProxyPassword, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + // Misc tab + connect(checkIPFilter, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(textFilterPath, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + connect(checkEnableQueueing, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(spinMaxActiveDownloads, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(spinMaxActiveUploads, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + connect(spinMaxActiveTorrents, SIGNAL(valueChanged(QString)), this, SLOT(enableApplyButton())); + // Web UI tab + connect(checkWebUi, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(spinWebUiPort, SIGNAL(valueChanged(int)), this, SLOT(enableApplyButton())); + connect(checkWebUIUPnP, SIGNAL(toggled(bool)), SLOT(enableApplyButton())); + connect(checkWebUiHttps, SIGNAL(toggled(bool)), SLOT(enableApplyButton())); + connect(btnWebUiKey, SIGNAL(clicked()), SLOT(enableApplyButton())); + connect(btnWebUiCrt, SIGNAL(clicked()), SLOT(enableApplyButton())); + connect(textWebUiUsername, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + connect(textWebUiPassword, SIGNAL(textChanged(QString)), this, SLOT(enableApplyButton())); + connect(checkBypassLocalAuth, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(checkDynDNS, SIGNAL(toggled(bool)), SLOT(enableApplyButton())); + connect(comboDNSService, SIGNAL(currentIndexChanged(int)), SLOT(enableApplyButton())); + connect(domainNameTxt, SIGNAL(textChanged(QString)), SLOT(enableApplyButton())); + connect(DNSUsernameTxt, SIGNAL(textChanged(QString)), SLOT(enableApplyButton())); + connect(DNSPasswordTxt, SIGNAL(textChanged(QString)), SLOT(enableApplyButton())); + // Disable apply Button + applyButton->setEnabled(false); + // Tab selection mecanism + connect(tabSelection, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this, SLOT(changePage(QListWidgetItem *, QListWidgetItem*))); +#if LIBTORRENT_VERSION_MINOR < 15 + checkAppendqB->setVisible(false); +#endif +#if LIBTORRENT_VERSION_MINOR < 16 + checkuTP->setVisible(false); + checkLimituTPConnections->setVisible(false); +#endif + // Load Advanced settings + QVBoxLayout *adv_layout = new QVBoxLayout(); + advancedSettings = new AdvancedSettings(); + adv_layout->addWidget(advancedSettings); + scrollArea_advanced->setLayout(adv_layout); + connect(advancedSettings, SIGNAL(settingsChanged()), this, SLOT(enableApplyButton())); + + // Adapt size + show(); + loadWindowState(); +} + +void options_imp::initializeLanguageCombo() +{ + // List language files + const QDir lang_dir(":/lang"); + const QStringList lang_files = lang_dir.entryList(QStringList() << "qbittorrent_*.qm", QDir::Files); + foreach(QString lang_file, lang_files) { + QString localeStr = lang_file.mid(12); // remove "qbittorrent_" + localeStr.chop(3); // Remove ".qm" + QLocale locale(localeStr); + const QString country = locale.name().split("_").last().toLower(); + QString language_name = languageToLocalizedString(locale.language(), country); + comboI18n->addItem(/*QIcon(":/Icons/flags/"+country+".png"), */language_name, locale.name()); + qDebug() << "Supported locale:" << locale.name(); + } +} + +// Main destructor +options_imp::~options_imp(){ + qDebug("-> destructing Options"); + foreach (const QString &path, addedScanDirs) + ScanFoldersModel::instance()->removePath(path); + delete scrollArea_advanced->layout(); + delete advancedSettings; +} + +void options_imp::changePage(QListWidgetItem *current, QListWidgetItem *previous) { + if (!current) + current = previous; + tabOption->setCurrentIndex(tabSelection->row(current)); +} + +void options_imp::loadWindowState() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + resize(settings.value(QString::fromUtf8("Preferences/State/size"), sizeFittingScreen()).toSize()); + QPoint p = settings.value(QString::fromUtf8("Preferences/State/pos"), QPoint()).toPoint(); + if(!p.isNull()) + move(p); + // Load slider size + const QStringList sizes_str = settings.value("Preferences/State/hSplitterSizes", QStringList()).toStringList(); + // Splitter size + QList sizes; + if(sizes_str.size() == 2) { + sizes << sizes_str.first().toInt(); + sizes << sizes_str.last().toInt(); + } else { + sizes << 130; + sizes << hsplitter->width()-130; + } + hsplitter->setSizes(sizes); +} + +void options_imp::saveWindowState() const { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.setValue(QString::fromUtf8("Preferences/State/size"), size()); + settings.setValue(QString::fromUtf8("Preferences/State/pos"), pos()); + // Splitter size + QStringList sizes_str; + sizes_str << QString::number(hsplitter->sizes().first()); + sizes_str << QString::number(hsplitter->sizes().last()); + settings.setValue(QString::fromUtf8("Preferences/State/hSplitterSizes"), sizes_str); +} + +QSize options_imp::sizeFittingScreen() const { + int scrn = 0; + QWidget *w = this->topLevelWidget(); + + if(w) + scrn = QApplication::desktop()->screenNumber(w); + else if(QApplication::desktop()->isVirtualDesktop()) + scrn = QApplication::desktop()->screenNumber(QCursor::pos()); + else + scrn = QApplication::desktop()->screenNumber(this); + + QRect desk(QApplication::desktop()->availableGeometry(scrn)); + if(width() > desk.width() || height() > desk.height()) { + if(desk.width() > 0 && desk.height() > 0) + return QSize(desk.width(), desk.height()); + } + return size(); +} + +void options_imp::saveOptions(){ + applyButton->setEnabled(false); + Preferences pref; + // Load the translation + QString locale = getLocale(); + if(pref.getLocale() != locale) { + QTranslator *translator = new QTranslator; + if(translator->load(QString::fromUtf8(":/lang/qbittorrent_") + locale)){ + qDebug("%s locale recognized, using translation.", qPrintable(locale)); + }else{ + qDebug("%s locale unrecognized, using default (en_GB).", qPrintable(locale)); + } + qApp->installTranslator(translator); + } + + // General preferences + pref.setLocale(locale); + pref.setAlternatingRowColors(checkAltRowColors->isChecked()); + pref.setSystrayIntegration(systrayIntegration()); + pref.setTrayIconStyle(TrayIcon::Style(comboTrayIcon->currentIndex())); + pref.setCloseToTray(closeToTray()); + pref.setMinimizeToTray(minimizeToTray()); + pref.setStartMinimized(startMinimized()); + pref.setSplashScreenDisabled(isSlashScreenDisabled()); + pref.setConfirmOnExit(checkProgramExitConfirm->isChecked()); + pref.setPreventFromSuspend(preventFromSuspend()); + // End General preferences + + // Downloads preferences + QString save_path = getSavePath(); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + save_path = save_path.replace("\\", "/"); +#endif + pref.setSavePath(save_path); + pref.setTempPathEnabled(isTempPathEnabled()); + QString temp_path = getTempPath(); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + temp_path = temp_path.replace("\\", "/"); +#endif + pref.setTempPath(temp_path); + pref.setAppendTorrentLabel(checkAppendLabel->isChecked()); +#if LIBTORRENT_VERSION_MINOR > 14 + pref.useIncompleteFilesExtension(checkAppendqB->isChecked()); +#endif + pref.preAllocateAllFiles(preAllocateAllFiles()); + pref.useAdditionDialog(useAdditionDialog()); + pref.addTorrentsInPause(addTorrentsInPause()); + ScanFoldersModel::instance()->makePersistent(); + addedScanDirs.clear(); + QString export_dir = getExportDir(); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + export_dir = export_dir.replace("\\", "/"); +#endif + pref.setExportDir(export_dir); + pref.setMailNotificationEnabled(groupMailNotification->isChecked()); + pref.setMailNotificationEmail(dest_email_txt->text()); + pref.setMailNotificationSMTP(smtp_server_txt->text()); + pref.setMailNotificationSMTPSSL(checkSmtpSSL->isChecked()); + pref.setMailNotificationSMTPAuth(groupMailNotifAuth->isChecked()); + pref.setMailNotificationSMTPUsername(mailNotifUsername->text()); + pref.setMailNotificationSMTPPassword(mailNotifPassword->text()); + pref.setAutoRunEnabled(autoRunBox->isChecked()); + pref.setAutoRunProgram(autoRun_txt->text()); + pref.setActionOnDblClOnTorrentDl(getActionOnDblClOnTorrentDl()); + pref.setActionOnDblClOnTorrentFn(getActionOnDblClOnTorrentFn()); + // End Downloads preferences + // Connection preferences + pref.setSessionPort(getPort()); + pref.setUPnPEnabled(isUPnPEnabled()); + const QPair down_up_limit = getGlobalBandwidthLimits(); + pref.setGlobalDownloadLimit(down_up_limit.first); + pref.setGlobalUploadLimit(down_up_limit.second); + pref.setuTPEnabled(checkuTP->isChecked()); + pref.setuTPRateLimited(checkLimituTPConnections->isChecked()); + pref.includeOverheadInLimits(checkLimitTransportOverhead->isChecked()); + pref.setAltGlobalDownloadLimit(spinDownloadLimitAlt->value()); + pref.setAltGlobalUploadLimit(spinUploadLimitAlt->value()); + pref.setSchedulerEnabled(check_schedule->isChecked()); + pref.setSchedulerStartTime(schedule_from->time()); + pref.setSchedulerEndTime(schedule_to->time()); + pref.setSchedulerDays((scheduler_days)schedule_days->currentIndex()); + pref.setProxyType(getProxyType()); + pref.setProxyIp(getProxyIp()); + pref.setProxyPort(getProxyPort()); + pref.setProxyPeerConnections(checkProxyPeerConnecs->isChecked()); + pref.setProxyAuthEnabled(isProxyAuthEnabled()); + pref.setProxyUsername(getProxyUsername()); + pref.setProxyPassword(getProxyPassword()); + // End Connection preferences + // Bittorrent preferences + pref.setMaxConnecs(getMaxConnecs()); + pref.setMaxConnecsPerTorrent(getMaxConnecsPerTorrent()); + pref.setMaxUploadsPerTorrent(getMaxUploadsPerTorrent()); + pref.setDHTEnabled(isDHTEnabled()); + pref.setPeXEnabled(checkPeX->isChecked()); + pref.setDHTPortSameAsBT(isDHTPortSameAsBT()); + pref.setDHTPort(getDHTPort()); + pref.setLSDEnabled(isLSDEnabled()); + pref.setEncryptionSetting(getEncryptionSetting()); + pref.setGlobalMaxRatio(getMaxRatio()); + pref.setMaxRatioAction(comboRatioLimitAct->currentIndex()); + // End Bittorrent preferences + // Misc preferences + // * IPFilter + pref.setFilteringEnabled(isFilteringEnabled()); + if(isFilteringEnabled()){ + QString filter_path = textFilterPath->text(); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + filter_path = filter_path.replace("\\", "/"); +#endif + pref.setFilter(filter_path); + } + // End IPFilter preferences + // Queueing system + pref.setQueueingSystemEnabled(isQueueingSystemEnabled()); + pref.setMaxActiveDownloads(spinMaxActiveDownloads->value()); + pref.setMaxActiveUploads(spinMaxActiveUploads->value()); + pref.setMaxActiveTorrents(spinMaxActiveTorrents->value()); + // End Queueing system preferences + // Web UI + pref.setWebUiEnabled(isWebUiEnabled()); + if(isWebUiEnabled()) + { + pref.setWebUiPort(webUiPort()); + pref.setUPnPForWebUIPort(checkWebUIUPnP->isChecked()); + pref.setWebUiHttpsEnabled(checkWebUiHttps->isChecked()); + if(checkWebUiHttps->isChecked()) + { + pref.setWebUiHttpsCertificate(m_sslCert); + pref.setWebUiHttpsKey(m_sslKey); + } + pref.setWebUiUsername(webUiUsername()); + // FIXME: Check that the password is valid (not empty at least) + pref.setWebUiPassword(webUiPassword()); + pref.setWebUiLocalAuthEnabled(!checkBypassLocalAuth->isChecked()); + // DynDNS + pref.setDynDNSEnabled(checkDynDNS->isChecked()); + pref.setDynDNSService(comboDNSService->currentIndex()); + pref.setDynDomainName(domainNameTxt->text()); + pref.setDynDNSUsername(DNSUsernameTxt->text()); + pref.setDynDNSPassword(DNSPasswordTxt->text()); + } + // End Web UI + // End preferences + // Save advanced settings + advancedSettings->saveAdvancedSettings(); +} + +bool options_imp::isFilteringEnabled() const{ + return checkIPFilter->isChecked(); +} + +int options_imp::getProxyType() const{ + switch(comboProxyType->currentIndex()) { + case 1: + return Proxy::SOCKS4; + break; + case 2: + if(isProxyAuthEnabled()){ + return Proxy::SOCKS5_PW; + } + return Proxy::SOCKS5; + case 3: + if(isProxyAuthEnabled()){ + return Proxy::HTTP_PW; + } + return Proxy::HTTP; + default: + return -1; + } +} + +void options_imp::loadOptions(){ + int intValue; + qreal floatValue; + QString strValue; + // General preferences + const Preferences pref; + setLocale(pref.getLocale()); + checkAltRowColors->setChecked(pref.useAlternatingRowColors()); + checkShowSystray->setChecked(pref.systrayIntegration()); + checkShowSplash->setChecked(!pref.isSlashScreenDisabled()); + if(checkShowSystray->isChecked()) { + checkCloseToSystray->setChecked(pref.closeToTray()); + checkMinimizeToSysTray->setChecked(pref.minimizeToTray()); + checkStartMinimized->setChecked(pref.startMinimized()); + } + comboTrayIcon->setCurrentIndex(pref.trayIconStyle()); + checkProgramExitConfirm->setChecked(pref.confirmOnExit()); + checkPreventFromSuspend->setChecked(pref.preventFromSuspend()); + // End General preferences + // Downloads preferences + QString save_path = pref.getSavePath(); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + save_path = save_path.replace("/", "\\"); +#endif + textSavePath->setText(save_path); + if(pref.isTempPathEnabled()) { + // enable + checkTempFolder->setChecked(true); + } else { + checkTempFolder->setChecked(false); + } + QString temp_path = pref.getTempPath(); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + temp_path = temp_path.replace("/", "\\"); +#endif + textTempPath->setText(temp_path); + checkAppendLabel->setChecked(pref.appendTorrentLabel()); +#if LIBTORRENT_VERSION_MINOR > 14 + checkAppendqB->setChecked(pref.useIncompleteFilesExtension()); +#endif + checkPreallocateAll->setChecked(pref.preAllocateAllFiles()); + checkAdditionDialog->setChecked(pref.useAdditionDialog()); + checkStartPaused->setChecked(pref.addTorrentsInPause()); + + strValue = pref.getExportDir(); + if(strValue.isEmpty()) { + // Disable + checkExportDir->setChecked(false); + } else { + // enable + checkExportDir->setChecked(true); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + strValue = strValue.replace("/", "\\"); +#endif + textExportDir->setText(strValue); + } + groupMailNotification->setChecked(pref.isMailNotificationEnabled()); + dest_email_txt->setText(pref.getMailNotificationEmail()); + smtp_server_txt->setText(pref.getMailNotificationSMTP()); + checkSmtpSSL->setChecked(pref.getMailNotificationSMTPSSL()); + groupMailNotifAuth->setChecked(pref.getMailNotificationSMTPAuth()); + mailNotifUsername->setText(pref.getMailNotificationSMTPUsername()); + mailNotifPassword->setText(pref.getMailNotificationSMTPPassword()); + autoRunBox->setChecked(pref.isAutoRunEnabled()); + autoRun_txt->setText(pref.getAutoRunProgram()); + intValue = pref.getActionOnDblClOnTorrentDl(); + if(intValue >= actionTorrentDlOnDblClBox->count()) + intValue = 0; + actionTorrentDlOnDblClBox->setCurrentIndex(intValue); + intValue = pref.getActionOnDblClOnTorrentFn(); + if(intValue >= actionTorrentFnOnDblClBox->count()) + intValue = 1; + actionTorrentFnOnDblClBox->setCurrentIndex(intValue); + // End Downloads preferences + // Connection preferences + spinPort->setValue(pref.getSessionPort()); + checkUPnP->setChecked(pref.isUPnPEnabled()); + intValue = pref.getGlobalDownloadLimit(); + if(intValue > 0) { + // Enabled + checkDownloadLimit->setChecked(true); + spinDownloadLimit->setEnabled(true); + spinDownloadLimit->setValue(intValue); + } else { + // Disabled + checkDownloadLimit->setChecked(false); + spinDownloadLimit->setEnabled(false); + } + intValue = pref.getGlobalUploadLimit(); + if(intValue != -1) { + // Enabled + checkUploadLimit->setChecked(true); + spinUploadLimit->setEnabled(true); + spinUploadLimit->setValue(intValue); + } else { + // Disabled + checkUploadLimit->setChecked(false); + spinUploadLimit->setEnabled(false); + } + spinUploadLimitAlt->setValue(pref.getAltGlobalUploadLimit()); + spinDownloadLimitAlt->setValue(pref.getAltGlobalDownloadLimit()); + // Options + checkuTP->setChecked(pref.isuTPEnabled()); + checkLimituTPConnections->setChecked(pref.isuTPRateLimited()); + checkLimitTransportOverhead->setChecked(pref.includeOverheadInLimits()); + // Scheduler + check_schedule->setChecked(pref.isSchedulerEnabled()); + schedule_from->setTime(pref.getSchedulerStartTime()); + schedule_to->setTime(pref.getSchedulerEndTime()); + schedule_days->setCurrentIndex((int)pref.getSchedulerDays()); + + intValue = pref.getProxyType(); + switch(intValue) { + case Proxy::SOCKS4: + comboProxyType->setCurrentIndex(1); + break; + case Proxy::SOCKS5: + case Proxy::SOCKS5_PW: + comboProxyType->setCurrentIndex(2); + break; + case Proxy::HTTP: + case Proxy::HTTP_PW: + comboProxyType->setCurrentIndex(3); + break; + default: + comboProxyType->setCurrentIndex(0); + } + enableProxy(comboProxyType->currentIndex()); + //if(isProxyEnabled()) { + // Proxy is enabled, save settings + textProxyIP->setText(pref.getProxyIp()); + spinProxyPort->setValue(pref.getProxyPort()); + checkProxyPeerConnecs->setChecked(pref.proxyPeerConnections()); + checkProxyAuth->setChecked(pref.isProxyAuthEnabled()); + textProxyUsername->setText(pref.getProxyUsername()); + textProxyPassword->setText(pref.getProxyPassword()); + //} + // End Connection preferences + // Bittorrent preferences + intValue = pref.getMaxConnecs(); + if(intValue > 0) { + // enable + checkMaxConnecs->setChecked(true); + spinMaxConnec->setEnabled(true); + spinMaxConnec->setValue(intValue); + } else { + // disable + checkMaxConnecs->setChecked(false); + spinMaxConnec->setEnabled(false); + } + intValue = pref.getMaxConnecsPerTorrent(); + if(intValue > 0) { + // enable + checkMaxConnecsPerTorrent->setChecked(true); + spinMaxConnecPerTorrent->setEnabled(true); + spinMaxConnecPerTorrent->setValue(intValue); + } else { + // disable + checkMaxConnecsPerTorrent->setChecked(false); + spinMaxConnecPerTorrent->setEnabled(false); + } + intValue = pref.getMaxUploadsPerTorrent(); + if(intValue > 0) { + // enable + checkMaxUploadsPerTorrent->setChecked(true); + spinMaxUploadsPerTorrent->setEnabled(true); + spinMaxUploadsPerTorrent->setValue(intValue); + } else { + // disable + checkMaxUploadsPerTorrent->setChecked(false); + spinMaxUploadsPerTorrent->setEnabled(false); + } + checkDHT->setChecked(pref.isDHTEnabled()); + checkDifferentDHTPort->setChecked(!pref.isDHTPortSameAsBT()); + spinDHTPort->setValue(pref.getDHTPort()); + checkPeX->setChecked(pref.isPeXEnabled()); + checkLSD->setChecked(pref.isLSDEnabled()); + comboEncryption->setCurrentIndex(pref.getEncryptionSetting()); + // Ratio limit + floatValue = pref.getGlobalMaxRatio(); + if(floatValue >= 0.) { + // Enable + checkMaxRatio->setChecked(true); + spinMaxRatio->setEnabled(true); + comboRatioLimitAct->setEnabled(true); + spinMaxRatio->setValue(floatValue); + } else { + // Disable + checkMaxRatio->setChecked(false); + spinMaxRatio->setEnabled(false); + comboRatioLimitAct->setEnabled(false); + } + comboRatioLimitAct->setCurrentIndex(pref.getMaxRatioAction()); + // End Bittorrent preferences + // Misc preferences + // * IP Filter + checkIPFilter->setChecked(pref.isFilteringEnabled()); + textFilterPath->setText(pref.getFilter()); + // End IP Filter + // Queueing system preferences + checkEnableQueueing->setChecked(pref.isQueueingSystemEnabled()); + spinMaxActiveDownloads->setValue(pref.getMaxActiveDownloads()); + spinMaxActiveUploads->setValue(pref.getMaxActiveUploads()); + spinMaxActiveTorrents->setValue(pref.getMaxActiveTorrents()); + // End Queueing system preferences + // Web UI + checkWebUi->setChecked(pref.isWebUiEnabled()); + spinWebUiPort->setValue(pref.getWebUiPort()); + checkWebUIUPnP->setChecked(pref.useUPnPForWebUIPort()); + checkWebUiHttps->setChecked(pref.isWebUiHttpsEnabled()); + setSslCertificate(pref.getWebUiHttpsCertificate(), false); + setSslKey(pref.getWebUiHttpsKey(), false); + textWebUiUsername->setText(pref.getWebUiUsername()); + textWebUiPassword->setText(pref.getWebUiPassword()); + checkBypassLocalAuth->setChecked(!pref.isWebUiLocalAuthEnabled()); + // Dynamic DNS + checkDynDNS->setChecked(pref.isDynDNSEnabled()); + comboDNSService->setCurrentIndex((int)pref.getDynDNSService()); + domainNameTxt->setText(pref.getDynDomainName()); + DNSUsernameTxt->setText(pref.getDynDNSUsername()); + DNSPasswordTxt->setText(pref.getDynDNSPassword()); + // End Web UI + // Random stuff + srand(time(0)); +} + +// return min & max ports +// [min, max] +int options_imp::getPort() const{ + return spinPort->value(); +} + +void options_imp::on_randomButton_clicked() { + // Range [1024: 65535] + spinPort->setValue(rand() % 64512 + 1024); +} + +int options_imp::getEncryptionSetting() const{ + return comboEncryption->currentIndex(); +} + +int options_imp::getMaxActiveDownloads() const { + return spinMaxActiveDownloads->value(); +} + +int options_imp::getMaxActiveUploads() const { + return spinMaxActiveUploads->value(); +} + +int options_imp::getMaxActiveTorrents() const { + return spinMaxActiveTorrents->value(); +} + +bool options_imp::minimizeToTray() const{ + if(!checkShowSystray->isChecked()) return false; + return checkMinimizeToSysTray->isChecked(); +} + +bool options_imp::closeToTray() const{ + if(!checkShowSystray->isChecked()) return false; + return checkCloseToSystray->isChecked(); +} + +bool options_imp::isQueueingSystemEnabled() const { + return checkEnableQueueing->isChecked(); +} + +bool options_imp::isDHTEnabled() const{ + return checkDHT->isChecked(); +} + +bool options_imp::isLSDEnabled() const{ + return checkLSD->isChecked(); +} + +bool options_imp::isUPnPEnabled() const{ + return checkUPnP->isChecked(); +} + +// Return Download & Upload limits in kbps +// [download,upload] +QPair options_imp::getGlobalBandwidthLimits() const{ + int DL = -1, UP = -1; + if(checkDownloadLimit->isChecked()){ + DL = spinDownloadLimit->value(); + } + if(checkUploadLimit->isChecked()){ + UP = spinUploadLimit->value(); + } + return qMakePair(DL, UP); +} + +bool options_imp::startMinimized() const { + if(checkStartMinimized->isChecked()) return true; + return checkStartMinimized->isChecked(); +} + +bool options_imp::systrayIntegration() const{ + if (!QSystemTrayIcon::isSystemTrayAvailable()) return false; + return checkShowSystray->isChecked(); +} + +int options_imp::getDHTPort() const { + return spinDHTPort->value(); +} + +// Return Share ratio +qreal options_imp::getMaxRatio() const{ + if(checkMaxRatio->isChecked()){ + return spinMaxRatio->value(); + } + return -1; +} + +// Return Save Path +QString options_imp::getSavePath() const{ + if(textSavePath->text().trimmed().isEmpty()){ + QString save_path = Preferences().getSavePath(); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + save_path = save_path.replace("/", "\\"); +#endif + textSavePath->setText(save_path); + } + return misc::expandPath(textSavePath->text()); +} + +QString options_imp::getTempPath() const { + return misc::expandPath(textTempPath->text()); +} + +bool options_imp::isTempPathEnabled() const { + return checkTempFolder->isChecked(); +} + +// Return max connections number +int options_imp::getMaxConnecs() const{ + if(!checkMaxConnecs->isChecked()){ + return -1; + }else{ + return spinMaxConnec->value(); + } +} + +int options_imp::getMaxConnecsPerTorrent() const{ + if(!checkMaxConnecsPerTorrent->isChecked()){ + return -1; + }else{ + return spinMaxConnecPerTorrent->value(); + } +} + +int options_imp::getMaxUploadsPerTorrent() const{ + if(!checkMaxUploadsPerTorrent->isChecked()){ + return -1; + }else{ + return spinMaxUploadsPerTorrent->value(); + } +} + +void options_imp::on_buttonBox_accepted(){ + if(applyButton->isEnabled()){ + saveOptions(); + applyButton->setEnabled(false); + this->hide(); + emit status_changed(); + } + saveWindowState(); + accept(); +} + +void options_imp::applySettings(QAbstractButton* button) { + if(button == applyButton){ + saveOptions(); + emit status_changed(); + } +} + +void options_imp::closeEvent(QCloseEvent *e){ + setAttribute(Qt::WA_DeleteOnClose); + e->accept(); +} + +void options_imp::on_buttonBox_rejected(){ + setAttribute(Qt::WA_DeleteOnClose); + reject(); +} + +bool options_imp::useAdditionDialog() const{ + return checkAdditionDialog->isChecked(); +} + +void options_imp::enableApplyButton(){ + applyButton->setEnabled(true); +} + +void options_imp::enableProxy(int index){ + if(index){ + //enable + lblProxyIP->setEnabled(true); + textProxyIP->setEnabled(true); + lblProxyPort->setEnabled(true); + spinProxyPort->setEnabled(true); + checkProxyPeerConnecs->setEnabled(true); + if(index > 1) { + checkProxyAuth->setEnabled(true); + } else { + checkProxyAuth->setEnabled(false); + checkProxyAuth->setChecked(false); + } + }else{ + //disable + lblProxyIP->setEnabled(false); + textProxyIP->setEnabled(false); + lblProxyPort->setEnabled(false); + spinProxyPort->setEnabled(false); + checkProxyPeerConnecs->setEnabled(false); + checkProxyAuth->setEnabled(false); + checkProxyAuth->setChecked(false); + } +} + +bool options_imp::isSlashScreenDisabled() const { + return !checkShowSplash->isChecked(); +} + +bool options_imp::preventFromSuspend() const { + return checkPreventFromSuspend->isChecked(); +} + +bool options_imp::preAllocateAllFiles() const { + return checkPreallocateAll->isChecked(); +} + +bool options_imp::addTorrentsInPause() const { + return checkStartPaused->isChecked(); +} + +bool options_imp::isDHTPortSameAsBT() const { + return !checkDifferentDHTPort->isChecked(); +} + +// Proxy settings +bool options_imp::isProxyEnabled() const{ + return comboProxyType->currentIndex(); +} + +bool options_imp::isProxyAuthEnabled() const{ + return checkProxyAuth->isChecked(); +} + +QString options_imp::getProxyIp() const{ + return textProxyIP->text().trimmed(); +} + +unsigned short options_imp::getProxyPort() const{ + return spinProxyPort->value(); +} + +QString options_imp::getProxyUsername() const{ + QString username = textProxyUsername->text(); + username = username.trimmed(); + return username; +} + +QString options_imp::getProxyPassword() const{ + QString password = textProxyPassword->text(); + password = password.trimmed(); + return password; +} + +// Locale Settings +QString options_imp::getLocale() const{ + return comboI18n->itemData(comboI18n->currentIndex(), Qt::UserRole).toString(); +} + +void options_imp::setLocale(const QString &localeStr) { + QLocale locale(localeStr); + // Attempt to find exact match + int index = comboI18n->findData(locale.name(), Qt::UserRole); + if(index < 0) { + // Unreconized, use US English + index = comboI18n->findData(QLocale("en").name(), Qt::UserRole); + Q_ASSERT(index >= 0); + } + comboI18n->setCurrentIndex(index); +} + +QString options_imp::getExportDir() const { + if(checkExportDir->isChecked()) + return misc::expandPath(textExportDir->text()); + return QString(); +} + +// Return action on double-click on a downloading torrent set in options +int options_imp::getActionOnDblClOnTorrentDl() const { + if(actionTorrentDlOnDblClBox->currentIndex() < 1) + return 0; + return actionTorrentDlOnDblClBox->currentIndex(); +} + +// Return action on double-click on a finished torrent set in options +int options_imp::getActionOnDblClOnTorrentFn() const { + if(actionTorrentFnOnDblClBox->currentIndex() < 1) + return 0; + return actionTorrentFnOnDblClBox->currentIndex(); +} + +void options_imp::on_addScanFolderButton_clicked() { + const QString dir = QFileDialog::getExistingDirectory(this, tr("Add directory to scan")); + if (!dir.isEmpty()) { + const ScanFoldersModel::PathStatus status = ScanFoldersModel::instance()->addPath(dir, false); + QString error; + switch (status) { + case ScanFoldersModel::AlreadyInList: + error = tr("Folder is already being watched.").arg(dir); + break; + case ScanFoldersModel::DoesNotExist: + error = tr("Folder does not exist."); + break; + case ScanFoldersModel::CannotRead: + error = tr("Folder is not readable."); + break; + default: + addedScanDirs << dir; + enableApplyButton(); + } + + if (!error.isEmpty()) { + QMessageBox::warning(this, tr("Failure"), tr("Failed to add Scan Folder '%1': %2").arg(dir).arg(error)); + } + } +} + +void options_imp::on_removeScanFolderButton_clicked() { + const QModelIndexList selected + = scanFoldersView->selectionModel()->selectedIndexes(); + if (selected.isEmpty()) + return; + Q_ASSERT(selected.count() == ScanFoldersModel::instance()->columnCount()); + ScanFoldersModel::instance()->removePath(selected.first().row()); +} + +void options_imp::handleScanFolderViewSelectionChanged() { + removeScanFolderButton->setEnabled(!scanFoldersView->selectionModel()->selectedIndexes().isEmpty()); +} + +void options_imp::on_browseExportDirButton_clicked() { + const QString export_path = misc::expandPath(textExportDir->text()); + QDir exportDir(export_path); + QString dir; + if(!export_path.isEmpty() && exportDir.exists()) { + dir = QFileDialog::getExistingDirectory(this, tr("Choose export directory"), exportDir.absolutePath()); + } else { + dir = QFileDialog::getExistingDirectory(this, tr("Choose export directory"), QDir::homePath()); + } + if(!dir.isNull()){ +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + dir = dir.replace("/", "\\"); +#endif + textExportDir->setText(dir); + } +} + +void options_imp::on_browseFilterButton_clicked() { + const QString filter_path = misc::expandPath(textFilterPath->text()); + QDir filterDir(filter_path); + QString ipfilter; + if(!filter_path.isEmpty() && filterDir.exists()) { + ipfilter = QFileDialog::getOpenFileName(this, tr("Choose an ip filter file"), filterDir.absolutePath(), tr("Filters")+QString(" (*.dat *.p2p *.p2b)")); + } else { + ipfilter = QFileDialog::getOpenFileName(this, tr("Choose an ip filter file"), QDir::homePath(), tr("Filters")+QString(" (*.dat *.p2p *.p2b)")); + } + if(!ipfilter.isNull()){ +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + ipfilter = ipfilter.replace("/", "\\"); +#endif + textFilterPath->setText(ipfilter); + } +} + +// Display dialog to choose save dir +void options_imp::on_browseSaveDirButton_clicked(){ + const QString save_path = misc::expandPath(textSavePath->text()); + QDir saveDir(save_path); + QString dir; + if(!save_path.isEmpty() && saveDir.exists()) { + dir = QFileDialog::getExistingDirectory(this, tr("Choose a save directory"), saveDir.absolutePath()); + } else { + dir = QFileDialog::getExistingDirectory(this, tr("Choose a save directory"), QDir::homePath()); + } + if(!dir.isNull()){ +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + dir = dir.replace("/", "\\"); +#endif + textSavePath->setText(dir); + } +} + +void options_imp::on_browseTempDirButton_clicked(){ + const QString temp_path = misc::expandPath(textTempPath->text()); + QDir tempDir(temp_path); + QString dir; + if(!temp_path.isEmpty() && tempDir.exists()) { + dir = QFileDialog::getExistingDirectory(this, tr("Choose a save directory"), tempDir.absolutePath()); + } else { + dir = QFileDialog::getExistingDirectory(this, tr("Choose a save directory"), QDir::homePath()); + } + if(!dir.isNull()){ +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + dir = dir.replace("/", "\\"); +#endif + textTempPath->setText(dir); + } +} + +// Return Filter object to apply to BT session +QString options_imp::getFilter() const{ + return textFilterPath->text(); +} + +// Web UI + +bool options_imp::isWebUiEnabled() const +{ + return checkWebUi->isChecked(); +} + +quint16 options_imp::webUiPort() const +{ + return spinWebUiPort->value(); +} + +QString options_imp::webUiUsername() const +{ + return textWebUiUsername->text(); +} + +QString options_imp::webUiPassword() const +{ + return textWebUiPassword->text(); +} + +void options_imp::showConnectionTab() +{ + tabSelection->setCurrentRow(2); +} + +void options_imp::on_btnWebUiCrt_clicked() { + QString filename = QFileDialog::getOpenFileName(this, QString(), QString(), tr("SSL Certificate (*.crt *.pem)")); + if(filename.isNull()) + return; + QFile file(filename); + if (file.open(QIODevice::ReadOnly)) { + setSslCertificate(file.readAll()); + file.close(); + } +} + +void options_imp::on_btnWebUiKey_clicked() { + QString filename = QFileDialog::getOpenFileName(this, QString(), QString(), tr("SSL Key (*.key *.pem)")); + if(filename.isNull()) + return; + QFile file(filename); + if (file.open(QIODevice::ReadOnly)) { + setSslKey(file.readAll()); + file.close(); + } +} + +void options_imp::on_registerDNSBtn_clicked() { + QDesktopServices::openUrl(DNSUpdater::getRegistrationUrl(comboDNSService->currentIndex())); +} + +void options_imp::on_IpFilterRefreshBtn_clicked() { + if(m_refreshingIpFilter) return; + m_refreshingIpFilter = true; + // Updating program preferences + Preferences pref; + pref.setFilteringEnabled(true); + pref.setFilter(getFilter()); + // Force refresh + connect(QBtSession::instance(), SIGNAL(ipFilterParsed(bool, int)), SLOT(handleIPFilterParsed(bool, int))); + setCursor(QCursor(Qt::WaitCursor)); + QBtSession::instance()->enableIPFilter(getFilter(), true); +} + +void options_imp::handleIPFilterParsed(bool error, int ruleCount) +{ + setCursor(QCursor(Qt::ArrowCursor)); + if(error) { + QMessageBox::warning(this, tr("Parsing error"), tr("Failed to parse the provided IP filter")); + } else { + QMessageBox::information(this, tr("Successfully refreshed"), tr("Successfuly parsed the provided IP filter: %1 rules were applied.", "%1 is a number").arg(ruleCount)); + } + m_refreshingIpFilter = false; + disconnect(QBtSession::instance(), SIGNAL(ipFilterParsed(bool, int)), this, SLOT(handleIPFilterParsed(bool, int))); +} + +QString options_imp::languageToLocalizedString(QLocale::Language language, const QString& country) +{ + switch(language) { + case QLocale::English: return "English"; + case QLocale::French: return QString::fromUtf8("Français"); + case QLocale::German: return QString::fromUtf8("Deutsch"); + case QLocale::Hungarian: return QString::fromUtf8("Magyar"); + case QLocale::Italian: return QString::fromUtf8("Italiano"); + case QLocale::Dutch: return QString::fromUtf8("Nederlands"); + case QLocale::Spanish: return QString::fromUtf8("Español"); + case QLocale::Catalan: return QString::fromUtf8("Català"); + case QLocale::Galician: return QString::fromUtf8("Galego"); + case QLocale::Portuguese: { + if(country == "br") + return QString::fromUtf8("Português brasileiro"); + return QString::fromUtf8("Português"); + } + case QLocale::Polish: return QString::fromUtf8("Polski"); + case QLocale::Lithuanian: return QString::fromUtf8("Lietuvių"); + case QLocale::Czech: return QString::fromUtf8("Čeština"); + case QLocale::Slovak: return QString::fromUtf8("Slovenčina"); + case QLocale::Serbian: return QString::fromUtf8("Српски"); + case QLocale::Croatian: return QString::fromUtf8("Hrvatski"); + case QLocale::Armenian: return QString::fromUtf8("Հայերեն"); + case QLocale::Romanian: return QString::fromUtf8("Română"); + case QLocale::Turkish: return QString::fromUtf8("Türkçe"); + case QLocale::Greek: return QString::fromUtf8("Ελληνικά"); + case QLocale::Swedish: return QString::fromUtf8("Svenska"); + case QLocale::Finnish: return QString::fromUtf8("Suomi"); + case QLocale::Norwegian: return QString::fromUtf8("Norsk"); + case QLocale::Danish: return QString::fromUtf8("Dansk"); + case QLocale::Bulgarian: return QString::fromUtf8("Български"); + case QLocale::Ukrainian: return QString::fromUtf8("Українська"); + case QLocale::Russian: return QString::fromUtf8("Русский"); + case QLocale::Japanese: return QString::fromUtf8("日本語"); + case QLocale::Arabic: return QString::fromUtf8("عربي"); + case QLocale::Chinese: { + if(country == "cn") + return QString::fromUtf8("中文 (简体)"); + return QString::fromUtf8("中文 (繁體)"); + } + case QLocale::Korean: return QString::fromUtf8("한글"); + default: { + // Fallback to English + const QString eng_lang = QLocale::languageToString(language); + qWarning() << "Unrecognized language name: " << eng_lang; + return eng_lang; + } + } +} + +void options_imp::setSslKey(const QByteArray &key, bool interactive) +{ +#ifndef QT_NO_OPENSSL + if (!key.isEmpty() && !QSslKey(key, QSsl::Rsa).isNull()) { + lblSslKeyStatus->setPixmap(QPixmap(":/Icons/oxygen/security-high.png").scaledToHeight(20, Qt::SmoothTransformation)); + m_sslKey = key; + } else { + lblSslKeyStatus->setPixmap(QPixmap(":/Icons/oxygen/security-low.png").scaledToHeight(20, Qt::SmoothTransformation)); + m_sslKey.clear(); + if (interactive) + QMessageBox::warning(this, tr("Invalid key"), tr("This is not a valid SSL key.")); + } +#endif +} + +void options_imp::setSslCertificate(const QByteArray &cert, bool interactive) +{ +#ifndef QT_NO_OPENSSL + if (!cert.isEmpty() && !QSslCertificate(cert).isNull()) { + lblSslCertStatus->setPixmap(QPixmap(":/Icons/oxygen/security-high.png").scaledToHeight(20, Qt::SmoothTransformation)); + m_sslCert = cert; + } else { + lblSslCertStatus->setPixmap(QPixmap(":/Icons/oxygen/security-low.png").scaledToHeight(20, Qt::SmoothTransformation)); + m_sslCert.clear(); + if (interactive) + QMessageBox::warning(this, tr("Invalid certificate"), tr("This is not a valid SSL certificate.")); + } +#endif +} diff --git a/src/preferences/options_imp.h b/src/preferences/options_imp.h new file mode 100644 index 000000000..fa354c773 --- /dev/null +++ b/src/preferences/options_imp.h @@ -0,0 +1,163 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef OPTIONS_IMP_H +#define OPTIONS_IMP_H + +#include "ui_options.h" +#include + +// actions on double-click on torrents +enum DoubleClickAction {TOGGLE_PAUSE, OPEN_DEST, NO_ACTION}; + +class AdvancedSettings; + +QT_BEGIN_NAMESPACE +class QCloseEvent; +QT_END_NAMESPACE + +class options_imp : public QDialog, private Ui_Preferences { + Q_OBJECT +private: + enum Tabs {TAB_UI, TAB_DOWNLOADS, TAB_CONNECTION, TAB_SPEED, TAB_BITTORRENT, TAB_WEBUI, TAB_ADVANCED}; + +public: + // Contructor / Destructor + options_imp(QWidget *parent=0); + ~options_imp(); + +public slots: + void showConnectionTab(); + +signals: + void status_changed() const; + void exitWithCancel(); + +private slots: + void enableProxy(int comboIndex); + void on_buttonBox_accepted(); + void closeEvent(QCloseEvent *e); + void on_buttonBox_rejected(); + void applySettings(QAbstractButton* button); + void enableApplyButton(); + void changePage(QListWidgetItem*, QListWidgetItem*); + void loadWindowState(); + void saveWindowState() const; + void handleScanFolderViewSelectionChanged(); + void on_IpFilterRefreshBtn_clicked(); + void handleIPFilterParsed(bool error, int ruleCount); + void on_browseExportDirButton_clicked(); + void on_browseFilterButton_clicked(); + void on_browseSaveDirButton_clicked(); + void on_browseTempDirButton_clicked(); + void on_randomButton_clicked(); + void on_addScanFolderButton_clicked(); + void on_removeScanFolderButton_clicked(); + void on_btnWebUiCrt_clicked(); + void on_btnWebUiKey_clicked(); + void on_registerDNSBtn_clicked(); + void setLocale(const QString &locale); + +private: + // Methods + void saveOptions(); + void loadOptions(); + void initializeLanguageCombo(); + static QString languageToLocalizedString(QLocale::Language language, const QString& country); + // General options + QString getLocale() const; + bool systrayIntegration() const; + bool minimizeToTray() const; + bool closeToTray() const; + bool startMinimized() const; + bool isSlashScreenDisabled() const; + bool preventFromSuspend() const; + // Downloads + QString getSavePath() const; + bool isTempPathEnabled() const; + QString getTempPath() const; + bool preAllocateAllFiles() const; + bool useAdditionDialog() const; + bool addTorrentsInPause() const; + QString getExportDir() const; + int getActionOnDblClOnTorrentDl() const; + int getActionOnDblClOnTorrentFn() const; + // Connection options + int getPort() const; + bool isUPnPEnabled() const; + QPair getGlobalBandwidthLimits() const; + // Bittorrent options + int getMaxConnecs() const; + int getMaxConnecsPerTorrent() const; + int getMaxUploadsPerTorrent() const; + bool isDHTEnabled() const; + bool isDHTPortSameAsBT() const; + int getDHTPort() const; + bool isLSDEnabled() const; + int getEncryptionSetting() const; + qreal getMaxRatio() const; + // Proxy options + bool isProxyEnabled() const; + bool isProxyAuthEnabled() const; + QString getProxyIp() const; + unsigned short getProxyPort() const; + QString getProxyUsername() const; + QString getProxyPassword() const; + int getProxyType() const; + // IP Filter + bool isFilteringEnabled() const; + QString getFilter() const; + bool m_refreshingIpFilter; + // Queueing system + bool isQueueingSystemEnabled() const; + int getMaxActiveDownloads() const; + int getMaxActiveUploads() const; + int getMaxActiveTorrents() const; + bool isWebUiEnabled() const; + quint16 webUiPort() const; + QString webUiUsername() const; + QString webUiPassword() const; + QSize sizeFittingScreen() const; + +private: + void setSslKey(const QByteArray &key, bool interactive = true); + void setSslCertificate(const QByteArray &cert, bool interactive = true); + +private: + QButtonGroup choiceLanguage; + QAbstractButton *applyButton; + AdvancedSettings *advancedSettings; + QList addedScanDirs; + // SSL Cert / key + QByteArray m_sslCert, m_sslKey; + +}; + +#endif diff --git a/src/preferences/preferences.h b/src/preferences/preferences.h new file mode 100644 index 000000000..57849b8b2 --- /dev/null +++ b/src/preferences/preferences.h @@ -0,0 +1,1186 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PREFERENCES_H +#define PREFERENCES_H + +#include +#include +#include +#include +#include +#include +#include + +#ifndef DISABLE_GUI +#include +#else +#include +#endif + +#ifdef Q_WS_WIN +#include +#endif + +#include "misc.h" +#include "qinisettings.h" + +#define QBT_REALM "Web UI Access" +enum scheduler_days { EVERY_DAY, WEEK_DAYS, WEEK_ENDS, MON, TUE, WED, THU, FRI, SAT, SUN }; +enum maxRatioAction {PAUSE_ACTION, REMOVE_ACTION}; +namespace Proxy { +enum ProxyType {HTTP=1, SOCKS5=2, HTTP_PW=3, SOCKS5_PW=4, SOCKS4=5}; +} +namespace TrayIcon { +enum Style { NORMAL = 0, MONO_DARK, MONO_LIGHT }; +} +namespace DNS { +enum Service { DYNDNS, NOIP, NONE = -1 }; +} + +class Preferences : public QIniSettings { + Q_DISABLE_COPY(Preferences); + +public: + Preferences() : QIniSettings("qBittorrent", "qBittorrent") { + qDebug() << "Preferences constructor"; + } + +public: + // General options + QString getLocale() const { + return value(QString::fromUtf8("Preferences/General/Locale"), "en_GB").toString(); + } + + void setLocale(const QString &locale) { + setValue(QString::fromUtf8("Preferences/General/Locale"), locale); + } + + bool useProgramNotification() const { + return value(QString::fromUtf8("Preferences/General/ProgramNotification"), true).toBool(); + } + + void useProgramNotification(bool use) { + setValue(QString::fromUtf8("Preferences/General/ProgramNotification"), use); + } + + bool deleteTorrentFilesAsDefault() const { + return value(QString::fromUtf8("Preferences/General/DeleteTorrentsFilesAsDefault"), false).toBool(); + } + + void setDeleteTorrentFilesAsDefault(bool del) { + setValue(QString::fromUtf8("Preferences/General/DeleteTorrentsFilesAsDefault"), del); + } + + void setConfirmOnExit(bool confirm) { + setValue(QString::fromUtf8("Preferences/General/ExitConfirm"), confirm); + } + + bool confirmOnExit() const { + return value(QString::fromUtf8("Preferences/General/ExitConfirm"), true).toBool(); + } + + void showSpeedInTitleBar(bool show) { + setValue(QString::fromUtf8("Preferences/General/SpeedInTitleBar"), show); + } + + bool speedInTitleBar() const { + return value(QString::fromUtf8("Preferences/General/SpeedInTitleBar"), false).toBool(); + } + + bool useAlternatingRowColors() const { + return value(QString::fromUtf8("Preferences/General/AlternatingRowColors"), true).toBool(); + } + + void setAlternatingRowColors(bool b) { + setValue("Preferences/General/AlternatingRowColors", b); + } + + bool systrayIntegration() const { + return value(QString::fromUtf8("Preferences/General/SystrayEnabled"), true).toBool(); + } + + void setSystrayIntegration(bool enabled) { + setValue(QString::fromUtf8("Preferences/General/SystrayEnabled"), enabled); + } + + void setToolbarDisplayed(bool displayed) { + setValue(QString::fromUtf8("Preferences/General/ToolbarDisplayed"), displayed); + } + + bool isToolbarDisplayed() const { + return value(QString::fromUtf8("Preferences/General/ToolbarDisplayed"), true).toBool(); + } + + bool minimizeToTray() const { + return value(QString::fromUtf8("Preferences/General/MinimizeToTray"), false).toBool(); + } + + void setMinimizeToTray(bool b) { + setValue("Preferences/General/MinimizeToTray", b); + } + + bool closeToTray() const { + return value(QString::fromUtf8("Preferences/General/CloseToTray"), false).toBool(); + } + + void setCloseToTray(bool b) { + setValue("Preferences/General/CloseToTray", b); + } + + bool startMinimized() const { + return value(QString::fromUtf8("Preferences/General/StartMinimized"), false).toBool(); + } + + void setStartMinimized(bool b) { + setValue("Preferences/General/StartMinimized", b); + } + + bool isSlashScreenDisabled() const { + return value(QString::fromUtf8("Preferences/General/NoSplashScreen"), false).toBool(); + } + + void setSplashScreenDisabled(bool b) { + setValue("Preferences/General/NoSplashScreen", b); + } + + // Preventing from system suspend while active torrents are presented. + bool preventFromSuspend() const { + return value(QString::fromUtf8("Preferences/General/PreventFromSuspend"), false).toBool(); + } + + void setPreventFromSuspend(bool b) { + setValue("Preferences/General/PreventFromSuspend", b); + } + + // Downloads + QString getSavePath() const { +#ifdef Q_WS_WIN + return value(QString::fromUtf8("Preferences/Downloads/SavePath"), + QDir(QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation)).absoluteFilePath("Downloads")).toString(); +#else + return value(QString::fromUtf8("Preferences/Downloads/SavePath"), QDir::home().absoluteFilePath("qBT_dir")).toString(); +#endif + } + + void setSavePath(const QString &save_path) { + setValue(QString::fromUtf8("Preferences/Downloads/SavePath"), save_path); + } + + bool isTempPathEnabled() const { + return value(QString::fromUtf8("Preferences/Downloads/TempPathEnabled"), false).toBool(); + } + + void setTempPathEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/Downloads/TempPathEnabled"), enabled); + } + + QString getTempPath() const { + const QString temp = QDir(getSavePath()).absoluteFilePath("temp"); + return value(QString::fromUtf8("Preferences/Downloads/TempPath"), temp).toString(); + } + + void setTempPath(const QString &path) { + setValue(QString::fromUtf8("Preferences/Downloads/TempPath"), path); + } + +#if LIBTORRENT_VERSION_MINOR > 14 + bool useIncompleteFilesExtension() const { + return value(QString::fromUtf8("Preferences/Downloads/UseIncompleteExtension"), false).toBool(); + } + + void useIncompleteFilesExtension(bool enabled) { + setValue(QString::fromUtf8("Preferences/Downloads/UseIncompleteExtension"), enabled); + } +#endif + + bool appendTorrentLabel() const { + return value(QString::fromUtf8("Preferences/Downloads/AppendLabel"), false).toBool(); + } + + void setAppendTorrentLabel(bool b) { + setValue("Preferences/Downloads/AppendLabel", b); + } + + bool preAllocateAllFiles() const { + return value(QString::fromUtf8("Preferences/Downloads/PreAllocation"), false).toBool(); + } + + void preAllocateAllFiles(bool enabled) { + return setValue(QString::fromUtf8("Preferences/Downloads/PreAllocation"), enabled); + } + + bool useAdditionDialog() const { + return value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), false).toBool(); + } + + void useAdditionDialog(bool b) { + setValue("Preferences/Downloads/AdditionDialog", b); + } + + bool addTorrentsInPause() const { + return value(QString::fromUtf8("Preferences/Downloads/StartInPause"), false).toBool(); + } + + void addTorrentsInPause(bool b) { + setValue("Preferences/Downloads/StartInPause", b); + } + + QStringList getScanDirs() const { + return value(QString::fromUtf8("Preferences/Downloads/ScanDirs"), QStringList()).toStringList(); + } + + // This must be called somewhere with data from the model + void setScanDirs(const QStringList &dirs) { + setValue(QString::fromUtf8("Preferences/Downloads/ScanDirs"), dirs); + } + + QList getDownloadInScanDirs() const { + return misc::boolListfromStringList(value(QString::fromUtf8("Preferences/Downloads/DownloadInScanDirs")).toStringList()); + } + + void setDownloadInScanDirs(const QList &list) { + setValue(QString::fromUtf8("Preferences/Downloads/DownloadInScanDirs"), misc::toStringList(list)); + } + + bool isTorrentExportEnabled() const { + return !value(QString::fromUtf8("Preferences/Downloads/TorrentExport"), QString()).toString().isEmpty(); + } + + QString getExportDir() const { + return value(QString::fromUtf8("Preferences/Downloads/TorrentExport"), QString()).toString(); + } + + void setExportDir(QString path) { + path = path.trimmed(); + if(path.isEmpty()) + path = QString(); + setValue(QString::fromUtf8("Preferences/Downloads/TorrentExport"), path); + } + + bool isMailNotificationEnabled() const { + return value(QString::fromUtf8("Preferences/MailNotification/enabled"), false).toBool(); + } + + void setMailNotificationEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/MailNotification/enabled"), enabled); + } + + QString getMailNotificationEmail() const { + return value(QString::fromUtf8("Preferences/MailNotification/email"), "").toString(); + } + + void setMailNotificationEmail(const QString &mail) { + setValue(QString::fromUtf8("Preferences/MailNotification/email"), mail); + } + + QString getMailNotificationSMTP() const { + return value(QString::fromUtf8("Preferences/MailNotification/smtp_server"), "smtp.changeme.com").toString(); + } + + void setMailNotificationSMTP(const QString &smtp_server) { + setValue(QString::fromUtf8("Preferences/MailNotification/smtp_server"), smtp_server); + } + + bool getMailNotificationSMTPSSL() const { + return value(QString::fromUtf8("Preferences/MailNotification/req_ssl"), false).toBool(); + } + + void setMailNotificationSMTPSSL(bool use) { + setValue(QString::fromUtf8("Preferences/MailNotification/req_ssl"), use); + } + + bool getMailNotificationSMTPAuth() const { + return value(QString::fromUtf8("Preferences/MailNotification/req_auth"), false).toBool(); + } + + void setMailNotificationSMTPAuth(bool use) { + setValue(QString::fromUtf8("Preferences/MailNotification/req_auth"), use); + } + + QString getMailNotificationSMTPUsername() const { + return value(QString::fromUtf8("Preferences/MailNotification/username")).toString(); + } + + void setMailNotificationSMTPUsername(const QString &username) { + setValue(QString::fromUtf8("Preferences/MailNotification/username"), username); + } + + QString getMailNotificationSMTPPassword() const { + return value(QString::fromUtf8("Preferences/MailNotification/password")).toString(); + } + + void setMailNotificationSMTPPassword(const QString &password) { + setValue(QString::fromUtf8("Preferences/MailNotification/password"), password); + } + + int getActionOnDblClOnTorrentDl() const { + return value(QString::fromUtf8("Preferences/Downloads/DblClOnTorDl"), 0).toInt(); + } + + void setActionOnDblClOnTorrentDl(int act) { + setValue("Preferences/Downloads/DblClOnTorDl", act); + } + + int getActionOnDblClOnTorrentFn() const { + return value(QString::fromUtf8("Preferences/Downloads/DblClOnTorFn"), 1).toInt(); + } + + void setActionOnDblClOnTorrentFn(int act) { + setValue("Preferences/Downloads/DblClOnTorFn", act); + } + + // Connection options + int getSessionPort() const { + return value(QString::fromUtf8("Preferences/Connection/PortRangeMin"), 6881).toInt(); + } + + void setSessionPort(int port) { + setValue(QString::fromUtf8("Preferences/Connection/PortRangeMin"), port); + } + + bool isUPnPEnabled() const { + return value(QString::fromUtf8("Preferences/Connection/UPnP"), true).toBool(); + } + + void setUPnPEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/Connection/UPnP"), enabled); + } + + int getGlobalDownloadLimit() const { + return value("Preferences/Connection/GlobalDLLimit", -1).toInt(); + } + + void setGlobalDownloadLimit(int limit) { + if(limit <= 0) limit = -1; + setValue("Preferences/Connection/GlobalDLLimit", limit); + } + + int getGlobalUploadLimit() const { + return value("Preferences/Connection/GlobalUPLimit", 50).toInt(); + } + + void setGlobalUploadLimit(int limit) { + if(limit <= 0) limit = -1; + setValue("Preferences/Connection/GlobalUPLimit", limit); + } + + int getAltGlobalDownloadLimit() const { + int ret = value(QString::fromUtf8("Preferences/Connection/GlobalDLLimitAlt"), 10).toInt(); + if(ret <= 0) + ret = 10; + return ret; + } + + void setAltGlobalDownloadLimit(int limit) { + if(limit <= 0) limit = -1; + setValue("Preferences/Connection/GlobalDLLimitAlt", limit); + } + + int getAltGlobalUploadLimit() const { + int ret = value(QString::fromUtf8("Preferences/Connection/GlobalUPLimitAlt"), 10).toInt(); + if(ret <= 0) + ret = 10; + return ret; + } + + void setAltGlobalUploadLimit(int limit) { + if(limit <= 0) limit = -1; + setValue("Preferences/Connection/GlobalUPLimitAlt", limit); + } + + bool isAltBandwidthEnabled() const { + return value("Preferences/Connection/alt_speeds_on", false).toBool(); + } + + void setAltBandwidthEnabled(bool enabled) { + setValue("Preferences/Connection/alt_speeds_on", enabled); + } + + void setSchedulerEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/Scheduler/Enabled"), enabled); + } + + bool isSchedulerEnabled() const { + return value(QString::fromUtf8("Preferences/Scheduler/Enabled"), false).toBool(); + } + + QTime getSchedulerStartTime() const { + return value(QString::fromUtf8("Preferences/Scheduler/start_time"), QTime(8,0)).toTime(); + } + + void setSchedulerStartTime(const QTime &time) { + setValue(QString::fromUtf8("Preferences/Scheduler/start_time"), time); + } + + QTime getSchedulerEndTime() const { + return value(QString::fromUtf8("Preferences/Scheduler/end_time"), QTime(20,0)).toTime(); + } + + void setSchedulerEndTime(const QTime &time) { + setValue(QString::fromUtf8("Preferences/Scheduler/end_time"), time); + } + + scheduler_days getSchedulerDays() const { + return (scheduler_days)value(QString::fromUtf8("Preferences/Scheduler/days"), EVERY_DAY).toInt(); + } + + void setSchedulerDays(scheduler_days days) { + setValue(QString::fromUtf8("Preferences/Scheduler/days"), (int)days); + } + + // Proxy options + bool isProxyEnabled() const { + return value(QString::fromUtf8("Preferences/Connection/ProxyType"), 0).toInt() > 0; + } + + bool isProxyAuthEnabled() const { + return value(QString::fromUtf8("Preferences/Connection/Proxy/Authentication"), false).toBool(); + } + + void setProxyAuthEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/Connection/Proxy/Authentication"), enabled); + } + + QString getProxyIp() const { + return value(QString::fromUtf8("Preferences/Connection/Proxy/IP"), "0.0.0.0").toString(); + } + + void setProxyIp(const QString &ip) { + setValue(QString::fromUtf8("Preferences/Connection/Proxy/IP"), ip); + } + + unsigned short getProxyPort() const { + return value(QString::fromUtf8("Preferences/Connection/Proxy/Port"), 8080).toInt(); + } + + void setProxyPort(unsigned short port) { + setValue(QString::fromUtf8("Preferences/Connection/Proxy/Port"), port); + } + + QString getProxyUsername() const { + return value(QString::fromUtf8("Preferences/Connection/Proxy/Username"), QString()).toString(); + } + + void setProxyUsername(const QString &username) { + setValue(QString::fromUtf8("Preferences/Connection/Proxy/Username"), username); + } + + QString getProxyPassword() const { + return value(QString::fromUtf8("Preferences/Connection/Proxy/Password"), QString()).toString(); + } + + void setProxyPassword(const QString &password) { + setValue(QString::fromUtf8("Preferences/Connection/Proxy/Password"), password); + } + + int getProxyType() const { + return value(QString::fromUtf8("Preferences/Connection/ProxyType"), 0).toInt(); + } + + void setProxyType(int type) { + setValue(QString::fromUtf8("Preferences/Connection/ProxyType"), type); + } + + void setProxyPeerConnections(bool enabled) { + setValue(QString::fromUtf8("Preferences/Connection/ProxyPeerConnections"), enabled); + } + + bool proxyPeerConnections() const { + return value(QString::fromUtf8("Preferences/Connection/ProxyPeerConnections"), false).toBool(); + } + + // Bittorrent options + int getMaxConnecs() const { + return value(QString::fromUtf8("Preferences/Bittorrent/MaxConnecs"), 500).toInt(); + } + + void setMaxConnecs(int val) { + if(val <= 0) val = -1; + setValue(QString::fromUtf8("Preferences/Bittorrent/MaxConnecs"), val); + } + + int getMaxConnecsPerTorrent() const { + return value(QString::fromUtf8("Preferences/Bittorrent/MaxConnecsPerTorrent"), 100).toInt(); + } + + void setMaxConnecsPerTorrent(int val) { + if(val <= 0) val = -1; + setValue(QString::fromUtf8("Preferences/Bittorrent/MaxConnecsPerTorrent"), val); + } + + int getMaxUploadsPerTorrent() const { + return value(QString::fromUtf8("Preferences/Bittorrent/MaxUploadsPerTorrent"), 4).toInt(); + } + + void setMaxUploadsPerTorrent(int val) { + if(val <= 0) val = -1; + setValue(QString::fromUtf8("Preferences/Bittorrent/MaxUploadsPerTorrent"), val); + } + + bool isuTPEnabled() const { + return value(QString::fromUtf8("Preferences/Bittorrent/uTP"), true).toBool(); + } + + void setuTPEnabled(bool enabled) { + setValue("Preferences/Bittorrent/uTP", enabled); + } + + bool isuTPRateLimited() const { + return value(QString::fromUtf8("Preferences/Bittorrent/uTP_rate_limiting"), false).toBool(); + } + + void setuTPRateLimited(bool enabled) { + setValue("Preferences/Bittorrent/uTP_rate_limiting", enabled); + } + + bool isDHTEnabled() const { + return value(QString::fromUtf8("Preferences/Bittorrent/DHT"), true).toBool(); + } + + void setDHTEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/Bittorrent/DHT"), enabled); + } + + bool isPeXEnabled() const { + return value(QString::fromUtf8("Preferences/Bittorrent/PeX"), true).toBool(); + } + + void setPeXEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/Bittorrent/PeX"), enabled); + } + + bool isDHTPortSameAsBT() const { + return value(QString::fromUtf8("Preferences/Bittorrent/sameDHTPortAsBT"), true).toBool(); + } + + void setDHTPortSameAsBT(bool same) { + setValue(QString::fromUtf8("Preferences/Bittorrent/sameDHTPortAsBT"), same); + } + + int getDHTPort() const { + return value(QString::fromUtf8("Preferences/Bittorrent/DHTPort"), 6881).toInt(); + } + + void setDHTPort(int port) { + setValue(QString::fromUtf8("Preferences/Bittorrent/DHTPort"), port); + } + + bool isLSDEnabled() const { + return value(QString::fromUtf8("Preferences/Bittorrent/LSD"), true).toBool(); + } + + void setLSDEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/Bittorrent/LSD"), enabled); + } + + int getEncryptionSetting() const { + return value(QString::fromUtf8("Preferences/Bittorrent/Encryption"), 0).toInt(); + } + + void setEncryptionSetting(int val) { + setValue(QString::fromUtf8("Preferences/Bittorrent/Encryption"), val); + } + + qreal getGlobalMaxRatio() const { + return value(QString::fromUtf8("Preferences/Bittorrent/MaxRatio"), -1).toDouble(); + } + + void setGlobalMaxRatio(qreal ratio) { + setValue(QString::fromUtf8("Preferences/Bittorrent/MaxRatio"), ratio); + } + + void setMaxRatioAction(int act) { + setValue(QString::fromUtf8("Preferences/Bittorrent/MaxRatioAction"), act); + } + + int getMaxRatioAction() const { + return value(QString::fromUtf8("Preferences/Bittorrent/MaxRatioAction"), PAUSE_ACTION).toInt(); + } + + // IP Filter + bool isFilteringEnabled() const { + return value(QString::fromUtf8("Preferences/IPFilter/Enabled"), false).toBool(); + } + + void setFilteringEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/IPFilter/Enabled"), enabled); + } + + QString getFilter() const { + return value(QString::fromUtf8("Preferences/IPFilter/File"), QString()).toString(); + } + + void setFilter(const QString &path) { + setValue(QString::fromUtf8("Preferences/IPFilter/File"), path); + } + + void banIP(const QString &ip) { + QStringList banned_ips = value(QString::fromUtf8("Preferences/IPFilter/BannedIPs"), QStringList()).toStringList(); + if(!banned_ips.contains(ip)) { + banned_ips << ip; + setValue("Preferences/IPFilter/BannedIPs", banned_ips); + } + } + + QStringList bannedIPs() const { + return value(QString::fromUtf8("Preferences/IPFilter/BannedIPs"), QStringList()).toStringList(); + } + + // Search + bool isSearchEnabled() const { + return value(QString::fromUtf8("Preferences/Search/SearchEnabled"), true).toBool(); + } + + void setSearchEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/Search/SearchEnabled"), enabled); + } + + // Execution Log + + bool isExecutionLogEnabled() const { + return value(QString::fromUtf8("Preferences/ExecutionLog/enabled"), false).toBool(); + } + + void setExecutionLogEnabled(bool b) { + setValue(QString::fromUtf8("Preferences/ExecutionLog/enabled"), b); + } + + // Queueing system + bool isQueueingSystemEnabled() const { + return value("Preferences/Queueing/QueueingEnabled", false).toBool(); + } + + void setQueueingSystemEnabled(bool enabled) { + setValue("Preferences/Queueing/QueueingEnabled", enabled); + } + + int getMaxActiveDownloads() const { + return value(QString::fromUtf8("Preferences/Queueing/MaxActiveDownloads"), 3).toInt(); + } + + void setMaxActiveDownloads(int val) { + if(val < 0) val = -1; + setValue(QString::fromUtf8("Preferences/Queueing/MaxActiveDownloads"), val); + } + + int getMaxActiveUploads() const { + return value(QString::fromUtf8("Preferences/Queueing/MaxActiveUploads"), 3).toInt(); + } + + void setMaxActiveUploads(int val) { + if(val < 0) val = -1; + setValue(QString::fromUtf8("Preferences/Queueing/MaxActiveUploads"), val); + } + + int getMaxActiveTorrents() const { + return value(QString::fromUtf8("Preferences/Queueing/MaxActiveTorrents"), 5).toInt(); + } + + void setMaxActiveTorrents(int val) { + if(val < 0) val = -1; + setValue(QString::fromUtf8("Preferences/Queueing/MaxActiveTorrents"), val); + } + + bool isWebUiEnabled() const { + return value("Preferences/WebUI/Enabled", false).toBool(); + } + + void setWebUiEnabled(bool enabled) { + setValue("Preferences/WebUI/Enabled", enabled); + } + + void setWebUiLocalAuthEnabled(bool enabled) { + setValue("Preferences/WebUI/LocalHostAuth", enabled); + } + + bool isWebUiLocalAuthEnabled() const { + return value("Preferences/WebUI/LocalHostAuth", true).toBool(); + } + + quint16 getWebUiPort() const { + return value("Preferences/WebUI/Port", 8080).toInt(); + } + + void setWebUiPort(quint16 port) { + setValue("Preferences/WebUI/Port", port); + } + + bool useUPnPForWebUIPort() const { + return value("Preferences/WebUI/UseUPnP", true).toBool(); + } + + void setUPnPForWebUIPort(bool enabled) { + setValue("Preferences/WebUI/UseUPnP", enabled); + } + + QString getWebUiUsername() const { + return value("Preferences/WebUI/Username", "admin").toString(); + } + + void setWebUiUsername(const QString &username) { + setValue("Preferences/WebUI/Username", username); + } + + void setWebUiPassword(const QString &new_password) { + // Get current password md5 + QString current_pass_md5 = getWebUiPassword(); + // Check if password did not change + if(current_pass_md5 == new_password) return; + // Encode to md5 and save + QCryptographicHash md5(QCryptographicHash::Md5); + md5.addData(getWebUiUsername().toLocal8Bit()+":"+QBT_REALM+":"); + md5.addData(new_password.toLocal8Bit()); + + setValue("Preferences/WebUI/Password_ha1", md5.result().toHex()); + } + + QString getWebUiPassword() const { + QString pass_ha1 = value("Preferences/WebUI/Password_ha1", "").toString(); + if(pass_ha1.isEmpty()) { + QCryptographicHash md5(QCryptographicHash::Md5); + md5.addData(getWebUiUsername().toLocal8Bit()+":"+QBT_REALM+":"); + md5.addData("adminadmin"); + pass_ha1 = md5.result().toHex(); + } + return pass_ha1; + } + + bool isWebUiHttpsEnabled() const { + return value("Preferences/WebUI/HTTPS/Enabled", false).toBool(); + } + + void setWebUiHttpsEnabled(bool enabled) { + setValue("Preferences/WebUI/HTTPS/Enabled", enabled); + } + + QByteArray getWebUiHttpsCertificate() const { + return value("Preferences/WebUI/HTTPS/Certificate").toByteArray(); + } + + void setWebUiHttpsCertificate(const QByteArray &data) { + setValue("Preferences/WebUI/HTTPS/Certificate", data); + } + + QByteArray getWebUiHttpsKey() const { + return value("Preferences/WebUI/HTTPS/Key").toByteArray(); + } + + void setWebUiHttpsKey(const QByteArray &data) { + setValue("Preferences/WebUI/HTTPS/Key", data); + } + + bool isDynDNSEnabled() const { + return value("Preferences/DynDNS/Enabled", false).toBool(); + } + + void setDynDNSEnabled(bool enabled) { + setValue("Preferences/DynDNS/Enabled", enabled); + } + + DNS::Service getDynDNSService() const { + return DNS::Service(value("Preferences/DynDNS/Service", DNS::DYNDNS).toInt()); + } + + void setDynDNSService(int service) { + setValue("Preferences/DynDNS/Service", service); + } + + QString getDynDomainName() const { + return value("Preferences/DynDNS/DomainName", "changeme.dyndns.org").toString(); + } + + void setDynDomainName(const QString name) { + setValue("Preferences/DynDNS/DomainName", name); + } + + QString getDynDNSUsername() const { + return value("Preferences/DynDNS/Username").toString(); + } + + void setDynDNSUsername(const QString username) { + setValue("Preferences/DynDNS/Username", username); + } + + QString getDynDNSPassword() const { + return value("Preferences/DynDNS/Password").toString(); + } + + void setDynDNSPassword(const QString password) { + setValue("Preferences/DynDNS/Password", password); + } + + // Advanced settings + + void setUILockPassword(const QString &clear_password) { + QCryptographicHash md5(QCryptographicHash::Md5); + md5.addData(clear_password.toLocal8Bit()); + QString md5_password = md5.result().toHex(); + setValue("Locking/password", md5_password); + } + + QString getUILockPasswordMD5() const { + return value("Locking/password", QString()).toString(); + } + + bool isUILocked() const { + return value("Locking/locked", false).toBool(); + } + + void setUILocked(bool locked) { + return setValue("Locking/locked", locked); + } + + bool isAutoRunEnabled() const { + return value("AutoRun/enabled", false).toBool(); + } + + void setAutoRunEnabled(bool enabled) { + return setValue("AutoRun/enabled", enabled); + } + + void setAutoRunProgram(const QString &program) { + setValue("AutoRun/program", program); + } + + QString getAutoRunProgram() const { + return value("AutoRun/program", QString()).toString(); + } + + bool shutdownWhenDownloadsComplete() const { + return value(QString::fromUtf8("Preferences/Downloads/AutoShutDownOnCompletion"), false).toBool(); + } + + void setShutdownWhenDownloadsComplete(bool shutdown) { + setValue(QString::fromUtf8("Preferences/Downloads/AutoShutDownOnCompletion"), shutdown); + } + + bool suspendWhenDownloadsComplete() const { + return value(QString::fromUtf8("Preferences/Downloads/AutoSuspendOnCompletion"), false).toBool(); + } + + void setSuspendWhenDownloadsComplete(bool suspend) { + setValue(QString::fromUtf8("Preferences/Downloads/AutoSuspendOnCompletion"), suspend); + } + + bool shutdownqBTWhenDownloadsComplete() const { + return value(QString::fromUtf8("Preferences/Downloads/AutoShutDownqBTOnCompletion"), false).toBool(); + } + + void setShutdownqBTWhenDownloadsComplete(bool shutdown) { + setValue(QString::fromUtf8("Preferences/Downloads/AutoShutDownqBTOnCompletion"), shutdown); + } + + uint diskCacheSize() const { + return value(QString::fromUtf8("Preferences/Downloads/DiskCache"), 16).toUInt(); + } + + void setDiskCacheSize(uint size) { + setValue(QString::fromUtf8("Preferences/Downloads/DiskCache"), size); + } + + uint outgoingPortsMin() const { + return value(QString::fromUtf8("Preferences/Advanced/OutgoingPortsMin"), 0).toUInt(); + } + + void setOutgoingPortsMin(uint val) { + setValue(QString::fromUtf8("Preferences/Advanced/OutgoingPortsMin"), val); + } + + uint outgoingPortsMax() const { + return value(QString::fromUtf8("Preferences/Advanced/OutgoingPortsMax"), 0).toUInt(); + } + + void setOutgoingPortsMax(uint val) { + setValue(QString::fromUtf8("Preferences/Advanced/OutgoingPortsMax"), val); + } + + bool ignoreLimitsOnLAN() const { + return value(QString::fromUtf8("Preferences/Advanced/IgnoreLimitsLAN"), true).toBool(); + } + + void ignoreLimitsOnLAN(bool ignore) { + setValue(QString::fromUtf8("Preferences/Advanced/IgnoreLimitsLAN"), ignore); + } + + bool includeOverheadInLimits() const { + return value(QString::fromUtf8("Preferences/Advanced/IncludeOverhead"), false).toBool(); + } + + void includeOverheadInLimits(bool include) { + setValue(QString::fromUtf8("Preferences/Advanced/IncludeOverhead"), include); + } + + bool trackerExchangeEnabled() const { + return value(QString::fromUtf8("Preferences/Advanced/TrackerExchange"), true).toBool(); + } + + void setTrackerExchangeEnabled(bool enable) { + setValue(QString::fromUtf8("Preferences/Advanced/TrackerExchange"), enable); + } + + bool recheckTorrentsOnCompletion() const { + return value(QString::fromUtf8("Preferences/Advanced/RecheckOnCompletion"), false).toBool(); + } + + void recheckTorrentsOnCompletion(bool recheck) { + setValue(QString::fromUtf8("Preferences/Advanced/RecheckOnCompletion"), recheck); + } + + unsigned int getRefreshInterval() const { + return value(QString::fromUtf8("Preferences/General/RefreshInterval"), 1500).toUInt(); + } + + void setRefreshInterval(uint interval) { + setValue(QString::fromUtf8("Preferences/General/RefreshInterval"), interval); + } + + bool resolvePeerCountries() const { + return value(QString::fromUtf8("Preferences/Connection/ResolvePeerCountries"), true).toBool(); + } + + void resolvePeerCountries(bool resolve) { + setValue(QString::fromUtf8("Preferences/Connection/ResolvePeerCountries"), resolve); + } + + bool resolvePeerHostNames() const { + return value(QString::fromUtf8("Preferences/Connection/ResolvePeerHostNames"), false).toBool(); + } + + void resolvePeerHostNames(bool resolve) { + setValue(QString::fromUtf8("Preferences/Connection/ResolvePeerHostNames"), resolve); + } + + int getMaxHalfOpenConnections() const { + const int val = value(QString::fromUtf8("Preferences/Connection/MaxHalfOpenConnec"), 50).toInt(); + if(val <= 0) return -1; + return val; + } + + void setMaxHalfOpenConnections(int value) { + if(value <= 0) value = -1; + setValue(QString::fromUtf8("Preferences/Connection/MaxHalfOpenConnec"), value); + } + + void setNetworkInterface(const QString& iface) { + setValue(QString::fromUtf8("Preferences/Connection/Interface"), iface); + } + + QString getNetworkInterface() const { + return value(QString::fromUtf8("Preferences/Connection/Interface"), QString()).toString(); + } + + void setNetworkAddress(const QString& addr) { + setValue(QString::fromUtf8("Preferences/Connection/InetAddress"), addr); + } + + QString getNetworkAddress() const { + return value(QString::fromUtf8("Preferences/Connection/InetAddress"), QString()).toString(); + } + +#if LIBTORRENT_VERSION_MINOR > 14 + bool isSuperSeedingEnabled() const { + return value(QString::fromUtf8("Preferences/Advanced/SuperSeeding"), false).toBool(); + } + + void enableSuperSeeding(bool enabled) { + setValue(QString::fromUtf8("Preferences/Advanced/SuperSeeding"), enabled); + } +#endif + +#if defined(Q_WS_X11) && (QT_VERSION >= QT_VERSION_CHECK(4,6,0)) + bool useSystemIconTheme() const { + return value(QString::fromUtf8("Preferences/Advanced/useSystemIconTheme"), true).toBool(); + } + + void useSystemIconTheme(bool enabled) { + setValue(QString::fromUtf8("Preferences/Advanced/useSystemIconTheme"), enabled); + } +#endif + + QStringList getTorrentLabels() const { + return value("TransferListFilters/customLabels").toStringList(); + } + + void addTorrentLabel(const QString& label) { + QStringList labels = value("TransferListFilters/customLabels").toStringList(); + if(!labels.contains(label)) + labels << label; + setValue("TransferListFilters/customLabels", labels); + } + + void removeTorrentLabel(const QString& label) { + QStringList labels = value("TransferListFilters/customLabels").toStringList(); + if(labels.contains(label)) + labels.removeOne(label); + setValue("TransferListFilters/customLabels", labels); + } + + bool recursiveDownloadDisabled() const { + return value(QString::fromUtf8("Preferences/Advanced/DisableRecursiveDownload"), false).toBool(); + } + + void disableRecursiveDownload(bool disable=true) { + setValue(QString::fromUtf8("Preferences/Advanced/DisableRecursiveDownload"), disable); + } + +#ifdef Q_WS_WIN + static QString getPythonPath() { + QSettings reg_python("HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore", QIniSettings::NativeFormat); + QStringList versions = reg_python.childGroups(); + qDebug("Python versions nb: %d", versions.size()); + versions = versions.filter(QRegExp("2\\..*")); + versions.sort(); + while(!versions.empty()) { + const QString version = versions.takeLast(); + qDebug("Detected possible Python v%s location", qPrintable(version)); + QString path = reg_python.value(version+"/InstallPath/Default", "").toString().replace("/", "\\"); + if(!path.isEmpty() && QDir(path).exists("python.exe")) { + qDebug("Found python.exe at %s", qPrintable(path)); + return path; + } + } + if(QFile::exists("C:/Python27/python.exe")) { + reg_python.setValue("2.7/InstallPath/Default", "C:\\Python27"); + return "C:\\Python27"; + } + if(QFile::exists("C:/Python26/python.exe")) { + reg_python.setValue("2.6/InstallPath/Default", "C:\\Python26"); + return "C:\\Python26"; + } + if(QFile::exists("C:/Python25/python.exe")) { + reg_python.setValue("2.5/InstallPath/Default", "C:\\Python25"); + return "C:\\Python25"; + } + return QString::null; + } + + bool neverCheckFileAssoc() const { + return value(QString::fromUtf8("Preferences/Win32/NeverCheckFileAssocation"), false).toBool(); + } + + void setNeverCheckFileAssoc(bool check=true) { + setValue(QString::fromUtf8("Preferences/Win32/NeverCheckFileAssocation"), check); + } + + static bool isFileAssocOk() { + QSettings settings("HKEY_CLASSES_ROOT", QIniSettings::NativeFormat); + if(settings.value(".torrent/Default").toString() != "qBittorrent") { + qDebug(".torrent != qBittorrent"); + return false; + } + qDebug("Checking shell command"); + QString shell_command = settings.value("qBittorrent/shell/open/command/Default", "").toString(); + qDebug("Shell command is: %s", qPrintable(shell_command)); + QRegExp exe_reg("\"([^\"]+)\".*"); + if(exe_reg.indexIn(shell_command) < 0) + return false; + QString assoc_exe = exe_reg.cap(1); + qDebug("exe: %s", qPrintable(assoc_exe)); + if(assoc_exe.compare(qApp->applicationFilePath().replace("/", "\\"), Qt::CaseInsensitive) != 0) + return false; + // Icon + const QString icon_str = "\""+qApp->applicationFilePath().replace("/", "\\")+"\",1"; + if(settings.value("qBittorrent/DefaultIcon/Default", icon_str).toString().compare(icon_str, Qt::CaseInsensitive) != 0) + return false; + // Check magnet link assoc + shell_command = settings.value("Magnet/shell/open/command/Default", "").toString(); + if(exe_reg.indexIn(shell_command) < 0) + return false; + assoc_exe = exe_reg.cap(1); + qDebug("exe: %s", qPrintable(assoc_exe)); + if(assoc_exe.compare(qApp->applicationFilePath().replace("/", "\\"), Qt::CaseInsensitive) != 0) + return false; + return true; + } + + static void setFileAssoc() { + QSettings settings("HKEY_CLASSES_ROOT", QSettings::NativeFormat); + // .Torrent association + settings.setValue(".torrent/Default", "qBittorrent"); + settings.setValue(".torrent/Content Type", "application/x-bittorrent"); + settings.setValue("qBittorrent/shell/Default", "open"); + const QString command_str = "\""+qApp->applicationFilePath().replace("/", "\\")+"\" \"%1\""; + settings.setValue("qBittorrent/shell/open/command/Default", command_str); + settings.setValue("qBittorrent/Content Type/Default", "application/x-bittorrent"); + const QString icon_str = "\""+qApp->applicationFilePath().replace("/", "\\")+"\",1"; + settings.setValue("qBittorrent/DefaultIcon/Default", icon_str); + // Magnet association + settings.setValue("Magnet/Default", "Magnet URI"); + settings.setValue("Magnet/Content Type", "application/x-magnet"); + settings.setValue("Magnet/URL Protocol", ""); + settings.setValue("Magnet/DefaultIcon/Default", icon_str); + settings.setValue("Magnet/shell/Default", "open"); + settings.setValue("Magnet/shell/open/command/Default", command_str); + } + +#endif + + bool isTrackerEnabled() const { + return value(QString::fromUtf8("Preferences/Advanced/trackerEnabled"), false).toBool(); + } + + void setTrackerEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/Advanced/trackerEnabled"), enabled); + } + + int getTrackerPort() const { + return value(QString::fromUtf8("Preferences/Advanced/trackerPort"), 9000).toInt(); + } + + void setTrackerPort(int port) { + setValue(QString::fromUtf8("Preferences/Advanced/trackerPort"), port); + } + +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) + bool isUpdateCheckEnabled() const { + return value(QString::fromUtf8("Preferences/Advanced/updateCheck"), true).toBool(); + } + + void setUpdateCheckEnabled(bool enabled) { + setValue(QString::fromUtf8("Preferences/Advanced/updateCheck"), enabled); + } +#endif + bool confirmTorrentDeletion() const { + return value(QString::fromUtf8("Preferences/Advanced/confirmTorrentDeletion"), true).toBool(); + } + void setConfirmTorrentDeletion(bool enabled) { + setValue(QString::fromUtf8("Preferences/Advanced/confirmTorrentDeletion"), enabled); + } + + TrayIcon::Style trayIconStyle() const { + return TrayIcon::Style(value(QString::fromUtf8("Preferences/Advanced/TrayIconStyle"), TrayIcon::NORMAL).toInt()); + } + void setTrayIconStyle(TrayIcon::Style style) { + setValue(QString::fromUtf8("Preferences/Advanced/TrayIconStyle"), style); + } +}; + +#endif // PREFERENCES_H diff --git a/src/preferences/preferences.pri b/src/preferences/preferences.pri new file mode 100644 index 000000000..0c4d80335 --- /dev/null +++ b/src/preferences/preferences.pri @@ -0,0 +1,13 @@ +INCLUDEPATH += $$PWD + +!contains(DEFINES, DISABLE_GUI) { + + HEADERS += $$PWD/options_imp.h \ + $$PWD/advancedsettings.h + + SOURCES += $$PWD/options_imp.cpp + + FORMS += $$PWD/options.ui +} + +HEADERS += $$PWD/preferences.h diff --git a/src/preview.ui b/src/preview.ui new file mode 100644 index 000000000..92bca6266 --- /dev/null +++ b/src/preview.ui @@ -0,0 +1,149 @@ + + + + + preview + + + + 0 + 0 + 414 + 256 + + + + Preview selection + + + + 9 + + + 6 + + + + + + 0 + 37 + + + + + 16777215 + 37 + + + + + Sans Serif + 14 + 75 + false + true + false + false + + + + File preview + + + Qt::AlignHCenter|Qt::AlignTop + + + + + + + + 16777215 + 42 + + + + The following files support previewing, <br>please select one of them: + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + + + + 0 + + + 6 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Preview + + + + + + + Cancel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + cancelButton + clicked() + preview + reject() + + + 296 + 245 + + + 179 + 282 + + + + + diff --git a/src/previewlistdelegate.h b/src/previewlistdelegate.h new file mode 100644 index 000000000..b489a5d55 --- /dev/null +++ b/src/previewlistdelegate.h @@ -0,0 +1,86 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PREVIEWLISTDELEGATE_H +#define PREVIEWLISTDELEGATE_H + +#include +#include +#include +#include +#include +#include +#include +#include "misc.h" +#include "previewselect.h" + +class PreviewListDelegate: public QItemDelegate { + Q_OBJECT + + public: + PreviewListDelegate(QObject *parent=0) : QItemDelegate(parent){} + + ~PreviewListDelegate(){} + + void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const{ + painter->save(); + QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option); + + switch(index.column()){ + case PreviewSelect::SIZE: + QItemDelegate::drawBackground(painter, opt, index); + QItemDelegate::drawDisplay(painter, opt, option.rect, misc::friendlyUnit(index.data().toLongLong())); + break; + case PreviewSelect::PROGRESS:{ + qreal progress = index.data().toDouble()*100.; + QStyleOptionProgressBarV2 newopt; + newopt.rect = opt.rect; + newopt.text = QString(QByteArray::number(progress, 'f', 1))+QString::fromUtf8("%"); + newopt.progress = (int)progress; + newopt.maximum = 100; + newopt.minimum = 0; + newopt.state |= QStyle::State_Enabled; + newopt.textVisible = true; + QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); + break; + } + default: + QItemDelegate::paint(painter, option, index); + } + painter->restore(); + } + + QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const { + // No editor here + return 0; + } +}; + +#endif diff --git a/src/previewselect.cpp b/src/previewselect.cpp new file mode 100644 index 000000000..d5f3ddd68 --- /dev/null +++ b/src/previewselect.cpp @@ -0,0 +1,122 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include + +#include +#include + +#include "misc.h" +#include "previewlistdelegate.h" +#include "previewselect.h" + +PreviewSelect::PreviewSelect(QWidget* parent, QTorrentHandle h): QDialog(parent), h(h){ + setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + // Preview list + previewListModel = new QStandardItemModel(0, 3); + previewListModel->setHeaderData(NAME, Qt::Horizontal, tr("Name")); + previewListModel->setHeaderData(SIZE, Qt::Horizontal, tr("Size")); + previewListModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress")); + previewList->setModel(previewListModel); + listDelegate = new PreviewListDelegate(this); + previewList->setItemDelegate(listDelegate); + previewList->header()->resizeSection(0, 200); + // Fill list in + std::vector fp; + h.file_progress(fp); + unsigned int nbFiles = h.num_files(); + for(unsigned int i=0; irowCount(); + previewListModel->insertRow(row); + previewListModel->setData(previewListModel->index(row, NAME), QVariant(fileName)); + previewListModel->setData(previewListModel->index(row, SIZE), QVariant((qlonglong)h.filesize_at(i))); + previewListModel->setData(previewListModel->index(row, PROGRESS), QVariant((double)fp[i]/h.filesize_at(i))); + indexes << i; + } + } + previewList->selectionModel()->select(previewListModel->index(0, NAME), QItemSelectionModel::Select); + previewList->selectionModel()->select(previewListModel->index(0, SIZE), QItemSelectionModel::Select); + previewList->selectionModel()->select(previewListModel->index(0, PROGRESS), QItemSelectionModel::Select); + if(!previewListModel->rowCount()){ + QMessageBox::critical(0, tr("Preview impossible"), tr("Sorry, we can't preview this file")); + close(); + } + connect(this, SIGNAL(readyToPreviewFile(QString)), parent, SLOT(previewFile(QString))); + if(previewListModel->rowCount() == 1){ + qDebug("Torrent file only contains one file, no need to display selection dialog before preview"); + // Only one file : no choice + on_previewButton_clicked(); + }else{ + qDebug("Displaying media file selection dialog for preview"); + show(); + } +} + +PreviewSelect::~PreviewSelect(){ + delete previewListModel; + delete listDelegate; +} + + +void PreviewSelect::on_previewButton_clicked(){ + QModelIndex index; + QModelIndexList selectedIndexes = previewList->selectionModel()->selectedRows(NAME); + if(selectedIndexes.size() == 0) return; +#if LIBTORRENT_VERSION_MINOR > 14 + // Flush data + h.flush_cache(); +#endif + QString path; + foreach(index, selectedIndexes){ + path = h.absolute_files_path().at(indexes.at(index.row())); + // File + if(QFile::exists(path)){ + emit readyToPreviewFile(path); + } else { + QMessageBox::critical(0, tr("Preview impossible"), tr("Sorry, we can't preview this file")); + } + close(); + return; + } + qDebug("Cannot find file: %s", path.toLocal8Bit().data()); + QMessageBox::critical(0, tr("Preview impossible"), tr("Sorry, we can't preview this file")); + close(); +} + +void PreviewSelect::on_cancelButton_clicked(){ + close(); +} diff --git a/src/previewselect.h b/src/previewselect.h new file mode 100644 index 000000000..998f4aa91 --- /dev/null +++ b/src/previewselect.h @@ -0,0 +1,70 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PREVIEWSELECT_H +#define PREVIEWSELECT_H + +#include +#include +#include "ui_preview.h" +#include "qtorrenthandle.h" + +class PreviewListDelegate; + +QT_BEGIN_NAMESPACE +class QStandardItemModel; +QT_END_NAMESPACE + +class PreviewSelect: public QDialog, private Ui::preview { + Q_OBJECT + +public: + enum PreviewColumn { NAME, SIZE, PROGRESS }; + +public: + PreviewSelect(QWidget* parent, QTorrentHandle h); + ~PreviewSelect(); + +signals: + void readyToPreviewFile(QString) const; + +protected slots: + void on_previewButton_clicked(); + void on_cancelButton_clicked(); + +private: + QStandardItemModel *previewListModel; + PreviewListDelegate *listDelegate; + QTorrentHandle h; + QList indexes; + +}; + +#endif diff --git a/src/programupdater.cpp b/src/programupdater.cpp new file mode 100644 index 000000000..c6267eed2 --- /dev/null +++ b/src/programupdater.cpp @@ -0,0 +1,235 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include +#include +#include + +#include "programupdater.h" +#include "misc.h" +#include "preferences.h" + +#ifdef Q_WS_MAC +const QString RSS_URL = "http://sourceforge.net/api/file/index/project-id/163414/mtime/desc/rss?path=/qbittorrent-mac"; +const QString FILE_EXT = "DMG"; +#else +const QString RSS_URL = "http://sourceforge.net/api/file/index/project-id/163414/mtime/desc/rss?path=/qbittorrent-win32"; +const QString FILE_EXT = "EXE"; +#endif + +using namespace libtorrent; + +ProgramUpdater::ProgramUpdater(QObject *parent) : + QObject(parent) +{ + mp_manager = new QNetworkAccessManager(this); + Preferences pref; + // Proxy support + if(pref.isProxyEnabled()) { + QNetworkProxy proxy; + switch(pref.getProxyType()) { + case Proxy::SOCKS4: + case Proxy::SOCKS5: + case Proxy::SOCKS5_PW: + proxy.setType(QNetworkProxy::Socks5Proxy); + default: + proxy.setType(QNetworkProxy::HttpProxy); + break; + } + proxy.setHostName(pref.getProxyIp()); + proxy.setPort(pref.getProxyPort()); + // Proxy authentication + if(pref.isProxyAuthEnabled()) { + proxy.setUser(pref.getProxyUsername()); + proxy.setPassword(pref.getProxyPassword()); + } + mp_manager->setProxy(proxy); + } +} + +ProgramUpdater::~ProgramUpdater() { + delete mp_manager; +} + +void ProgramUpdater::checkForUpdates() +{ + // SIGNAL/SLOT + connect(mp_manager, SIGNAL(finished(QNetworkReply*)), + this, SLOT(rssDownloadFinished(QNetworkReply*))); + // Send the request + mp_manager->get(QNetworkRequest(QUrl(RSS_URL))); +} + +void ProgramUpdater::setUpdateUrl(QString title) { + m_updateUrl = "http://downloads.sourceforge.net/project/qbittorrent"+title; + qDebug("The Update URL is %s", qPrintable(m_updateUrl)); +} + +void ProgramUpdater::rssDownloadFinished(QNetworkReply *reply) +{ + // Disconnect SIGNAL/SLOT + disconnect(mp_manager, 0, this, 0); + qDebug("Finished downloading the new qBittorrent updates RSS"); + QString new_version; + if(!reply->error()) { + qDebug("No download error, good."); + QXmlStreamReader xml(reply); + QString item_title; + bool in_title = false; + bool in_item = false; + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement()) { + if (in_item && xml.name() == "title") { + in_title = true; + item_title = ""; + } else if (xml.name() == "item") { + in_item = true; + } + } else if (xml.isEndElement()) { + if(in_item && xml.name() == "title") { + in_title = false; + const QString ext = misc::file_extension(item_title).toUpper(); + qDebug("Found an update with file extension: %s", qPrintable(ext)); + if(ext == FILE_EXT) { + qDebug("The last update available is %s", qPrintable(item_title)); + new_version = extractVersionNumber(item_title); + if(!new_version.isEmpty()) { + qDebug("Detected version is %s", qPrintable(new_version)); + if(isVersionMoreRecent(new_version)) + setUpdateUrl(item_title); + } + break; + } + } else if (xml.name() == "item") { + in_item = false; + } + } else if (xml.isCharacters() && !xml.isWhitespace()) { + if(in_item && in_title) + item_title += xml.text().toString(); + } + } + } + emit updateCheckFinished(!m_updateUrl.isEmpty(), new_version); + // Clean up + reply->deleteLater(); +} + +void ProgramUpdater::updateProgram() +{ + Q_ASSERT(!m_updateUrl.isEmpty()); + QDesktopServices::openUrl(m_updateUrl); + return; + /*connect(mp_manager, SIGNAL(finished(QNetworkReply*)), + this, SLOT(saveUpdate(QNetworkReply*))); + // Send the request + mp_manager->get(QNetworkRequest(QUrl(m_updateUrl)));*/ +} + +/*void ProgramUpdater::saveUpdate(QNetworkReply *reply) +{ + // Disconnect SIGNAL/SLOT + disconnect(mp_manager, 0, this, 0); + // Process the download + if(!reply->error()) { + // Save the file + const QString installer_path = QDir::temp().absoluteFilePath("qbittorrent_update."+FILE_EXT.toLower()); + QFile update_installer(installer_path); + if(update_installer.exists()) { + update_installer.remove(); + } + if(update_installer.open(QIODevice::WriteOnly)) { + update_installer.write(reply->readAll()); + reply->close(); + update_installer.close(); + // Install the update + installUpdate(installer_path); + } else { + emit updateInstallFinished(tr("Could not create the file %1").arg(installer_path)); + } + } else { + emit updateInstallFinished(tr("Failed to download the update at %1", "%1 is an URL").arg(m_updateUrl)); + } + reply->deleteLater(); + deleteLater(); +}*/ + +/*void ProgramUpdater::installUpdate(QString update_path) +{ + qDebug("Installing the update at %s...", qPrintable(update_path)); +#ifdef Q_WS_WIN + QDesktopServices::openUrl(QUrl(QString("file:///")+update_path, QUrl::TolerantMode)); +#else + QDesktopServices::openUrl(QUrl(QString("file://")+update_path, QUrl::TolerantMode)); +#endif +}*/ + +// title on Windows: /qbittorrent-win32/qbittorrent-2.4.7/qbittorrent_2.4.7_setup.exe +// title on Mac: /qbittorrent-mac/qbittorrent-2.4.4/qbittorrent-2.4.4.dmg +QString ProgramUpdater::extractVersionNumber(QString title) const +{ + QString version; + QStringList parts = title.split("/"); + if(parts.size() != 4) { + qDebug("ProgramUpdater: Unrecognized title: %s", qPrintable(title)); + return version; + } + QString folder = parts.at(2); + if(!folder.contains("-")) { + qDebug("ProgramUpdater: Unrecognized folder name: %s", qPrintable(folder)); + return version; + } + version = folder.mid(folder.lastIndexOf("-")+1); + if(version.split(".").size() != 3) { + qDebug("ProgramUpdater: Unrecognized version format: %s", qPrintable(version)); + return QString::null; + } + return version; +} + +bool ProgramUpdater::isVersionMoreRecent(QString new_version) const +{ + const QStringList parts = new_version.split("."); + Q_ASSERT(parts.size() == 3); + const int major = parts.at(0).toInt(); + const int minor = parts.at(1).toInt(); + const int bugfix = parts.at(2).toInt(); + if(major < VERSION_MAJOR) + return false; + if(minor < VERSION_MINOR) + return false; + if(bugfix <= VERSION_BUGFIX) + return false; + return true; +} + diff --git a/src/programupdater.h b/src/programupdater.h new file mode 100644 index 000000000..7f9ab7a85 --- /dev/null +++ b/src/programupdater.h @@ -0,0 +1,68 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PROGRAMUPDATER_H +#define PROGRAMUPDATER_H + +#include +#include + +class QNetworkReply; +class QNetworkAccessManager; + +class ProgramUpdater : public QObject +{ + Q_OBJECT +public: + explicit ProgramUpdater(QObject *parent = 0); + ~ProgramUpdater(); + void checkForUpdates(); + void updateProgram(); + +protected: + QString extractVersionNumber(QString title) const; + bool isVersionMoreRecent(QString new_version) const; + +protected slots: + void rssDownloadFinished(QNetworkReply* reply); + //void installUpdate(QString update_path); + //void saveUpdate(QNetworkReply* reply); + void setUpdateUrl(QString title); + +signals: + void updateCheckFinished(bool update_available, QString version); + void updateInstallFinished(QString error); + +private: + QString m_updateUrl; + QNetworkAccessManager *mp_manager; +}; + +#endif // PROGRAMUPDATER_H diff --git a/src/properties/downloadedpiecesbar.h b/src/properties/downloadedpiecesbar.h new file mode 100644 index 000000000..8bb2bbf8d --- /dev/null +++ b/src/properties/downloadedpiecesbar.h @@ -0,0 +1,131 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef DOWNLOADEDPIECESBAR_H +#define DOWNLOADEDPIECESBAR_H + +#include +#include +#include +#include +#include +#include + +#define BAR_HEIGHT 18 + +class DownloadedPiecesBar: public QWidget { + Q_OBJECT + Q_DISABLE_COPY(DownloadedPiecesBar) + +private: + QPixmap pixmap; + + +public: + DownloadedPiecesBar(QWidget *parent): QWidget(parent) { + setFixedHeight(BAR_HEIGHT); + } + + void setProgress(const libtorrent::bitfield &pieces, const libtorrent::bitfield &downloading_pieces) { + if(pieces.empty()) { + // Empty bar + QPixmap pix = QPixmap(1, 1); + pix.fill(); + pixmap = pix; + } else { + const qulonglong nb_pieces = pieces.size(); + // Reduce the number of pieces before creating the pixmap + // otherwise it can crash when there are too many pieces + const uint w = width(); + if(nb_pieces > w) { + const uint ratio = floor(nb_pieces/(double)w); + libtorrent::bitfield scaled_pieces(ceil(nb_pieces/(double)ratio), false); + libtorrent::bitfield scaled_downloading(ceil(nb_pieces/(double)ratio), false); + uint scaled_index = 0; + for(qulonglong i=0; i + + addPeerDialog + + + + 0 + 0 + 400 + 112 + + + + + 0 + 0 + + + + Peer addition + + + + + + + + + + + 75 + true + + + + IP + + + Qt::AlignCenter + + + + + + + + + + + + + + + 75 + true + + + + Port + + + Qt::AlignCenter + + + + + + + + 60 + 0 + + + + + 70 + 16777215 + + + + 1000 + + + 65535 + + + 6881 + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + diff --git a/src/properties/peeraddition.h b/src/properties/peeraddition.h new file mode 100644 index 000000000..6f0b1f0f8 --- /dev/null +++ b/src/properties/peeraddition.h @@ -0,0 +1,103 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PEERADDITION_H +#define PEERADDITION_H + +#include +#include +#include +#include +#include "ui_peer.h" +#include + +#include +#if BOOST_VERSION < 103500 +#include +#else +#include +#endif + +class PeerAdditionDlg: public QDialog, private Ui::addPeerDialog { + Q_OBJECT + +public: + PeerAdditionDlg(QWidget *parent=0): QDialog(parent) { + setupUi(this); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(validateInput())); + } + + ~PeerAdditionDlg(){} + + QString getIP() const { + QHostAddress ip(lineIP->text()); + if(!ip.isNull()) { + // QHostAddress::toString() cleans up the IP for libtorrent + return ip.toString(); + } + return QString(); + } + + unsigned short getPort() const { + return spinPort->value(); + } + + static libtorrent::asio::ip::tcp::endpoint askForPeerEndpoint() { + libtorrent::asio::ip::tcp::endpoint ep; + PeerAdditionDlg dlg; + if(dlg.exec() == QDialog::Accepted) { + QString ip = dlg.getIP(); + boost::system::error_code ec; + libtorrent::address addr = libtorrent::address::from_string(qPrintable(ip), ec); + if(ec) { + qDebug("Unable to parse the provided IP: %s", qPrintable(ip)); + return ep; + } + qDebug("Provided IP is correct"); + ep = libtorrent::asio::ip::tcp::endpoint(addr, dlg.getPort()); + } + return ep; + } + + +protected slots: + void validateInput() { + if(getIP().isEmpty()) { + QMessageBox::warning(this, tr("Invalid IP"), + tr("The IP you provided is invalid."), + QMessageBox::Ok); + } else { + accept(); + } + } +}; + +#endif // PEERADDITION_H diff --git a/src/properties/peerlistdelegate.h b/src/properties/peerlistdelegate.h new file mode 100644 index 000000000..e48931a90 --- /dev/null +++ b/src/properties/peerlistdelegate.h @@ -0,0 +1,86 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PEERLISTDELEGATE_H +#define PEERLISTDELEGATE_H + +#include +#include +#include "misc.h" + +class PeerListDelegate: public QItemDelegate { + Q_OBJECT + +public: + enum PeerListColumns {IP, CONNECTION, CLIENT, PROGRESS, DOWN_SPEED, UP_SPEED, + TOT_DOWN, TOT_UP, IP_HIDDEN, COL_COUNT}; + +public: + PeerListDelegate(QObject *parent) : QItemDelegate(parent){} + + ~PeerListDelegate(){} + + void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const{ + painter->save(); + QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option); + switch(index.column()){ + case TOT_DOWN: + case TOT_UP: + QItemDelegate::drawBackground(painter, opt, index); + QItemDelegate::drawDisplay(painter, opt, option.rect, misc::friendlyUnit(index.data().toLongLong())); + break; + case DOWN_SPEED: + case UP_SPEED:{ + QItemDelegate::drawBackground(painter, opt, index); + qreal speed = index.data().toDouble(); + if (speed > 0.0) + QItemDelegate::drawDisplay(painter, opt, opt.rect, misc::friendlyUnit(speed)+tr("/s", "/second (i.e. per second)")); + break; + } + case PROGRESS:{ + QItemDelegate::drawBackground(painter, opt, index); + qreal progress = index.data().toDouble(); + QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::number(progress*100., 'f', 1)+"%"); + break; + } + default: + QItemDelegate::paint(painter, option, index); + } + painter->restore(); + } + + QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const { + // No editor here + return 0; + } + +}; + +#endif // PEERLISTDELEGATE_H diff --git a/src/properties/peerlistwidget.cpp b/src/properties/peerlistwidget.cpp new file mode 100644 index 000000000..570bf5f24 --- /dev/null +++ b/src/properties/peerlistwidget.cpp @@ -0,0 +1,426 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include "peerlistwidget.h" +#include "peerlistdelegate.h" +#include "reverseresolution.h" +#include "preferences.h" +#include "propertieswidget.h" +#include "geoipmanager.h" +#include "peeraddition.h" +#include "speedlimitdlg.h" +#include "iconprovider.h" +#include +#include +#include +#include +#include +#include +#include +#include "qinisettings.h" + +using namespace libtorrent; + +PeerListWidget::PeerListWidget(PropertiesWidget *parent): QTreeView(parent), properties(parent), display_flags(false) { + // Load settings + loadSettings(); + // Visual settings + setRootIsDecorated(false); + setItemsExpandable(false); + setAllColumnsShowFocus(true); + setSelectionMode(QAbstractItemView::ExtendedSelection); + // List Model + listModel = new QStandardItemModel(0, PeerListDelegate::COL_COUNT); + listModel->setHeaderData(PeerListDelegate::IP, Qt::Horizontal, tr("IP")); + listModel->setHeaderData(PeerListDelegate::CONNECTION, Qt::Horizontal, tr("Connection")); + listModel->setHeaderData(PeerListDelegate::CLIENT, Qt::Horizontal, tr("Client", "i.e.: Client application")); + listModel->setHeaderData(PeerListDelegate::PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded")); + listModel->setHeaderData(PeerListDelegate::DOWN_SPEED, Qt::Horizontal, tr("Down Speed", "i.e: Download speed")); + listModel->setHeaderData(PeerListDelegate::UP_SPEED, Qt::Horizontal, tr("Up Speed", "i.e: Upload speed")); + listModel->setHeaderData(PeerListDelegate::TOT_DOWN, Qt::Horizontal, tr("Downloaded", "i.e: total data downloaded")); + listModel->setHeaderData(PeerListDelegate::TOT_UP, Qt::Horizontal, tr("Uploaded", "i.e: total data uploaded")); + // Proxy model to support sorting without actually altering the underlying model + proxyModel = new QSortFilterProxyModel(); + proxyModel->setDynamicSortFilter(true); + proxyModel->setSourceModel(listModel); + setModel(proxyModel); + hideColumn(PeerListDelegate::IP_HIDDEN); + // Context menu + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showPeerListMenu(QPoint))); + // List delegate + listDelegate = new PeerListDelegate(this); + setItemDelegate(listDelegate); + // Enable sorting + setSortingEnabled(true); + // IP to Hostname resolver + updatePeerHostNameResolutionState(); + // SIGNAL/SLOT + connect(header(), SIGNAL(sectionClicked(int)), SLOT(handleSortColumnChanged(int))); + handleSortColumnChanged(header()->sortIndicatorSection()); +} + +PeerListWidget::~PeerListWidget() { + saveSettings(); + delete proxyModel; + delete listModel; + delete listDelegate; + if(resolver) + delete resolver; +} + +void PeerListWidget::updatePeerHostNameResolutionState() { + if(Preferences().resolvePeerHostNames()) { + if(!resolver) { + resolver = new ReverseResolution(this); + connect(resolver, SIGNAL(ip_resolved(QString,QString)), this, SLOT(handleResolved(QString,QString))); + loadPeers(properties->getCurrentTorrent(), true); + } + } else { + if(resolver) { + delete resolver; + } + } +} + +void PeerListWidget::updatePeerCountryResolutionState() { + if(Preferences().resolvePeerCountries() != display_flags) { + display_flags = !display_flags; + if(display_flags) { + const QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) return; + loadPeers(h); + } + } +} + +void PeerListWidget::showPeerListMenu(QPoint) { + QMenu menu; + bool empty_menu = true; + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) return; + QModelIndexList selectedIndexes = selectionModel()->selectedRows(); + QStringList selectedPeerIPs; + foreach(const QModelIndex &index, selectedIndexes) { + int row = proxyModel->mapToSource(index).row(); + QString myip = listModel->data(listModel->index(row, PeerListDelegate::IP_HIDDEN)).toString(); + selectedPeerIPs << myip; + } + // Add Peer Action + QAction *addPeerAct = 0; + if(!h.is_queued() && !h.is_checking()) { + addPeerAct = menu.addAction(IconProvider::instance()->getIcon("user-group-new"), tr("Add a new peer...")); + empty_menu = false; + } + // Per Peer Speed limiting actions + QAction *upLimitAct = 0; + QAction *dlLimitAct = 0; + QAction *banAct = 0; + QAction *copyIPAct = 0; + if(!selectedPeerIPs.isEmpty()) { + copyIPAct = menu.addAction(IconProvider::instance()->getIcon("edit-copy"), tr("Copy IP")); + menu.addSeparator(); + dlLimitAct = menu.addAction(QIcon(":/Icons/skin/download.png"), tr("Limit download rate...")); + upLimitAct = menu.addAction(QIcon(":/Icons/skin/seeding.png"), tr("Limit upload rate...")); + menu.addSeparator(); + banAct = menu.addAction(IconProvider::instance()->getIcon("user-group-delete"), tr("Ban peer permanently")); + empty_menu = false; + } + if(empty_menu) return; + QAction *act = menu.exec(QCursor::pos()); + if(act == 0) return; + if(act == addPeerAct) { + libtorrent::asio::ip::tcp::endpoint ep = PeerAdditionDlg::askForPeerEndpoint(); + if(ep != libtorrent::asio::ip::tcp::endpoint()) { + try { + h.connect_peer(ep); + QMessageBox::information(0, tr("Peer addition"), tr("The peer was added to this torrent.")); + } catch(std::exception) { + QMessageBox::critical(0, tr("Peer addition"), tr("The peer could not be added to this torrent.")); + } + } else { + qDebug("No peer was added"); + } + return; + } + if(act == upLimitAct) { + limitUpRateSelectedPeers(selectedPeerIPs); + return; + } + if(act == dlLimitAct) { + limitDlRateSelectedPeers(selectedPeerIPs); + return; + } + if(act == banAct) { + banSelectedPeers(selectedPeerIPs); + return; + } + if(act == copyIPAct) { +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + QApplication::clipboard()->setText(selectedPeerIPs.join("\r\n")); +#else + QApplication::clipboard()->setText(selectedPeerIPs.join("\n")); +#endif + } +} + +void PeerListWidget::banSelectedPeers(QStringList peer_ips) { + // Confirm first + int ret = QMessageBox::question(this, tr("Are you sure? -- qBittorrent"), tr("Are you sure you want to ban permanently the selected peers?"), + tr("&Yes"), tr("&No"), + QString(), 0, 1); + if(ret) return; + foreach(const QString &ip, peer_ips) { + qDebug("Banning peer %s...", ip.toLocal8Bit().data()); + QBtSession::instance()->addConsoleMessage(tr("Manually banning peer %1...").arg(ip)); + QBtSession::instance()->banIP(ip); + } + // Refresh list + loadPeers(properties->getCurrentTorrent()); +} + +void PeerListWidget::limitUpRateSelectedPeers(QStringList peer_ips) { + if(peer_ips.empty()) return; + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) return; + bool ok=false; + int cur_limit = -1; +#if LIBTORRENT_VERSION_MINOR > 15 + libtorrent::asio::ip::tcp::endpoint first_ep = peerEndpoints.value(peer_ips.first(), + libtorrent::asio::ip::tcp::endpoint()); + if(first_ep != libtorrent::asio::ip::tcp::endpoint()) + cur_limit = h.get_peer_upload_limit(first_ep); +#endif + long limit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Upload rate limiting"), cur_limit, Preferences().getGlobalUploadLimit()*1024.); + if(!ok) return; + foreach(const QString &ip, peer_ips) { + libtorrent::asio::ip::tcp::endpoint ep = peerEndpoints.value(ip, libtorrent::asio::ip::tcp::endpoint()); + if(ep != libtorrent::asio::ip::tcp::endpoint()) { + qDebug("Settings Upload limit of %.1f Kb/s to peer %s", limit/1024., ip.toLocal8Bit().data()); + try { + h.set_peer_upload_limit(ep, limit); + }catch(std::exception) { + std::cerr << "Impossible to apply upload limit to peer" << std::endl; + } + } else { + qDebug("The selected peer no longer exists..."); + } + } +} + +void PeerListWidget::limitDlRateSelectedPeers(QStringList peer_ips) { + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) return; + bool ok=false; + int cur_limit = -1; +#if LIBTORRENT_VERSION_MINOR > 15 + libtorrent::asio::ip::tcp::endpoint first_ep = peerEndpoints.value(peer_ips.first(), + libtorrent::asio::ip::tcp::endpoint()); + if(first_ep != libtorrent::asio::ip::tcp::endpoint()) + cur_limit = h.get_peer_download_limit(first_ep); +#endif + long limit = SpeedLimitDialog::askSpeedLimit(&ok, tr("Download rate limiting"), cur_limit, Preferences().getGlobalDownloadLimit()*1024.); + if(!ok) return; + foreach(const QString &ip, peer_ips) { + libtorrent::asio::ip::tcp::endpoint ep = peerEndpoints.value(ip, libtorrent::asio::ip::tcp::endpoint()); + if(ep != libtorrent::asio::ip::tcp::endpoint()) { + qDebug("Settings Download limit of %.1f Kb/s to peer %s", limit/1024., ip.toLocal8Bit().data()); + try { + h.set_peer_download_limit(ep, limit); + }catch(std::exception) { + std::cerr << "Impossible to apply download limit to peer" << std::endl; + } + } else { + qDebug("The selected peer no longer exists..."); + } + } +} + + +void PeerListWidget::clear() { + qDebug("clearing peer list"); + peerItems.clear(); + peerEndpoints.clear(); + missingFlags.clear(); + int nbrows = listModel->rowCount(); + if(nbrows > 0) { + qDebug("Cleared %d peers", nbrows); + listModel->removeRows(0, nbrows); + } +} + +void PeerListWidget::loadSettings() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + header()->restoreState(settings.value("TorrentProperties/Peers/PeerListState").toByteArray()); +} + +void PeerListWidget::saveSettings() const { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.setValue("TorrentProperties/Peers/PeerListState", header()->saveState()); +} + +void PeerListWidget::loadPeers(const QTorrentHandle &h, bool force_hostname_resolution) { + if(!h.is_valid()) return; + boost::system::error_code ec; + std::vector peers; + h.get_peer_info(peers); + std::vector::iterator itr; + QSet old_peers_set = peerItems.keys().toSet(); + for(itr = peers.begin(); itr != peers.end(); itr++) { + peer_info peer = *itr; + QString peer_ip = misc::toQString(peer.ip.address().to_string(ec)); + if(ec) continue; + if(peerItems.contains(peer_ip)) { + // Update existing peer + updatePeer(peer_ip, peer); + old_peers_set.remove(peer_ip); + if(force_hostname_resolution) { + if(resolver) { + const QString host = resolver->getHostFromCache(peer.ip); + if(host.isNull()) { + resolver->resolve(peer.ip); + } else { + qDebug("Got peer IP from cache"); + handleResolved(peer_ip, host); + } + } + } + } else { + // Add new peer + peerItems[peer_ip] = addPeer(peer_ip, peer); + peerEndpoints[peer_ip] = peer.ip; + } + } + // Delete peers that are gone + QSetIterator it(old_peers_set); + while(it.hasNext()) { + QString ip = it.next(); + missingFlags.remove(ip); + peerEndpoints.remove(ip); + QStandardItem *item = peerItems.take(ip); + listModel->removeRow(item->row()); + } +} + +QStandardItem* PeerListWidget::addPeer(QString ip, peer_info peer) { + int row = listModel->rowCount(); + // Adding Peer to peer list + listModel->insertRow(row); + QString host; + if(resolver) { + host = resolver->getHostFromCache(peer.ip); + } + if(host.isNull()) + listModel->setData(listModel->index(row, PeerListDelegate::IP), ip); + else + listModel->setData(listModel->index(row, PeerListDelegate::IP), host); + listModel->setData(listModel->index(row, PeerListDelegate::IP_HIDDEN), ip); + // Resolve peer host name is asked + if(resolver && host.isNull()) + resolver->resolve(peer.ip); + if(display_flags) { + const QIcon ico = GeoIPManager::CountryISOCodeToIcon(peer.country); + if(!ico.isNull()) { + listModel->setData(listModel->index(row, PeerListDelegate::IP), ico, Qt::DecorationRole); + const QString country_name = GeoIPManager::CountryISOCodeToName(peer.country); + listModel->setData(listModel->index(row, PeerListDelegate::IP), country_name, Qt::ToolTipRole); + } else { + missingFlags.insert(ip); + } + } + listModel->setData(listModel->index(row, PeerListDelegate::CONNECTION), getConnectionString(peer.connection_type)); + listModel->setData(listModel->index(row, PeerListDelegate::CLIENT), misc::toQStringU(peer.client)); + listModel->setData(listModel->index(row, PeerListDelegate::PROGRESS), peer.progress); + listModel->setData(listModel->index(row, PeerListDelegate::DOWN_SPEED), peer.payload_down_speed); + listModel->setData(listModel->index(row, PeerListDelegate::UP_SPEED), peer.payload_up_speed); + listModel->setData(listModel->index(row, PeerListDelegate::TOT_DOWN), (qulonglong)peer.total_download); + listModel->setData(listModel->index(row, PeerListDelegate::TOT_UP), (qulonglong)peer.total_upload); + return listModel->item(row, PeerListDelegate::IP); +} + +void PeerListWidget::updatePeer(QString ip, peer_info peer) { + QStandardItem *item = peerItems.value(ip); + int row = item->row(); + if(display_flags) { + const QIcon ico = GeoIPManager::CountryISOCodeToIcon(peer.country); + if(!ico.isNull()) { + listModel->setData(listModel->index(row, PeerListDelegate::IP), ico, Qt::DecorationRole); + const QString country_name = GeoIPManager::CountryISOCodeToName(peer.country); + listModel->setData(listModel->index(row, PeerListDelegate::IP), country_name, Qt::ToolTipRole); + missingFlags.remove(ip); + } + } + listModel->setData(listModel->index(row, PeerListDelegate::CONNECTION), getConnectionString(peer.connection_type)); + listModel->setData(listModel->index(row, PeerListDelegate::CLIENT), misc::toQStringU(peer.client)); + listModel->setData(listModel->index(row, PeerListDelegate::PROGRESS), peer.progress); + listModel->setData(listModel->index(row, PeerListDelegate::DOWN_SPEED), peer.payload_down_speed); + listModel->setData(listModel->index(row, PeerListDelegate::UP_SPEED), peer.payload_up_speed); + listModel->setData(listModel->index(row, PeerListDelegate::TOT_DOWN), (qulonglong)peer.total_download); + listModel->setData(listModel->index(row, PeerListDelegate::TOT_UP), (qulonglong)peer.total_upload); +} + +void PeerListWidget::handleResolved(const QString &ip, const QString &hostname) { + QStandardItem *item = peerItems.value(ip, 0); + if(item) { + qDebug("Resolved %s -> %s", qPrintable(ip), qPrintable(hostname)); + item->setData(hostname, Qt::DisplayRole); + //listModel->setData(listModel->index(item->row(), IP), hostname, Qt::DisplayRole); + } +} + +void PeerListWidget::handleSortColumnChanged(int col) +{ + if(col == 0) { + qDebug("Sorting by decoration"); + proxyModel->setSortRole(Qt::ToolTipRole); + } else { + proxyModel->setSortRole(Qt::DisplayRole); + } +} + +QString PeerListWidget::getConnectionString(int connection_type) +{ + QString connection; + switch(connection_type) { +#if LIBTORRENT_VERSION_MINOR > 15 + case peer_info::bittorrent_utp: + connection = "uTP"; + break; + case peer_info::http_seed: +#endif + case peer_info::web_seed: + connection = "Web"; + break; + default: + connection = "BT"; + break; + } + return connection; +} diff --git a/src/properties/peerlistwidget.h b/src/properties/peerlistwidget.h new file mode 100644 index 000000000..66a3b1417 --- /dev/null +++ b/src/properties/peerlistwidget.h @@ -0,0 +1,100 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PEERLISTWIDGET_H +#define PEERLISTWIDGET_H + +#include +#include +#include +#include +#include +#include "qtorrenthandle.h" +#include "misc.h" + +class PeerListDelegate; +class ReverseResolution; +class PropertiesWidget; + +QT_BEGIN_NAMESPACE +class QSortFilterProxyModel; +class QStandardItem; +class QStandardItemModel; +QT_END_NAMESPACE + +#include +#if BOOST_VERSION < 103500 +#include +#else +#include +#endif + +class PeerListWidget : public QTreeView { + Q_OBJECT + Q_DISABLE_COPY(PeerListWidget) + +public: + PeerListWidget(PropertiesWidget *parent); + ~PeerListWidget(); + +public slots: + void loadPeers(const QTorrentHandle &h, bool force_hostname_resolution=false); + QStandardItem* addPeer(QString ip, libtorrent::peer_info peer); + void updatePeer(QString ip, libtorrent::peer_info peer); + void handleResolved(const QString &ip, const QString &hostname); + void updatePeerHostNameResolutionState(); + void updatePeerCountryResolutionState(); + void clear(); + +protected slots: + void loadSettings(); + void saveSettings() const; + void showPeerListMenu(QPoint); + void limitUpRateSelectedPeers(QStringList peer_ips); + void limitDlRateSelectedPeers(QStringList peer_ips); + void banSelectedPeers(QStringList peer_ips); + void handleSortColumnChanged(int col); + +private: + static QString getConnectionString(int connection_type); + +private: + QStandardItemModel *listModel; + PeerListDelegate *listDelegate; + QSortFilterProxyModel * proxyModel; + QHash peerItems; + QHash peerEndpoints; + QSet missingFlags; + QPointer resolver; + PropertiesWidget* properties; + bool display_flags; +}; + +#endif // PEERLISTWIDGET_H diff --git a/src/properties/pieceavailabilitybar.h b/src/properties/pieceavailabilitybar.h new file mode 100644 index 000000000..278cb8ce1 --- /dev/null +++ b/src/properties/pieceavailabilitybar.h @@ -0,0 +1,117 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PIECEAVAILABILITYBAR_H +#define PIECEAVAILABILITYBAR_H + +#include +#include +#include +#include +#include +#include +#include + +#define BAR_HEIGHT 18 + +class PieceAvailabilityBar: public QWidget { + Q_OBJECT + Q_DISABLE_COPY(PieceAvailabilityBar) + +private: + QPixmap pixmap; + +public: + PieceAvailabilityBar(QWidget *parent): QWidget(parent) { + setFixedHeight(BAR_HEIGHT); + } + + void setAvailability(const std::vector& avail) { + if(avail.empty()) { + // Empty bar + QPixmap pix = QPixmap(1, 1); + pix.fill(); + pixmap = pix; + } else { + // Reduce the number of pieces before creating the pixmap + // otherwise it can crash when there are too many pieces + const qulonglong nb_pieces = avail.size(); + const uint w = width(); + if(nb_pieces > w) { + const qulonglong ratio = floor(nb_pieces/(double)w); + std::vector scaled_avail; + scaled_avail.reserve(ceil(nb_pieces/(double)ratio)); + for(qulonglong i=0; i avail) { + const int max = *std::max_element(avail.begin(), avail.end()); + if(max == 0) { + QPixmap pix = QPixmap(1, 1); + pix.fill(); + pixmap = pix; + return; + } + QPixmap pix = QPixmap(avail.size(), 1); + //pix.fill(); + QPainter painter(&pix); + for(uint i=0; i < avail.size(); ++i) { + const uint rg = 0xff - (0xff * avail[i]/max); + painter.setPen(QColor(rg, rg, 0xff)); + painter.drawPoint(i,0); + } + pixmap = pix; + } +}; + +#endif // PIECEAVAILABILITYBAR_H diff --git a/src/properties/properties.pri b/src/properties/properties.pri new file mode 100644 index 000000000..6468da420 --- /dev/null +++ b/src/properties/properties.pri @@ -0,0 +1,22 @@ +INCLUDEPATH += $$PWD + +FORMS += $$PWD/propertieswidget.ui \ + $$PWD/trackersadditiondlg.ui \ + $$PWD/peer.ui + +HEADERS += $$PWD/propertieswidget.h \ + $$PWD/peerlistwidget.h \ + $$PWD/proplistdelegate.h \ + $$PWD/trackerlist.h \ + $$PWD/downloadedpiecesbar.h \ + $$PWD/peerlistdelegate.h \ + $$PWD/peeraddition.h \ + $$PWD/trackersadditiondlg.h \ + $$PWD/pieceavailabilitybar.h \ + $$PWD/proptabbar.h + +SOURCES += $$PWD/propertieswidget.cpp \ + $$PWD/peerlistwidget.cpp \ + $$PWD/trackerlist.cpp \ + $$PWD/proptabbar.cpp + diff --git a/src/properties/propertieswidget.cpp b/src/properties/propertieswidget.cpp new file mode 100644 index 000000000..c94caacca --- /dev/null +++ b/src/properties/propertieswidget.cpp @@ -0,0 +1,731 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "propertieswidget.h" +#include "transferlistwidget.h" +#include "torrentpersistentdata.h" +#include "qbtsession.h" +#include "proplistdelegate.h" +#include "torrentfilesmodel.h" +#include "peerlistwidget.h" +#include "trackerlist.h" +#include "mainwindow.h" +#include "downloadedpiecesbar.h" +#include "pieceavailabilitybar.h" +#include "qinisettings.h" +#include "proptabbar.h" +#include "iconprovider.h" +#include "lineedit.h" + +using namespace libtorrent; + +PropertiesWidget::PropertiesWidget(QWidget *parent, MainWindow* main_window, TransferListWidget *transferList): + QWidget(parent), transferList(transferList), main_window(main_window) { + setupUi(this); + + // Icons + deleteWS_button->setIcon(IconProvider::instance()->getIcon("list-remove")); + addWS_button->setIcon(IconProvider::instance()->getIcon("list-add")); + trackerUpButton->setIcon(IconProvider::instance()->getIcon("go-up")); + trackerDownButton->setIcon(IconProvider::instance()->getIcon("go-down")); + + state = VISIBLE; + setEnabled(false); + + // Set Properties list model + PropListModel = new TorrentFilesFilterModel(); + filesList->setModel(PropListModel); + PropDelegate = new PropListDelegate(this); + filesList->setItemDelegate(PropDelegate); + filesList->setSortingEnabled(true); + // Torrent content filtering + m_contentFilerLine = new LineEdit(this); + connect(m_contentFilerLine, SIGNAL(textChanged(QString)), PropListModel, SLOT(setFilterFixedString(QString))); + contentFilterLayout->insertWidget(1, m_contentFilerLine); + + // SIGNAL/SLOTS + connect(filesList, SIGNAL(clicked(const QModelIndex&)), filesList, SLOT(edit(const QModelIndex&))); + connect(selectAllButton, SIGNAL(clicked()), PropListModel, SLOT(selectAll())); + connect(selectNoneButton, SIGNAL(clicked()), PropListModel, SLOT(selectNone())); + connect(filesList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFilesListMenu(const QPoint&))); + connect(filesList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(openDoubleClickedFile(QModelIndex))); + connect(PropListModel, SIGNAL(filteredFilesChanged()), this, SLOT(filteredFilesChanged())); + connect(addWS_button, SIGNAL(clicked()), this, SLOT(askWebSeed())); + connect(deleteWS_button, SIGNAL(clicked()), this, SLOT(deleteSelectedUrlSeeds())); + connect(transferList, SIGNAL(currentTorrentChanged(QTorrentHandle)), this, SLOT(loadTorrentInfos(QTorrentHandle))); + connect(PropDelegate, SIGNAL(filteredFilesChanged()), this, SLOT(filteredFilesChanged())); + connect(stackedProperties, SIGNAL(currentChanged(int)), this, SLOT(loadDynamicData())); + connect(QBtSession::instance(), SIGNAL(savePathChanged(QTorrentHandle)), this, SLOT(updateSavePath(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(metadataReceived(QTorrentHandle)), this, SLOT(updateTorrentInfos(QTorrentHandle))); + + // Downloaded pieces progress bar + downloaded_pieces = new DownloadedPiecesBar(this); + ProgressHLayout->insertWidget(1, downloaded_pieces); + // Pieces availability bar + pieces_availability = new PieceAvailabilityBar(this); + ProgressHLayout_2->insertWidget(1, pieces_availability); + // Tracker list + trackerList = new TrackerList(this); +#if LIBTORRENT_VERSION_MINOR > 14 + trackerUpButton->setVisible(false); + trackerDownButton->setVisible(false); +#else + connect(trackerUpButton, SIGNAL(clicked()), trackerList, SLOT(moveSelectionUp())); + connect(trackerDownButton, SIGNAL(clicked()), trackerList, SLOT(moveSelectionDown())); +#endif + horizontalLayout_trackers->insertWidget(0, trackerList); + // Peers list + peersList = new PeerListWidget(this); + peerpage_layout->addWidget(peersList); + // Tab bar + m_tabBar = new PropTabBar(); + verticalLayout->addLayout(m_tabBar); + connect(m_tabBar, SIGNAL(tabChanged(int)), stackedProperties, SLOT(setCurrentIndex(int))); + connect(m_tabBar, SIGNAL(visibilityToggled(bool)), SLOT(setVisibility(bool))); + // Dynamic data refresher + refreshTimer = new QTimer(this); + connect(refreshTimer, SIGNAL(timeout()), this, SLOT(loadDynamicData())); + refreshTimer->start(3000); // 3sec +} + +PropertiesWidget::~PropertiesWidget() { + qDebug() << Q_FUNC_INFO << "ENTER"; + delete refreshTimer; + delete trackerList; + delete peersList; + delete downloaded_pieces; + delete pieces_availability; + delete PropListModel; + delete PropDelegate; + delete m_tabBar; + qDebug() << Q_FUNC_INFO << "EXIT"; +} + +void PropertiesWidget::showPiecesAvailability(bool show) { + avail_pieces_lbl->setVisible(show); + pieces_availability->setVisible(show); + avail_average_lbl->setVisible(show); + if(show || (!show && !downloaded_pieces->isVisible())) + line_2->setVisible(show); +} + +void PropertiesWidget::showPiecesDownloaded(bool show) { + downloaded_pieces_lbl->setVisible(show); + downloaded_pieces->setVisible(show); + progress_lbl->setVisible(show); + if(show || (!show && !pieces_availability->isVisible())) + line_2->setVisible(show); +} + +void PropertiesWidget::setVisibility(bool visible) { + if(!visible && state == VISIBLE) { + QSplitter *hSplitter = static_cast(parentWidget()); + stackedProperties->setVisible(false); + slideSizes = hSplitter->sizes(); + hSplitter->handle(1)->setVisible(false); + hSplitter->handle(1)->setDisabled(true); + QList sizes = QList() << hSplitter->geometry().height()-30 << 30; + hSplitter->setSizes(sizes); + state = REDUCED; + return; + } + + if(visible && state == REDUCED) { + stackedProperties->setVisible(true); + QSplitter *hSplitter = static_cast(parentWidget()); + hSplitter->handle(1)->setDisabled(false); + hSplitter->handle(1)->setVisible(true); + hSplitter->setSizes(slideSizes); + state = VISIBLE; + // Force refresh + loadDynamicData(); + } +} + +void PropertiesWidget::clear() { + qDebug("Clearing torrent properties"); + save_path->clear(); + lbl_creationDate->clear(); + pieceSize_lbl->clear(); + hash_lbl->clear(); + comment_text->clear(); + progress_lbl->clear(); + trackerList->clear(); + downloaded_pieces->clear(); + pieces_availability->clear(); + avail_average_lbl->clear(); + wasted->clear(); + upTotal->clear(); + dlTotal->clear(); + peersList->clear(); + lbl_uplimit->clear(); + lbl_dllimit->clear(); + lbl_elapsed->clear(); + lbl_connections->clear(); + reannounce_lbl->clear(); + shareRatio->clear(); + listWebSeeds->clear(); + m_contentFilerLine->clear(); + PropListModel->model()->clear(); + showPiecesAvailability(false); + showPiecesDownloaded(false); + setEnabled(false); +} + +QTorrentHandle PropertiesWidget::getCurrentTorrent() const { + return h; +} + +void PropertiesWidget::updateSavePath(const QTorrentHandle& _h) { + if(h.is_valid() && h == _h) { + QString p; + if(h.has_metadata() && h.num_files() == 1) { + p = h.firstFileSavePath(); + } else { + p = TorrentPersistentData::getSavePath(h.hash()); + if(p.isEmpty()) + p = h.save_path(); + } +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + p = p.replace("/", "\\"); +#endif + save_path->setText(p); + } +} + +void PropertiesWidget::updateTorrentInfos(const QTorrentHandle& _h) { + if(h.is_valid() && h == _h) { + loadTorrentInfos(h); + } +} + +void PropertiesWidget::loadTorrentInfos(const QTorrentHandle &_h) { + clear(); + h = _h; + if(!h.is_valid()) { + clear(); + return; + } + setEnabled(true); + + try { + // Save path + updateSavePath(h); + changeSavePathButton->setEnabled(h.has_metadata()); + // Hash + hash_lbl->setText(h.hash()); + PropListModel->model()->clear(); + if(h.has_metadata()) { + // Creation date + lbl_creationDate->setText(h.creation_date()); + // Pieces size + pieceSize_lbl->setText(misc::friendlyUnit(h.piece_length())); + // Comment + comment_text->setHtml(misc::parseHtmlLinks(h.comment())); + // URL seeds + loadUrlSeeds(); + // List files in torrent + PropListModel->model()->setupModelData(h.get_torrent_info()); + } + } catch(invalid_handle& e) { + + } + // Load dynamic data + loadDynamicData(); +} + +void PropertiesWidget::readSettings() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + // Restore splitter sizes + QStringList sizes_str = settings.value(QString::fromUtf8("TorrentProperties/SplitterSizes"), QString()).toString().split(","); + if(sizes_str.size() == 2) { + slideSizes << sizes_str.first().toInt(); + slideSizes << sizes_str.last().toInt(); + QSplitter *hSplitter = static_cast(parentWidget()); + hSplitter->setSizes(slideSizes); + } + if (!filesList->header()->restoreState(settings.value("TorrentProperties/FilesListState").toByteArray())) { + filesList->header()->resizeSection(0, 400); //Default + } + const int current_tab = settings.value("TorrentProperties/CurrentTab", -1).toInt(); + m_tabBar->setCurrentIndex(current_tab); + if(!settings.value("TorrentProperties/Visible", false).toBool()) { + setVisibility(false); + } +} + +void PropertiesWidget::saveSettings() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.setValue("TorrentProperties/Visible", state==VISIBLE); + // Splitter sizes + QSplitter *hSplitter = static_cast(parentWidget()); + QList sizes; + if(state == VISIBLE) + sizes = hSplitter->sizes(); + else + sizes = slideSizes; + qDebug("Sizes: %d", sizes.size()); + if(sizes.size() == 2) { + settings.setValue(QString::fromUtf8("TorrentProperties/SplitterSizes"), QVariant(QString::number(sizes.first())+','+QString::number(sizes.last()))); + } + settings.setValue("TorrentProperties/FilesListState", filesList->header()->saveState()); + // Remember current tab + settings.setValue("TorrentProperties/CurrentTab", m_tabBar->currentIndex()); +} + +void PropertiesWidget::reloadPreferences() { + // Take program preferences into consideration + peersList->updatePeerHostNameResolutionState(); + peersList->updatePeerCountryResolutionState(); +} + +void PropertiesWidget::loadDynamicData() { + // Refresh only if the torrent handle is valid and if visible + if(!h.is_valid() || main_window->getCurrentTabWidget() != transferList || state != VISIBLE) return; + try { + // Transfer infos + if(stackedProperties->currentIndex() == PropTabBar::MAIN_TAB) { + wasted->setText(misc::friendlyUnit(h.total_failed_bytes()+h.total_redundant_bytes())); + upTotal->setText(misc::friendlyUnit(h.all_time_upload()) + " ("+misc::friendlyUnit(h.total_payload_upload())+" "+tr("this session")+")"); + dlTotal->setText(misc::friendlyUnit(h.all_time_download()) + " ("+misc::friendlyUnit(h.total_payload_download())+" "+tr("this session")+")"); + if(h.upload_limit() <= 0) + lbl_uplimit->setText(QString::fromUtf8("∞")); + else + lbl_uplimit->setText(misc::friendlyUnit(h.upload_limit())+tr("/s", "/second (i.e. per second)")); + if(h.download_limit() <= 0) + lbl_dllimit->setText(QString::fromUtf8("∞")); + else + lbl_dllimit->setText(misc::friendlyUnit(h.download_limit())+tr("/s", "/second (i.e. per second)")); + QString elapsed_txt = misc::userFriendlyDuration(h.active_time()); + if(h.is_seed()) { + elapsed_txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(h.seeding_time()))+")"; + } + lbl_elapsed->setText(elapsed_txt); + if(h.connections_limit() > 0) + lbl_connections->setText(QString::number(h.num_connections())+" ("+tr("%1 max", "e.g. 10 max").arg(QString::number(h.connections_limit()))+")"); + else + lbl_connections->setText(QString::number(h.num_connections())); + // Update next announce time + reannounce_lbl->setText(h.next_announce()); + // Update ratio info + const qreal ratio = QBtSession::instance()->getRealRatio(h.hash()); + if(ratio > QBtSession::MAX_RATIO) + shareRatio->setText(QString::fromUtf8("∞")); + else + shareRatio->setText(QString(QByteArray::number(ratio, 'f', 2))); + if(!h.is_seed()) { + showPiecesDownloaded(true); + // Downloaded pieces + bitfield bf(h.get_torrent_info().num_pieces(), 0); + h.downloading_pieces(bf); + downloaded_pieces->setProgress(h.pieces(), bf); + // Pieces availability + if(h.has_metadata() && !h.is_paused() && !h.is_queued() && !h.is_checking()) { + showPiecesAvailability(true); + std::vector avail; + h.piece_availability(avail); + pieces_availability->setAvailability(avail); + avail_average_lbl->setText(QString::number(h.distributed_copies(), 'f', 3)); + } else { + showPiecesAvailability(false); + } + // Progress + qreal progress = h.progress()*100.; + if(progress > 99.94 && progress < 100.) + progress = 99.9; + progress_lbl->setText(QString::number(progress, 'f', 1)+"%"); + } else { + showPiecesAvailability(false); + showPiecesDownloaded(false); + } + return; + } + if(stackedProperties->currentIndex() == PropTabBar::TRACKERS_TAB) { + // Trackers + trackerList->loadTrackers(); + return; + } + if(stackedProperties->currentIndex() == PropTabBar::PEERS_TAB) { + // Load peers + peersList->loadPeers(h); + return; + } + if(stackedProperties->currentIndex() == PropTabBar::FILES_TAB) { + // Files progress + if(h.is_valid() && h.has_metadata()) { + qDebug("Updating priorities in files tab"); + filesList->setUpdatesEnabled(false); + std::vector fp; + h.file_progress(fp); + PropListModel->model()->updateFilesPriorities(h.file_priorities()); + PropListModel->model()->updateFilesProgress(fp); + filesList->setUpdatesEnabled(true); + } + } + } catch(invalid_handle e) {} +} + +void PropertiesWidget::loadUrlSeeds(){ + listWebSeeds->clear(); + qDebug("Loading URL seeds"); + const QStringList hc_seeds = h.url_seeds(); + // Add url seeds + foreach(const QString &hc_seed, hc_seeds){ + qDebug("Loading URL seed: %s", qPrintable(hc_seed)); + new QListWidgetItem(hc_seed, listWebSeeds); + } +} + +void PropertiesWidget::openDoubleClickedFile(QModelIndex index) { + if(!index.isValid()) return; + if(!h.is_valid() || !h.has_metadata()) return; + if(PropListModel->getType(index) == TorrentFileItem::TFILE) { + int i = PropListModel->getFileIndex(index); + const QDir saveDir(h.save_path()); + const QString filename = h.filepath_at(i); + const QString file_path = QDir::cleanPath(saveDir.absoluteFilePath(filename)); + qDebug("Trying to open file at %s", qPrintable(file_path)); +#if LIBTORRENT_VERSION_MINOR > 14 + // Flush data + h.flush_cache(); +#endif + if(QFile::exists(file_path)) { + QDesktopServices::openUrl(QUrl::fromLocalFile(file_path)); + } else { + QMessageBox::warning(this, tr("I/O Error"), tr("This file does not exist yet.")); + } + } else { + // FOLDER + QStringList path_items; + path_items << index.data().toString(); + QModelIndex parent = PropListModel->parent(index); + while(parent.isValid()) { + path_items.prepend(parent.data().toString()); + parent = PropListModel->parent(parent); + } + const QDir saveDir(h.save_path()); + const QString filename = path_items.join(QDir::separator()); + const QString file_path = QDir::cleanPath(saveDir.absoluteFilePath(filename)); + qDebug("Trying to open folder at %s", qPrintable(file_path)); +#if LIBTORRENT_VERSION_MINOR > 14 + // Flush data + h.flush_cache(); +#endif + if(QFile::exists(file_path)) { + QDesktopServices::openUrl(QUrl::fromLocalFile(file_path)); + } else { + QMessageBox::warning(this, tr("I/O Error"), tr("This folder does not exist yet.")); + } + } +} + +void PropertiesWidget::displayFilesListMenu(const QPoint&){ + QMenu myFilesLlistMenu; + QModelIndexList selectedRows = filesList->selectionModel()->selectedRows(0); + QAction *actRename = 0; + if(selectedRows.size() == 1) { + actRename = myFilesLlistMenu.addAction(IconProvider::instance()->getIcon("edit-rename"), tr("Rename...")); + myFilesLlistMenu.addSeparator(); + } + QMenu subMenu; +#if LIBTORRENT_VERSION_MINOR > 15 + if(!h.status(0x0).is_seeding) { +#else + if(!static_cast(h).is_seed()) { +#endif + subMenu.setTitle(tr("Priority")); + subMenu.addAction(actionNot_downloaded); + subMenu.addAction(actionNormal); + subMenu.addAction(actionHigh); + subMenu.addAction(actionMaximum); + myFilesLlistMenu.addMenu(&subMenu); + } + // Call menu + const QAction *act = myFilesLlistMenu.exec(QCursor::pos()); + if(act) { + if(act == actRename) { + renameSelectedFile(); + } else { + int prio = 1; + if(act == actionHigh) { + prio = prio::HIGH; + } else { + if(act == actionMaximum) { + prio = prio::MAXIMUM; + } else { + if(act == actionNot_downloaded) { + prio = prio::IGNORED; + } + } + } + qDebug("Setting files priority"); + foreach(QModelIndex index, selectedRows) { + qDebug("Setting priority(%d) for file at row %d", prio, index.row()); + PropListModel->setData(PropListModel->index(index.row(), PRIORITY, index.parent()), prio); + } + // Save changes + filteredFilesChanged(); + } + } +} + +void PropertiesWidget::renameSelectedFile() { + const QModelIndexList selectedIndexes = filesList->selectionModel()->selectedRows(0); + Q_ASSERT(selectedIndexes.size() == 1); + const QModelIndex index = selectedIndexes.first(); + // Ask for new name + bool ok; + QString new_name_last = QInputDialog::getText(this, tr("Rename the file"), + tr("New name:"), QLineEdit::Normal, + index.data().toString(), &ok); + if (ok && !new_name_last.isEmpty()) { + if(!misc::isValidFileSystemName(new_name_last)) { + QMessageBox::warning(this, tr("The file could not be renamed"), + tr("This file name contains forbidden characters, please choose a different one."), + QMessageBox::Ok); + return; + } + if(PropListModel->getType(index) == TorrentFileItem::TFILE) { + // File renaming + const int file_index = PropListModel->getFileIndex(index); + if(!h.is_valid() || !h.has_metadata()) return; + QString old_name = h.filepath_at(file_index); + old_name = old_name.replace("\\", "/"); + if(old_name.endsWith(".!qB") && !new_name_last.endsWith(".!qB")) { + new_name_last += ".!qB"; + } + QStringList path_items = old_name.split("/"); + path_items.removeLast(); + path_items << new_name_last; + QString new_name = path_items.join("/"); + if(old_name == new_name) { + qDebug("Name did not change"); + return; + } + new_name = QDir::cleanPath(new_name); + // Check if that name is already used + for(int i=0; isetData(index, new_name_last); + } else { + // Folder renaming + QStringList path_items; + path_items << index.data().toString(); + QModelIndex parent = PropListModel->parent(index); + while(parent.isValid()) { + path_items.prepend(parent.data().toString()); + parent = PropListModel->parent(parent); + } + const QString old_path = path_items.join("/"); + path_items.removeLast(); + path_items << new_name_last; + QString new_path = path_items.join("/"); + if(!new_path.endsWith("/")) new_path += "/"; + // Check for overwriting + const int num_files = h.num_files(); + for(int i=0; isetData(index, new_name_last); + // Remove old folder + const QDir old_folder(h.save_path()+"/"+old_path); + int timeout = 10; + while(!QDir().rmpath(old_folder.absolutePath()) && timeout > 0) { + // XXX: We should not sleep here (freezes the UI for 1 second) + SleeperThread::msleep(100); + --timeout; + } + } + } +} + +void PropertiesWidget::askWebSeed(){ + bool ok; + // Ask user for a new url seed + const QString url_seed = QInputDialog::getText(this, tr("New url seed", "New HTTP source"), + tr("New url seed:"), QLineEdit::Normal, + QString::fromUtf8("http://www."), &ok); + if(!ok) return; + qDebug("Adding %s web seed", qPrintable(url_seed)); + if(!listWebSeeds->findItems(url_seed, Qt::MatchFixedString).empty()) { + QMessageBox::warning(this, tr("qBittorrent"), + tr("This url seed is already in the list."), + QMessageBox::Ok); + return; + } + h.add_url_seed(url_seed); + // Refresh the seeds list + loadUrlSeeds(); +} + +void PropertiesWidget::deleteSelectedUrlSeeds(){ + const QList selectedItems = listWebSeeds->selectedItems(); + bool change = false; + foreach(const QListWidgetItem *item, selectedItems){ + QString url_seed = item->text(); + h.remove_url_seed(url_seed); + change = true; + } + if(change){ + // Refresh list + loadUrlSeeds(); + } +} + +bool PropertiesWidget::applyPriorities() { + qDebug("Saving files priorities"); + const std::vector priorities = PropListModel->model()->getFilesPriorities(h.get_torrent_info().num_files()); + // Save first/last piece first option state + bool first_last_piece_first = h.first_last_piece_first(); + // Prioritize the files + qDebug("prioritize files: %d", priorities[0]); + h.prioritize_files(priorities); + // Restore first/last piece first option if necessary + if(first_last_piece_first) + h.prioritize_first_last_piece(true); + return true; +} + + +void PropertiesWidget::on_changeSavePathButton_clicked() { + if(!h.is_valid()) return; + QString new_path; + if(h.has_metadata() && h.num_files() == 1) { + new_path = QFileDialog::getSaveFileName(this, tr("Choose save path"), h.firstFileSavePath()); + } else { + const QDir saveDir(TorrentPersistentData::getSavePath(h.hash())); + new_path = QFileDialog::getExistingDirectory(this, tr("Choose save path"), saveDir.absolutePath(), + QFileDialog::DontConfirmOverwrite|QFileDialog::ShowDirsOnly|QFileDialog::HideNameFilterDetails); + } + if(!new_path.isEmpty()){ + // Check if savePath exists + QString save_path_dir = new_path.replace("\\", "/"); + QString new_file_name; + if(h.has_metadata() && h.num_files() == 1) { + new_file_name = misc::fileName(save_path_dir); // New file name + save_path_dir = misc::branchPath(save_path_dir, true); // Skip file name + } + QDir savePath(misc::expandPath(save_path_dir)); + // Actually move storage + if(!QBtSession::instance()->useTemporaryFolder() || h.is_seed()) { + if(!savePath.exists()) savePath.mkpath(savePath.absolutePath()); + h.move_storage(savePath.absolutePath()); + } + // Update save_path in dialog + QString display_path; + if(h.has_metadata() && h.num_files() == 1) { + // Rename the file + Q_ASSERT(!new_file_name.isEmpty()); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + if(h.filename_at(0).compare(new_file_name, Qt::CaseInsensitive) != 0) { +#else + if(h.filename_at(0).compare(new_file_name, Qt::CaseSensitive) != 0) { +#endif + qDebug("Renaming single file to %s", qPrintable(new_file_name)); + h.rename_file(0, new_file_name); + // Also rename it in the files list model + PropListModel->setData(PropListModel->index(0, 0), new_file_name); + } + display_path = h.firstFileSavePath(); + } else { + display_path = savePath.absolutePath(); + } +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + display_path = display_path.replace("/", "\\"); +#endif + save_path->setText(display_path); + } +} + +void PropertiesWidget::filteredFilesChanged() { + if(h.is_valid()) { + applyPriorities(); + } +} diff --git a/src/properties/propertieswidget.h b/src/properties/propertieswidget.h new file mode 100644 index 000000000..9e656fbd3 --- /dev/null +++ b/src/properties/propertieswidget.h @@ -0,0 +1,115 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PROPERTIESWIDGET_H +#define PROPERTIESWIDGET_H + +#include +#include "ui_propertieswidget.h" +#include "qtorrenthandle.h" + + +class TransferListWidget; +class TorrentFilesFilterModel; +class PropListDelegate; +class torrent_file; +class PeerListWidget; +class TrackerList; +class MainWindow; +class DownloadedPiecesBar; +class PieceAvailabilityBar; +class PropTabBar; +class LineEdit; + +QT_BEGIN_NAMESPACE +class QAction; +class QTimer; +QT_END_NAMESPACE + +class PropertiesWidget : public QWidget, private Ui::PropertiesWidget { + Q_OBJECT + Q_DISABLE_COPY(PropertiesWidget) + +public: + enum SlideState {REDUCED, VISIBLE}; + +public: + PropertiesWidget(QWidget *parent, MainWindow* main_window, TransferListWidget *transferList); + ~PropertiesWidget(); + QTorrentHandle getCurrentTorrent() const; + TrackerList* getTrackerList() const { return trackerList; } + PeerListWidget* getPeerList() const { return peersList; } + QTreeView* getFilesList() const { return filesList; } + +protected: + QPushButton* getButtonFromIndex(int index); + bool applyPriorities(); + +protected slots: + void loadTorrentInfos(const QTorrentHandle &h); + void updateTorrentInfos(const QTorrentHandle &h); + void loadUrlSeeds(); + void askWebSeed(); + void deleteSelectedUrlSeeds(); + void displayFilesListMenu(const QPoint& pos); + void on_changeSavePathButton_clicked(); + void filteredFilesChanged(); + void showPiecesDownloaded(bool show); + void showPiecesAvailability(bool show); + void renameSelectedFile(); + +public slots: + void setVisibility(bool visible); + void loadDynamicData(); + void clear(); + void readSettings(); + void saveSettings(); + void reloadPreferences(); + void openDoubleClickedFile(QModelIndex); + void updateSavePath(const QTorrentHandle& h); + +private: + TransferListWidget *transferList; + MainWindow *main_window; + QTorrentHandle h; + QTimer *refreshTimer; + SlideState state; + TorrentFilesFilterModel *PropListModel; + PropListDelegate *PropDelegate; + PeerListWidget *peersList; + TrackerList *trackerList; + QList slideSizes; + DownloadedPiecesBar *downloaded_pieces; + PieceAvailabilityBar *pieces_availability; + PropTabBar *m_tabBar; + LineEdit *m_contentFilerLine; +}; + +#endif // PROPERTIESWIDGET_H diff --git a/src/properties/propertieswidget.ui b/src/properties/propertieswidget.ui new file mode 100644 index 000000000..55371f57e --- /dev/null +++ b/src/properties/propertieswidget.ui @@ -0,0 +1,891 @@ + + + PropertiesWidget + + + + 0 + 0 + 540 + 274 + + + + + 8 + + + + Form + + + + 0 + + + 0 + + + + + 0 + + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + true + + + + + 0 + 0 + 520 + 373 + + + + + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Downloaded: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 50 + 16777215 + + + + 0.0% + + + Qt::AlignCenter + + + 0 + + + + + + + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Availability: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + 16777215 + + + + 0.0 + + + Qt::AlignCenter + + + + + + + + + Qt::Horizontal + + + + + + + Transfer + + + + + + Uploaded: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 0 Kb + + + + + + + UP limit: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + Share ratio: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 1.0 + + + + + + + Downloaded: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 0 Kb + + + + + + + DL limit: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + Connections: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 0 + + + + + + + Wasted: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 0 kb + + + + + + + Time active: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + Reannounce in: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + + + + + + + Information + + + + + + + 0 + 0 + + + + Save path: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + 0 + 0 + + + + path + + + + + + + + 22 + 15 + + + + ... + + + false + + + + + + + Qt::Horizontal + + + + 40 + 14 + + + + + + + + + + + 0 + 0 + + + + Created on: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + 0 + 0 + + + + date + + + + + + + Qt::Horizontal + + + + 40 + 14 + + + + + + + + + + + 0 + 0 + + + + Torrent hash: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + 0 + 0 + + + + hash + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + Qt::Horizontal + + + + 40 + 14 + + + + + + + + + + Pieces size: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + 0 + 0 + + + + piece size + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + Qt::Horizontal + + + + 40 + 14 + + + + + + + + + + Comment: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:8pt; font-weight:400; font-style:normal;"> +<table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> +<tr> +<td style="border: none;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu';"></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu';"></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu';"></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></td></tr></table></body></html> + + + true + + + true + + + + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 31 + 27 + + + + + 31 + 27 + + + + + 31 + 27 + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 28 + + + + + + + + + 31 + 27 + + + + + 31 + 27 + + + + + 31 + 27 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + + + 6 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 32 + 32 + + + + + + + + + + + + 32 + 32 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + 75 + true + + + + Torrent content: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::AllEditTriggers + + + QAbstractItemView::ExtendedSelection + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Select All + + + + + + + Select None + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + Qt::Horizontal + + + + + + + Normal + + + + + High + + + + + Maximum + + + + + Do not download + + + Do not download + + + + + + diff --git a/src/properties/proplistdelegate.h b/src/properties/proplistdelegate.h new file mode 100644 index 000000000..6169e1505 --- /dev/null +++ b/src/properties/proplistdelegate.h @@ -0,0 +1,202 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PROPLISTDELEGATE_H +#define PROPLISTDELEGATE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "misc.h" +#include "propertieswidget.h" + +#ifdef Q_WS_WIN +#include +#endif + +// Defines for properties list columns +enum PropColumn {NAME, PCSIZE, PROGRESS, PRIORITY}; + +class PropListDelegate: public QItemDelegate { + Q_OBJECT + +private: + PropertiesWidget *properties; + +signals: + void filteredFilesChanged() const; + +public: + PropListDelegate(PropertiesWidget* properties=0, QObject *parent=0) : QItemDelegate(parent), properties(properties){ + } + + ~PropListDelegate(){} + + void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const{ + painter->save(); + QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option); + switch(index.column()){ + case PCSIZE: + QItemDelegate::drawBackground(painter, opt, index); + QItemDelegate::drawDisplay(painter, opt, option.rect, misc::friendlyUnit(index.data().toLongLong())); + break; + case PROGRESS:{ + QStyleOptionProgressBarV2 newopt; + qreal progress = index.data().toDouble()*100.; + newopt.rect = opt.rect; + // We don't want to display 100% unless + // the torrent is really complete + if(progress > 99.94 && progress < 100.) + progress = 99.9; + newopt.text = QString(QByteArray::number(progress, 'f', 1))+QString::fromUtf8("%"); + newopt.progress = (int)progress; + newopt.maximum = 100; + newopt.minimum = 0; + newopt.state |= QStyle::State_Enabled; + newopt.textVisible = true; +#ifndef Q_WS_WIN + QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); +#else + // XXX: To avoid having the progress text on the right of the bar + QPlastiqueStyle st; + st.drawControl(QStyle::CE_ProgressBar, &newopt, painter, 0); +#endif + break; + } + case PRIORITY: { + QItemDelegate::drawBackground(painter, opt, index); + QString text = ""; + switch(index.data().toInt()) { + case -1: + text = tr("Mixed", "Mixed (priorities"); + break; + case 0: + text = tr("Not downloaded"); + break; + case 2: + text = tr("High", "High (priority)"); + break; + case 7: + text = tr("Maximum", "Maximum (priority)"); + break; + default: + text = tr("Normal", "Normal (priority)"); + break; + } + QItemDelegate::drawDisplay(painter, opt, option.rect, text); + break; + } + default: + QItemDelegate::paint(painter, option, index); + break; + } + painter->restore(); + } + + QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const{ + QVariant value = index.data(Qt::FontRole); + QFont fnt = value.isValid() ? qvariant_cast(value) : option.font; + QFontMetrics fontMetrics(fnt); + const QString text = index.data(Qt::DisplayRole).toString(); + QRect textRect = QRect(0, 0, 0, fontMetrics.lineSpacing() * (text.count(QLatin1Char('\n')) + 1)); + textRect.setHeight(textRect.height()+4); + return textRect.size(); + } + + void setEditorData(QWidget *editor, const QModelIndex &index) const { + QComboBox *combobox = static_cast(editor); + // Set combobox index + switch(index.data().toInt()) { + case 2: + combobox->setCurrentIndex(1); + break; + case 7: + combobox->setCurrentIndex(2); + break; + default: + combobox->setCurrentIndex(0); + break; + } + } + + QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex &index) const { + if(index.column() != PRIORITY) return 0; + if(properties) { + QTorrentHandle h = properties->getCurrentTorrent(); +#if LIBTORRENT_VERSION_MINOR > 15 + if(!h.is_valid() || !h.has_metadata() || h.status(0x0).is_seeding) return 0; +#else + if(!h.is_valid() || !h.has_metadata() || static_cast(h).is_seed()) return 0; +#endif + } + if(index.data().toInt() <= 0) { + // IGNORED or MIXED + return 0; + } + QComboBox* editor = new QComboBox(parent); + editor->setFocusPolicy(Qt::StrongFocus); + editor->addItem(tr("Normal", "Normal (priority)")); + editor->addItem(tr("High", "High (priority)")); + editor->addItem(tr("Maximum", "Maximum (priority)")); + return editor; + } + +public slots: + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { + QComboBox *combobox = static_cast(editor); + int value = combobox->currentIndex(); + qDebug("PropListDelegate: setModelData(%d)", value); + switch(value) { + case 1: + model->setData(index, 2); // HIGH + break; + case 2: + model->setData(index, 7); // MAX + break; + default: + model->setData(index, 1); // NORMAL + } + emit filteredFilesChanged(); + } + + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const { + qDebug("UpdateEditor Geometry called"); + editor->setGeometry(option.rect); + } + +}; + +#endif diff --git a/src/properties/proptabbar.cpp b/src/properties/proptabbar.cpp new file mode 100644 index 000000000..128d0a8cc --- /dev/null +++ b/src/properties/proptabbar.cpp @@ -0,0 +1,129 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include + +#include "proptabbar.h" +#include "iconprovider.h" + +#ifdef Q_WS_MAC +#define DEFAULT_BUTTON_CSS "QPushButton {border: 1px solid #888;border-radius: 2px; padding: 4px; margin-left: 0px; margin-right: 8px;}" +#define SELECTED_BUTTON_CSS "QPushButton {border: 1px solid #888;border-radius: 2px; padding: 4px;background-color: palette(highlight); color: palette(highlighted-text); margin-left: 0px; margin-right: 8px;}" +#else +#define DEFAULT_BUTTON_CSS "QPushButton {border: 1px solid #888;border-radius: 2px; padding: 4px; margin-left: 0px; margin-right: 3px;}" +#define SELECTED_BUTTON_CSS "QPushButton {border: 1px solid #888;border-radius: 2px; padding: 4px;background-color: palette(highlight); color: palette(highlighted-text); margin-left: 0px; margin-right: 3px;}" +#endif + +const int BTN_ICON_SIZE = 16; + +PropTabBar::PropTabBar(QWidget *parent) : + QHBoxLayout(parent), m_currentIndex(-1) +{ + m_btnGroup = new QButtonGroup(this); + setContentsMargins(0, 4, 0, 4); + // General tab + QPushButton *main_infos_button = new QPushButton(IconProvider::instance()->getIcon("document-properties"), tr("General"), parent); + main_infos_button->setShortcut(QKeySequence(QString::fromUtf8("Alt+P"))); + main_infos_button->setStyleSheet(DEFAULT_BUTTON_CSS); + main_infos_button->setIconSize(QSize(BTN_ICON_SIZE, BTN_ICON_SIZE)); + addWidget(main_infos_button); + m_btnGroup->addButton(main_infos_button, MAIN_TAB); + // Trackers tab + QPushButton *trackers_button = new QPushButton(IconProvider::instance()->getIcon("network-server"), tr("Trackers"), parent); + trackers_button->setStyleSheet(DEFAULT_BUTTON_CSS); + trackers_button->setIconSize(QSize(BTN_ICON_SIZE, BTN_ICON_SIZE)); + addWidget(trackers_button); + m_btnGroup->addButton(trackers_button, TRACKERS_TAB); + // Peers tab + QPushButton *peers_button = new QPushButton(IconProvider::instance()->getIcon("edit-find-user"), tr("Peers"), parent); + peers_button->setStyleSheet(DEFAULT_BUTTON_CSS); + peers_button->setIconSize(QSize(BTN_ICON_SIZE, BTN_ICON_SIZE)); + addWidget(peers_button); + m_btnGroup->addButton(peers_button, PEERS_TAB); + // URL seeds tab + QPushButton *urlseeds_button = new QPushButton(IconProvider::instance()->getIcon("network-server"), tr("HTTP Sources"), parent); + urlseeds_button->setStyleSheet(DEFAULT_BUTTON_CSS); + urlseeds_button->setIconSize(QSize(BTN_ICON_SIZE, BTN_ICON_SIZE)); + addWidget(urlseeds_button); + m_btnGroup->addButton(urlseeds_button, URLSEEDS_TAB); + // Files tab + QPushButton *files_button = new QPushButton(IconProvider::instance()->getIcon("inode-directory"), tr("Content"), parent); + files_button->setStyleSheet(DEFAULT_BUTTON_CSS); + files_button->setIconSize(QSize(BTN_ICON_SIZE, BTN_ICON_SIZE)); + addWidget(files_button); + m_btnGroup->addButton(files_button, FILES_TAB); + // Spacer + addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + // SIGNAL/SLOT + connect(m_btnGroup, SIGNAL(buttonClicked(int)), SLOT(setCurrentIndex(int))); + // Disable buttons focus + foreach(QAbstractButton *btn, m_btnGroup->buttons()) { + btn->setFocusPolicy(Qt::NoFocus); + } +} + +PropTabBar::~PropTabBar() { + delete m_btnGroup; +} + +int PropTabBar::currentIndex() const +{ + return m_currentIndex; +} + +void PropTabBar::setCurrentIndex(int index) +{ + if(index >= m_btnGroup->buttons().size()) + index = 0; + // If asked to hide or if the currently selected tab is clicked + if(index < 0 || m_currentIndex == index) { + if(m_currentIndex >= 0) { + m_btnGroup->button(m_currentIndex)->setStyleSheet(DEFAULT_BUTTON_CSS); + m_currentIndex = -1; + emit visibilityToggled(false); + } + return; + } + // Unselect previous tab + if(m_currentIndex >= 0) { + m_btnGroup->button(m_currentIndex)->setStyleSheet(DEFAULT_BUTTON_CSS); + } else { + // Nothing was selected, show! + emit visibilityToggled(true); + } + // Select the new button + m_btnGroup->button(index)->setStyleSheet(SELECTED_BUTTON_CSS); + m_currentIndex = index; + // Emit the signal + emit tabChanged(index); +} diff --git a/src/properties/proptabbar.h b/src/properties/proptabbar.h new file mode 100644 index 000000000..23c1d3774 --- /dev/null +++ b/src/properties/proptabbar.h @@ -0,0 +1,66 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef PROPTABBAR_H +#define PROPTABBAR_H + +#include + +QT_BEGIN_NAMESPACE +class QButtonGroup; +QT_END_NAMESPACE + +class PropTabBar : public QHBoxLayout +{ + Q_OBJECT + Q_DISABLE_COPY(PropTabBar) + +public: + enum PropertyTab {MAIN_TAB, TRACKERS_TAB, PEERS_TAB, URLSEEDS_TAB, FILES_TAB}; + +public: + explicit PropTabBar(QWidget *parent = 0); + ~PropTabBar(); + int currentIndex() const; + +signals: + void tabChanged(int index); + void visibilityToggled(bool visible); + +public slots: + void setCurrentIndex(int index); + +private: + QButtonGroup *m_btnGroup; + int m_currentIndex; + +}; + +#endif // PROPTABBAR_H diff --git a/src/properties/trackerlist.cpp b/src/properties/trackerlist.cpp new file mode 100644 index 000000000..21da95de9 --- /dev/null +++ b/src/properties/trackerlist.cpp @@ -0,0 +1,379 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "trackerlist.h" +#include "propertieswidget.h" +#include "trackersadditiondlg.h" +#include "iconprovider.h" +#include "qbtsession.h" +#include "qinisettings.h" +#include "misc.h" + +using namespace libtorrent; + +TrackerList::TrackerList(PropertiesWidget *properties): QTreeWidget(), properties(properties) { + loadSettings(); + // Graphical settings + setRootIsDecorated(false); + setAllColumnsShowFocus(true); + setItemsExpandable(false); + setSelectionMode(QAbstractItemView::ExtendedSelection); + // Context menu + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showTrackerListMenu(QPoint))); + // Set header + QStringList header; + header << tr("URL"); + header << tr("Status"); + header << tr("Peers"); + header << tr("Message"); + setHeaderItem(new QTreeWidgetItem(header)); + dht_item = new QTreeWidgetItem(QStringList("** "+tr("[DHT]")+" **")); + insertTopLevelItem(0, dht_item); + setRowColor(0, QColor("grey")); + pex_item = new QTreeWidgetItem(QStringList("** "+tr("[PeX]")+" **")); + insertTopLevelItem(1, pex_item); + setRowColor(1, QColor("grey")); + lsd_item = new QTreeWidgetItem(QStringList("** "+tr("[LSD]")+" **")); + insertTopLevelItem(2, lsd_item); + setRowColor(2, QColor("grey")); +} + +TrackerList::~TrackerList() { + saveSettings(); +} + +QList TrackerList::getSelectedTrackerItems() const { + QList selected_items = selectedItems(); + QList selected_trackers; + foreach(QTreeWidgetItem *item, selectedItems()) { + if(indexOfTopLevelItem(item) >= NB_STICKY_ITEM) { // Ignore STICKY ITEMS + selected_trackers << item; + } + } + return selected_trackers; +} + +void TrackerList::setRowColor(int row, QColor color) { + unsigned int nbColumns = columnCount(); + QTreeWidgetItem *item = topLevelItem(row); + for(unsigned int i=0; isetData(i, Qt::ForegroundRole, color); + } +} + +void TrackerList::moveSelectionUp() { +#if LIBTORRENT_VERSION_MINOR < 15 + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) { + clear(); + return; + } + QList selected_items = getSelectedTrackerItems(); + if(selected_items.isEmpty()) return; + bool change = false; + foreach(QTreeWidgetItem *item, selected_items){ + int index = indexOfTopLevelItem(item); + if(index > NB_STICKY_ITEM) { + insertTopLevelItem(index-1, takeTopLevelItem(index)); + change = true; + } + } + if(!change) return; + // Restore selection + QItemSelectionModel *selection = selectionModel(); + foreach(QTreeWidgetItem *item, selected_items) { + selection->select(indexFromItem(item), QItemSelectionModel::Rows|QItemSelectionModel::Select); + } + setSelectionModel(selection); + // Update torrent trackers + std::vector trackers; + for(int i=NB_STICKY_ITEM; idata(COL_URL, Qt::DisplayRole).toString(); + announce_entry e(tracker_url.toStdString()); + e.tier = i-NB_STICKY_ITEM; + trackers.push_back(e); + } + h.replace_trackers(trackers); + // Reannounce + h.force_reannounce(); +#endif +} + +void TrackerList::moveSelectionDown() { +#if LIBTORRENT_VERSION_MINOR < 15 + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) { + clear(); + return; + } + QList selected_items = getSelectedTrackerItems(); + if(selected_items.isEmpty()) return; + bool change = false; + for(int i=selectedItems().size()-1; i>= 0; --i) { + int index = indexOfTopLevelItem(selected_items.at(i)); + if(index < topLevelItemCount()-1) { + insertTopLevelItem(index+1, takeTopLevelItem(index)); + change = true; + } + } + if(!change) return; + // Restore selection + QItemSelectionModel *selection = selectionModel(); + foreach(QTreeWidgetItem *item, selected_items) { + selection->select(indexFromItem(item), QItemSelectionModel::Rows|QItemSelectionModel::Select); + } + setSelectionModel(selection); + // Update torrent trackers + std::vector trackers; + for(int i=NB_STICKY_ITEM; idata(COL_URL, Qt::DisplayRole).toString(); + announce_entry e(tracker_url.toStdString()); + e.tier = i-NB_STICKY_ITEM; + trackers.push_back(e); + } + h.replace_trackers(trackers); + // Reannounce + h.force_reannounce(); +#endif +} + +void TrackerList::clear() { + qDeleteAll(tracker_items.values()); + tracker_items.clear(); + dht_item->setText(COL_PEERS, ""); + dht_item->setText(COL_STATUS, ""); + dht_item->setText(COL_MSG, ""); + pex_item->setText(COL_PEERS, ""); + pex_item->setText(COL_STATUS, ""); + pex_item->setText(COL_MSG, ""); + lsd_item->setText(COL_PEERS, ""); + lsd_item->setText(COL_STATUS, ""); + lsd_item->setText(COL_MSG, ""); +} + +void TrackerList::loadStickyItems(const QTorrentHandle &h) { + // XXX: libtorrent should provide this info... + // Count peers from DHT, LSD, PeX + uint nb_dht=0, nb_lsd=0, nb_pex=0; + std::vector peers; + h.get_peer_info(peers); + std::vector::iterator it; + for(it=peers.begin(); it!=peers.end(); it++) { + if(it->source & peer_info::dht) + ++nb_dht; + if(it->source & peer_info::lsd) + ++nb_lsd; + if(it->source & peer_info::pex) + ++nb_pex; + } + // load DHT information + if(QBtSession::instance()->isDHTEnabled() && h.has_metadata() && !h.priv()) { + dht_item->setText(COL_STATUS, tr("Working")); + } else { + dht_item->setText(COL_STATUS, tr("Disabled")); + } + dht_item->setText(COL_PEERS, QString::number(nb_dht)); + if(h.has_metadata() && h.priv()) { + dht_item->setText(COL_MSG, tr("This torrent is private")); + } + // Load PeX Information + if(QBtSession::instance()->isPexEnabled()) + pex_item->setText(COL_STATUS, tr("Working")); + else + pex_item->setText(COL_STATUS, tr("Disabled")); + pex_item->setText(COL_PEERS, QString::number(nb_pex)); + // Load LSD Information + if(QBtSession::instance()->isLSDEnabled()) + lsd_item->setText(COL_STATUS, tr("Working")); + else + lsd_item->setText(COL_STATUS, tr("Disabled")); + lsd_item->setText(COL_PEERS, QString::number(nb_lsd)); +} + +void TrackerList::loadTrackers() { + // Load trackers from torrent handle + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) return; + loadStickyItems(h); + // Load actual trackers information + QHash trackers_data = QBtSession::instance()->getTrackersInfo(h.hash()); + QStringList old_trackers_urls = tracker_items.keys(); + const std::vector trackers = h.trackers(); + for(std::vector::const_iterator it = trackers.begin(); it != trackers.end(); it++) { + QString tracker_url = misc::toQString(it->url); + QTreeWidgetItem *item = tracker_items.value(tracker_url, 0); + if(!item) { + item = new QTreeWidgetItem(); + item->setText(COL_URL, tracker_url); + addTopLevelItem(item); + tracker_items[tracker_url] = item; + } else { + old_trackers_urls.removeOne(tracker_url); + } + TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); + QString error_message = data.last_message.trimmed(); +#if LIBTORRENT_VERSION_MINOR > 14 + if(it->verified) { + item->setText(COL_STATUS, tr("Working")); + item->setText(COL_MSG, ""); + } else { + if(it->updating && it->fails == 0) { + item->setText(COL_STATUS, tr("Updating...")); + item->setText(COL_MSG, ""); + } else { + if(it->fails > 0) { + item->setText(COL_STATUS, tr("Not working")); + item->setText(COL_MSG, error_message); + } else { + item->setText(COL_STATUS, tr("Not contacted yet")); + item->setText(COL_MSG, ""); + } + } + } +#else + if(data.verified) { + item->setText(COL_STATUS, tr("Working")); + item->setText(COL_MSG, ""); + } else { + if(data.fail_count > 0) { + item->setText(COL_STATUS, tr("Not working")); + item->setText(COL_MSG, error_message); + } else { + item->setText(COL_STATUS, tr("Not contacted yet")); + item->setText(COL_MSG, ""); + } + } +#endif + item->setText(COL_PEERS, QString::number(trackers_data.value(tracker_url, TrackerInfos(tracker_url)).num_peers)); + } + // Remove old trackers + foreach(const QString &tracker, old_trackers_urls) { + delete tracker_items.take(tracker); + } +} + +// Ask the user for new trackers and add them to the torrent +void TrackerList::askForTrackers(){ + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) return; + QStringList trackers = TrackersAdditionDlg::askForTrackers(h); + if(!trackers.empty()) { + foreach(const QString& tracker, trackers) { + if(tracker.trimmed().isEmpty()) continue; + announce_entry url(tracker.toStdString()); + url.tier = 0; + h.add_tracker(url); + } + // Reannounce to new trackers + h.force_reannounce(); + // Reload tracker list + loadTrackers(); + } +} + +void TrackerList::deleteSelectedTrackers(){ + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) { + clear(); + return; + } + QList selected_items = getSelectedTrackerItems(); + if(selected_items.isEmpty()) return; + QStringList urls_to_remove; + foreach(QTreeWidgetItem *item, selected_items){ + QString tracker_url = item->data(COL_URL, Qt::DisplayRole).toString(); + urls_to_remove << tracker_url; + tracker_items.remove(tracker_url); + delete item; + } + // Iterate of trackers and remove selected ones + std::vector remaining_trackers; + std::vector trackers = h.trackers(); + std::vector::iterator it; + for(it = trackers.begin(); it != trackers.end(); it++) { + if(!urls_to_remove.contains(misc::toQString((*it).url))) { + remaining_trackers.push_back(*it); + } + } + h.replace_trackers(remaining_trackers); + h.force_reannounce(); + // Reload Trackers + loadTrackers(); +} + +void TrackerList::showTrackerListMenu(QPoint) { + QTorrentHandle h = properties->getCurrentTorrent(); + if(!h.is_valid()) return; + //QList selected_items = getSelectedTrackerItems(); + QMenu menu; + // Add actions + QAction *addAct = menu.addAction(IconProvider::instance()->getIcon("list-add"), tr("Add a new tracker...")); + QAction *delAct = 0; + if(!getSelectedTrackerItems().isEmpty()) { + delAct = menu.addAction(IconProvider::instance()->getIcon("list-remove"), tr("Remove tracker")); + } + menu.addSeparator(); + QAction *reannounceAct = menu.addAction(IconProvider::instance()->getIcon("view-refresh"), tr("Force reannounce")); + QAction *act = menu.exec(QCursor::pos()); + if(act == 0) return; + if(act == addAct) { + askForTrackers(); + return; + } + if(act == delAct) { + deleteSelectedTrackers(); + return; + } + if(act == reannounceAct) { + properties->getCurrentTorrent().force_reannounce(); + return; + } +} + +void TrackerList::loadSettings() { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + if(!header()->restoreState(settings.value("TorrentProperties/Trackers/TrackerListState").toByteArray())) { + setColumnWidth(0, 300); + } +} + +void TrackerList::saveSettings() const { + QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); + settings.setValue("TorrentProperties/Trackers/TrackerListState", header()->saveState()); +} diff --git a/src/properties/trackerlist.h b/src/properties/trackerlist.h new file mode 100644 index 000000000..3389c7eb1 --- /dev/null +++ b/src/properties/trackerlist.h @@ -0,0 +1,79 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TRACKERLIST_H +#define TRACKERLIST_H + +#include +#include + +#include +#include "qtorrenthandle.h" +#include "propertieswidget.h" + +enum TrackerListColumn {COL_URL, COL_STATUS, COL_PEERS, COL_MSG}; +#define NB_STICKY_ITEM 3 + +class TrackerList: public QTreeWidget { + Q_OBJECT + Q_DISABLE_COPY(TrackerList) + +private: + PropertiesWidget *properties; + QHash tracker_items; + QTreeWidgetItem* dht_item; + QTreeWidgetItem* pex_item; + QTreeWidgetItem* lsd_item; + +public: + TrackerList(PropertiesWidget *properties); + ~TrackerList(); + +protected: + QList getSelectedTrackerItems() const; + +public slots: + void setRowColor(int row, QColor color); + + void moveSelectionUp(); + void moveSelectionDown(); + + void clear(); + void loadStickyItems(const QTorrentHandle &h); + void loadTrackers(); + void askForTrackers(); + void deleteSelectedTrackers(); + void showTrackerListMenu(QPoint); + void loadSettings(); + void saveSettings() const; + +}; + +#endif // TRACKERLIST_H diff --git a/src/properties/trackersadditiondlg.h b/src/properties/trackersadditiondlg.h new file mode 100644 index 000000000..536f64b16 --- /dev/null +++ b/src/properties/trackersadditiondlg.h @@ -0,0 +1,148 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TRACKERSADDITION_H +#define TRACKERSADDITION_H + +#include +#include +#include +#include +#include +#include "iconprovider.h" +#include "misc.h" +#include "ui_trackersadditiondlg.h" +#include "downloadthread.h" +#include "qtorrenthandle.h" + +class TrackersAdditionDlg : public QDialog, private Ui::TrackersAdditionDlg{ + Q_OBJECT + +private: + QTorrentHandle h; + +public: + TrackersAdditionDlg(QTorrentHandle h, QWidget *parent=0): QDialog(parent), h(h) { + setupUi(this); + // Icons + uTorrentListButton->setIcon(IconProvider::instance()->getIcon("download")); + // As a default, use torrentz.com link + list_url->setText("http://www.torrentz.com/announce_"+h.hash()); + list_url->setCursorPosition(0); + } + + ~TrackersAdditionDlg(){} + + QStringList newTrackers() const { + return trackers_list->toPlainText().trimmed().split("\n"); + } + +public slots: + void on_uTorrentListButton_clicked() { + uTorrentListButton->setEnabled(false); + DownloadThread *d = new DownloadThread(this); + connect(d, SIGNAL(downloadFinished(QString,QString)), SLOT(parseUTorrentList(QString,QString))); + connect(d, SIGNAL(downloadFailure(QString,QString)), SLOT(getTrackerError(QString,QString))); + //Just to show that it takes times + setCursor(Qt::WaitCursor); + d->downloadUrl("http://www.torrentz.com/announce_"+h.hash()); + } + + void parseUTorrentList(QString, QString path) { + QFile list_file(path); + if (!list_file.open(QFile::ReadOnly)) { + QMessageBox::warning(this, tr("I/O Error"), tr("Error while trying to open the downloaded file."), QMessageBox::Ok); + setCursor(Qt::ArrowCursor); + uTorrentListButton->setEnabled(true); + sender()->deleteLater(); + return; + } + QList existingTrackers; + // Load from torrent handle + std::vector tor_trackers = h.trackers(); + std::vector::iterator itr = tor_trackers.begin(); + while(itr != tor_trackers.end()) { + existingTrackers << QUrl(misc::toQString(itr->url)); + itr++; + } + // Load from current user list + QStringList tmp = trackers_list->toPlainText().split("\n"); + foreach(const QString &user_url_str, tmp) { + QUrl user_url(user_url_str); + if(!existingTrackers.contains(user_url)) + existingTrackers << user_url; + } + // Add new trackers to the list + if(!trackers_list->toPlainText().isEmpty() && !trackers_list->toPlainText().endsWith("\n")) + trackers_list->insertPlainText("\n"); + int nb = 0; + while (!list_file.atEnd()) { + const QByteArray line = list_file.readLine().trimmed(); + if(line.isEmpty()) continue; + QUrl url(line); + if (!existingTrackers.contains(url)) { + trackers_list->insertPlainText(line + "\n"); + ++nb; + } + } + // Clean up + list_file.close(); + list_file.remove(); + //To restore the cursor ... + setCursor(Qt::ArrowCursor); + uTorrentListButton->setEnabled(true); + // Display information message if necessary + if(nb == 0) { + QMessageBox::information(this, tr("No change"), tr("No additional trackers were found."), QMessageBox::Ok); + } + sender()->deleteLater(); + } + + void getTrackerError(const QString&, const QString &error) { + //To restore the cursor ... + setCursor(Qt::ArrowCursor); + uTorrentListButton->setEnabled(true); + QMessageBox::warning(this, tr("Download error"), tr("The trackers list could not be downloaded, reason: %1").arg(error), QMessageBox::Ok); + sender()->deleteLater(); + } + +public: + + static QStringList askForTrackers(QTorrentHandle h) { + QStringList trackers; + TrackersAdditionDlg dlg(h); + if(dlg.exec() == QDialog::Accepted) { + return dlg.newTrackers(); + } + return trackers; + } +}; + +#endif diff --git a/src/properties/trackersadditiondlg.ui b/src/properties/trackersadditiondlg.ui new file mode 100644 index 000000000..c4c3c0a73 --- /dev/null +++ b/src/properties/trackersadditiondlg.ui @@ -0,0 +1,121 @@ + + + TrackersAdditionDlg + + + + 0 + 0 + 367 + 274 + + + + Trackers addition dialog + + + + + + List of trackers to add (one per line): + + + + + + + QTextEdit::NoWrap + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:10pt;"></p></body></html> + + + false + + + + + + + µTorrent compatible list URL: + + + + + + + + + + + + + 31 + 31 + + + + + 31 + 31 + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + TrackersAdditionDlg + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + TrackersAdditionDlg + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qbittorrent.exe.manifest b/src/qbittorrent.exe.manifest new file mode 100644 index 000000000..2f99a7ec8 --- /dev/null +++ b/src/qbittorrent.exe.manifest @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/qbittorrent.ico b/src/qbittorrent.ico new file mode 100644 index 0000000000000000000000000000000000000000..e8ac738c1a1814d4c03c63ab190ff18a0c9ca27a GIT binary patch literal 99678 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 PHUc&RHUc&Rbryl2I8bw# literal 0 HcmV?d00001 diff --git a/src/qbittorrent.rc b/src/qbittorrent.rc new file mode 100644 index 000000000..7005b540f --- /dev/null +++ b/src/qbittorrent.rc @@ -0,0 +1,2 @@ +IDI_ICON1 ICON DISCARDABLE "qbittorrent.ico" +IDI_ICON2 ICON DISCARDABLE "qbittorrent_file.ico" diff --git a/src/qbittorrent_file.ico b/src/qbittorrent_file.ico new file mode 100644 index 0000000000000000000000000000000000000000..30596214a0b3fb72715d4f5204708b5abb9ebc44 GIT binary patch literal 99678 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 + +class QIniSettings : public QSettings { + Q_OBJECT + +public: + QIniSettings(const QString &organization, const QString &application = QString(), QObject *parent = 0 ): +#ifdef Q_WS_WIN + QSettings(QSettings::IniFormat, QSettings::UserScope, organization, application, parent) +#else + QSettings(organization, application, parent) +#endif + { + + } + + QIniSettings(const QString &fileName, Format format, QObject *parent = 0 ) : QSettings(fileName, format, parent) { + + } + + QIniSettings& operator =(const QIniSettings &other) { + Q_UNUSED(other); + Q_ASSERT(0); + return *this; + } + +#ifdef Q_WS_WIN + QVariant value(const QString & key, const QVariant &defaultValue = QVariant()) const { + QString key_tmp(key); + QVariant ret = QSettings::value(key_tmp); + if(ret.isNull()) + return defaultValue; + return ret; + } + + void setValue(const QString &key, const QVariant &val) { + QString key_tmp(key); + if(format() == QSettings::NativeFormat) + key_tmp = key_tmp.replace("\\", "/"); + QSettings::setValue(key_tmp, val); + } +#endif +}; + +#endif // QINISETTINGS_H diff --git a/src/qmacapplication.cpp b/src/qmacapplication.cpp new file mode 100644 index 000000000..5187df2aa --- /dev/null +++ b/src/qmacapplication.cpp @@ -0,0 +1,59 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include "qmacapplication.h" + +QMacApplication::QMacApplication(QString appid, int &argc, char** argv) : + QtSingleApplication(appid, argc, argv) +{ + qDebug("Constructing a QMacApplication to receive file open events"); +} + +bool QMacApplication::event(QEvent * ev) { + switch (ev->type()) { + case QEvent::FileOpen: + { + QString path = static_cast(ev)->file(); + if(path.isEmpty()) { + // Get the url instead + path = static_cast(ev)->url().toString(); + } + qDebug("Received a mac file open event: %s", qPrintable(path)); + emit newFileOpenMacEvent(path); + return true; + } + default: + return QtSingleApplication::event(ev); + } +} + diff --git a/src/qmacapplication.h b/src/qmacapplication.h new file mode 100644 index 000000000..55b6e18fd --- /dev/null +++ b/src/qmacapplication.h @@ -0,0 +1,49 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ +#ifndef QMACAPPLICATION_H +#define QMACAPPLICATION_H + +#include "qtsingleapplication.h" + +class QMacApplication : public QtSingleApplication +{ + Q_OBJECT +public: + explicit QMacApplication(QString appid, int &argc, char** argv); + +signals: + void newFileOpenMacEvent(const QString &path); + +protected: + bool event(QEvent *); + +}; + +#endif // QMACAPPLICATION_H diff --git a/src/qtlibtorrent/bandwidthscheduler.h b/src/qtlibtorrent/bandwidthscheduler.h new file mode 100644 index 000000000..a7baabfab --- /dev/null +++ b/src/qtlibtorrent/bandwidthscheduler.h @@ -0,0 +1,113 @@ +#ifndef BANDWIDTHSCHEDULER_H +#define BANDWIDTHSCHEDULER_H + +#include +#include +#include +#include "preferences.h" +#include + +class BandwidthScheduler: public QTimer { + Q_OBJECT + +private: + bool in_alternative_mode; + +public: + BandwidthScheduler(QObject *parent): QTimer(parent), in_alternative_mode(false) { + Q_ASSERT(Preferences().isSchedulerEnabled()); + // Signal shot, we call start() again manually + setSingleShot(true); + // Connect Signals/Slots + connect(this, SIGNAL(timeout()), this, SLOT(switchMode())); + } + +public slots: + void start() { + const Preferences pref; + Q_ASSERT(pref.isSchedulerEnabled()); + + QTime startAltSpeeds = pref.getSchedulerStartTime(); + QTime endAltSpeeds = pref.getSchedulerEndTime(); + if(startAltSpeeds == endAltSpeeds) { + std::cerr << "Error: bandwidth scheduler have the same start time and end time." << std::endl; + std::cerr << "The bandwidth scheduler will be disabled" << std::endl; + stop(); + emit switchToAlternativeMode(false); + return; + } + + // Determine what the closest QTime is + QTime now = QTime::currentTime(); + uint time_to_start = secsTo(now, startAltSpeeds); + uint time_to_end = secsTo(now, endAltSpeeds); + if(time_to_end < time_to_start) { + // We should be in alternative mode + in_alternative_mode = true; + // Start counting + QTimer::start(time_to_end*1000); + } else { + // We should be in normal mode + in_alternative_mode = false; + // Start counting + QTimer::start(time_to_start*1000); + } + // Send signal to notify BTSession + emit switchToAlternativeMode(in_alternative_mode); + } + + void switchMode() { + const Preferences pref; + // Get the day this mode was started (either today or yesterday) + QDate current_date = QDateTime::currentDateTime().toLocalTime().date(); + int day = current_date.dayOfWeek(); + if(in_alternative_mode) { + // It is possible that starttime was yesterday + if(QTime::currentTime().secsTo(pref.getSchedulerStartTime()) > 0) { + current_date.addDays(-1); // Go to yesterday + day = current_date.day(); + } + } + // Check if the day is in scheduler days + // Notify BTSession only if necessary + switch(pref.getSchedulerDays()) { + case EVERY_DAY: + emit switchToAlternativeMode(!in_alternative_mode); + break; + case WEEK_ENDS: + if(day == Qt::Saturday || day == Qt::Sunday) + emit switchToAlternativeMode(!in_alternative_mode); + break; + case WEEK_DAYS: + if(day != Qt::Saturday && day != Qt::Sunday) + emit switchToAlternativeMode(!in_alternative_mode); + break; + default: + // Convert our enum index to Qt enum index + int scheduler_day = ((int)pref.getSchedulerDays()) - 2; + if(day == scheduler_day) + emit switchToAlternativeMode(!in_alternative_mode); + break; + } + // Call start again + start(); + } + +signals: + void switchToAlternativeMode(bool alternative); + +private: + // Qt function can return negative values and we + // don't want that + uint secsTo(QTime now, QTime t) { + int diff = now.secsTo(t); + if(diff < 0) { + // 86400 seconds in a day + diff += 86400; + } + Q_ASSERT(diff >= 0); + return diff; + } +}; + +#endif // BANDWIDTHSCHEDULER_H diff --git a/src/qtlibtorrent/filterparserthread.h b/src/qtlibtorrent/filterparserthread.h new file mode 100644 index 000000000..08a46cfd6 --- /dev/null +++ b/src/qtlibtorrent/filterparserthread.h @@ -0,0 +1,429 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef FILTERPARSERTHREAD_H +#define FILTERPARSERTHREAD_H + +#include +#include +#include +#include +#include + +#include +#include + +using namespace std; + +// P2B Stuff +#include +#ifdef Q_WS_WIN +#include +#else +#include +#endif +// End of P2B stuff + +class FilterParserThread : public QThread { + Q_OBJECT + +public: + FilterParserThread(QObject* parent, libtorrent::session *s) : QThread(parent), s(s), abort(false) { + + } + + ~FilterParserThread(){ + abort = true; + wait(); + } + + // Parser for eMule ip filter in DAT format + int parseDATFilterFile(QString filePath) { + int ruleCount = 0; + QFile file(filePath); + if (file.exists()){ + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + std::cerr << "I/O Error: Could not open ip filer file in read mode." << std::endl; + return ruleCount; + } + unsigned int nbLine = 0; + while (!file.atEnd() && !abort) { + ++nbLine; + QByteArray line = file.readLine(); + // Ignoring empty lines + line = line.trimmed(); + if(line.isEmpty()) continue; + // Ignoring commented lines + if(line.startsWith('#') || line.startsWith("//")) continue; + + // Line should be splitted by commas + QList partsList = line.split(','); + const uint nbElem = partsList.size(); + + // IP Range should be splitted by a dash + QList IPs = partsList.first().split('-'); + if(IPs.size() != 2) { + qDebug("Ipfilter.dat: line %d is malformed.", nbLine); + qDebug("Line was %s", line.constData()); + continue; + } + + boost::system::error_code ec; + const QString strStartIP = cleanupIPAddress(IPs.at(0)); + if(strStartIP.isEmpty()) { + qDebug("Ipfilter.dat: line %d is malformed.", nbLine); + qDebug("Start IP of the range is malformated: %s", qPrintable(strStartIP)); + continue; + } + libtorrent::address startAddr = libtorrent::address::from_string(qPrintable(strStartIP), ec); + if(ec) { + qDebug("Ipfilter.dat: line %d is malformed.", nbLine); + qDebug("Start IP of the range is malformated: %s", qPrintable(strStartIP)); + continue; + } + const QString strEndIP = cleanupIPAddress(IPs.at(1)); + if(strEndIP.isEmpty()) { + qDebug("Ipfilter.dat: line %d is malformed.", nbLine); + qDebug("End IP of the range is malformated: %s", qPrintable(strEndIP)); + continue; + } + libtorrent::address endAddr = libtorrent::address::from_string(qPrintable(strEndIP), ec); + if(ec) { + qDebug("Ipfilter.dat: line %d is malformed.", nbLine); + qDebug("End IP of the range is malformated: %s", qPrintable(strEndIP)); + continue; + } + if(startAddr.is_v4() != endAddr.is_v4()) { + qDebug("Ipfilter.dat: line %d is malformed.", nbLine); + qDebug("One IP is IPv4 and the other is IPv6!"); + continue; + } + + // Check if there is an access value (apparently not mandatory) + int nbAccess = 0; + if(nbElem > 1) { + // There is possibly one + nbAccess = partsList.at(1).trimmed().toInt(); + } + + if(nbAccess > 127) { + // Ignoring this rule because access value is too high + continue; + } + // Now Add to the filter + try { + filter.add_rule(startAddr, endAddr, libtorrent::ip_filter::blocked); + ++ruleCount; + }catch(exception){ + qDebug("Bad line in filter file, avoided crash..."); + } + } + file.close(); + } + return ruleCount; + } + + // Parser for PeerGuardian ip filter in p2p format + int parseP2PFilterFile(QString filePath) { + int ruleCount = 0; + QFile file(filePath); + if (file.exists()){ + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + std::cerr << "I/O Error: Could not open ip filer file in read mode." << std::endl; + return ruleCount; + } + unsigned int nbLine = 0; + while (!file.atEnd() && !abort) { + ++nbLine; + QByteArray line = file.readLine().trimmed(); + if(line.isEmpty()) continue; + // Ignoring commented lines + if(line.startsWith('#') || line.startsWith("//")) continue; + // Line is splitted by : + QList partsList = line.split(':'); + if(partsList.size() < 2){ + qDebug("p2p file: line %d is malformed.", nbLine); + continue; + } + // Get IP range + QList IPs = partsList.last().split('-'); + if(IPs.size() != 2) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("line was: %s", line.constData()); + continue; + } + boost::system::error_code ec; + QString strStartIP = cleanupIPAddress(IPs.at(0)); + if(strStartIP.isEmpty()) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("Start IP is invalid: %s", qPrintable(strStartIP)); + continue; + } + libtorrent::address startAddr = libtorrent::address::from_string(qPrintable(strStartIP), ec); + if(ec) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("Start IP is invalid: %s", qPrintable(strStartIP)); + continue; + } + QString strEndIP = cleanupIPAddress(IPs.at(1)); + if(strEndIP.isEmpty()) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("End IP is invalid: %s", qPrintable(strStartIP)); + continue; + } + libtorrent::address endAddr = libtorrent::address::from_string(qPrintable(strEndIP), ec); + if(ec) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("End IP is invalid: %s", qPrintable(strStartIP)); + continue; + } + if(startAddr.is_v4() != endAddr.is_v4()) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("Line was: %s", line.constData()); + continue; + } + try { + filter.add_rule(startAddr, endAddr, libtorrent::ip_filter::blocked); + ++ruleCount; + } catch(std::exception&) { + qDebug("p2p file: line %d is malformed.", nbLine); + qDebug("Line was: %s", line.constData()); + continue; + } + } + file.close(); + } + return ruleCount; + } + + int getlineInStream(QDataStream& stream, string& name, char delim) { + char c; + int total_read = 0; + int read; + do { + read = stream.readRawData(&c, 1); + total_read += read; + if(read > 0) { + if(c != delim) { + name += c; + } else { + // Delim found + return total_read; + } + } + } while(read > 0); + return total_read; + } + + // Parser for PeerGuardian ip filter in p2p format + int parseP2BFilterFile(QString filePath) { + int ruleCount = 0; + QFile file(filePath); + if (file.exists()){ + if(!file.open(QIODevice::ReadOnly)){ + std::cerr << "I/O Error: Could not open ip filer file in read mode." << std::endl; + return ruleCount; + } + QDataStream stream(&file); + // Read header + char buf[7]; + unsigned char version; + if( + !stream.readRawData(buf, sizeof(buf)) || + memcmp(buf, "\xFF\xFF\xFF\xFFP2B", 7) || + !stream.readRawData((char*)&version, sizeof(version)) + ) { + std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl; + return ruleCount; + } + + if(version==1 || version==2) { + qDebug ("p2b version 1 or 2"); + unsigned int start, end; + + string name; + while(getlineInStream(stream, name, '\0') && !abort) { + if( + !stream.readRawData((char*)&start, sizeof(start)) || + !stream.readRawData((char*)&end, sizeof(end)) + ) { + std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl; + return ruleCount; + } + // Network byte order to Host byte order + // asio address_v4 contructor expects it + // that way + libtorrent::address_v4 first(ntohl(start)); + libtorrent::address_v4 last(ntohl(end)); + // Apply to bittorrent session + try { + filter.add_rule(first, last, libtorrent::ip_filter::blocked); + ++ruleCount; + } catch(std::exception&) {} + } + } + else if(version==3) { + qDebug ("p2b version 3"); + unsigned int namecount; + if(!stream.readRawData((char*)&namecount, sizeof(namecount))) { + std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl; + return ruleCount; + } + namecount=ntohl(namecount); + // Reading names although, we don't really care about them + for(unsigned int i=0; iget_ip_filter(); + if(isRunning()) { + // Already parsing a filter, abort first + abort = true; + wait(); + } + abort = false; + filePath = _filePath; + // Run it + start(); + } + + static void processFilterList(libtorrent::session *s, QStringList IPs) { + // First, import current filter + libtorrent::ip_filter filter = s->get_ip_filter(); + foreach(const QString &ip, IPs) { + qDebug("Manual ban of peer %s", ip.toLocal8Bit().constData()); + boost::system::error_code ec; + libtorrent::address_v4 addr = libtorrent::address_v4::from_string(ip.toLocal8Bit().constData(), ec); + Q_ASSERT(!ec); + if(!ec) + filter.add_rule(addr, addr, libtorrent::ip_filter::blocked); + } + s->set_ip_filter(filter); + } + +signals: + void IPFilterParsed(int ruleCount); + void IPFilterError(); + +protected: + QString cleanupIPAddress(QString _ip) { + QHostAddress ip(_ip.trimmed()); + if(ip.isNull()) { + return QString(); + } + return ip.toString(); + } + + void run(){ + qDebug("Processing filter file"); + int ruleCount = 0; + if(filePath.endsWith(".p2p", Qt::CaseInsensitive)) { + // PeerGuardian p2p file + ruleCount = parseP2PFilterFile(filePath); + } else { + if(filePath.endsWith(".p2b", Qt::CaseInsensitive)) { + // PeerGuardian p2b file + ruleCount = parseP2BFilterFile(filePath); + } else { + // Default: eMule DAT format + ruleCount = parseDATFilterFile(filePath); + } + } + if(abort) + return; + try { + s->set_ip_filter(filter); + emit IPFilterParsed(ruleCount); + } catch(std::exception&){ + emit IPFilterError(); + } + qDebug("IP Filter thread: finished parsing, filter applied"); + } + +private: + libtorrent::session *s; + libtorrent::ip_filter filter; + bool abort; + QString filePath; + +}; + +#endif diff --git a/src/qtlibtorrent/qbtsession.cpp b/src/qtlibtorrent/qbtsession.cpp new file mode 100644 index 000000000..0061d16db --- /dev/null +++ b/src/qtlibtorrent/qbtsession.cpp @@ -0,0 +1,2919 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "smtp.h" +#include "filesystemwatcher.h" +#include "torrentspeedmonitor.h" +#include "qbtsession.h" +#include "misc.h" +#include "downloadthread.h" +#include "filterparserthread.h" +#include "preferences.h" +#include "scannedfoldersmodel.h" +#ifndef DISABLE_GUI +#include "shutdownconfirm.h" +#include "geoipmanager.h" +#endif +#include "torrentpersistentdata.h" +#include "httpserver.h" +#include "qinisettings.h" +#include "bandwidthscheduler.h" +#include +#include +#include +#if LIBTORRENT_VERSION_MINOR > 14 +#include +#endif +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LIBTORRENT_VERSION_MINOR > 15 +#include "libtorrent/error_code.hpp" +#endif +#include +#include +#include "dnsupdater.h" + +using namespace libtorrent; + +QBtSession* QBtSession::m_instance = 0; +const qreal QBtSession::MAX_RATIO = 9999.; + +const int MAX_TRACKER_ERRORS = 2; +enum VersionType { NORMAL,ALPHA,BETA,RELEASE_CANDIDATE,DEVEL }; + +// Main constructor +QBtSession::QBtSession() + : m_scanFolders(ScanFoldersModel::instance(this)), + preAllocateAll(false), addInPause(false), global_ratio_limit(-1), + LSDEnabled(false), + DHTEnabled(false), current_dht_port(0), queueingEnabled(false), + torrentExport(false) + #ifndef DISABLE_GUI + , geoipDBLoaded(false), resolve_countries(false) + #endif + , m_tracker(0), m_shutdownAct(NO_SHUTDOWN), + m_upnp(0), m_natpmp(0), m_dynDNSUpdater(0) +{ + BigRatioTimer = new QTimer(this); + BigRatioTimer->setInterval(10000); + connect(BigRatioTimer, SIGNAL(timeout()), SLOT(processBigRatios())); + Preferences pref; + // To avoid some exceptions + boost::filesystem::path::default_name_check(boost::filesystem::no_check); + // Creating Bittorrent session + QList version; + version << VERSION_MAJOR; + version << VERSION_MINOR; + version << VERSION_BUGFIX; + version << VERSION_TYPE; + const QString peer_id = "qB"; + // Construct session + s = new session(fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)), 0); + std::cout << "Peer ID: " << fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)).to_string() << std::endl; + addConsoleMessage("Peer ID: "+misc::toQString(fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)).to_string())); + + // Set severity level of libtorrent session + s->set_alert_mask(alert::error_notification | alert::peer_notification | alert::port_mapping_notification | alert::storage_notification | alert::tracker_notification | alert::status_notification | alert::ip_block_notification | alert::progress_notification); + // Load previous state + loadSessionState(); + // Enabling plugins + //s->add_extension(&create_metadata_plugin); + s->add_extension(&create_ut_metadata_plugin); +#if LIBTORRENT_VERSION_MINOR > 14 + if(pref.trackerExchangeEnabled()) + s->add_extension(&create_lt_trackers_plugin); +#endif + if(pref.isPeXEnabled()) { + PeXEnabled = true; + s->add_extension(&create_ut_pex_plugin); + } else { + PeXEnabled = false; + } + s->add_extension(&create_smart_ban_plugin); + timerAlerts = new QTimer(this); + connect(timerAlerts, SIGNAL(timeout()), SLOT(readAlerts())); + timerAlerts->start(1000); + appendLabelToSavePath = pref.appendTorrentLabel(); +#if LIBTORRENT_VERSION_MINOR > 14 + appendqBExtension = pref.useIncompleteFilesExtension(); +#endif + connect(m_scanFolders, SIGNAL(torrentsAdded(QStringList&)), SLOT(addTorrentsFromScanFolder(QStringList&))); + // Apply user settings to Bittorrent session + configureSession(); + // Torrent speed monitor + m_speedMonitor = new TorrentSpeedMonitor(this); + m_speedMonitor->start(); + // To download from urls + downloader = new DownloadThread(this); + connect(downloader, SIGNAL(downloadFinished(QString, QString)), SLOT(processDownloadedFile(QString, QString))); + connect(downloader, SIGNAL(downloadFailure(QString, QString)), SLOT(handleDownloadFailure(QString, QString))); + // Regular saving of fastresume data + connect(&resumeDataTimer, SIGNAL(timeout()), SLOT(saveTempFastResumeData())); + resumeDataTimer.start(170000); // 3min + qDebug("* BTSession constructed"); +} + +// Main destructor +QBtSession::~QBtSession() { + qDebug("BTSession destructor IN"); + delete m_speedMonitor; + qDebug("Deleted the torrent speed monitor"); + // Do some BT related saving +#if LIBTORRENT_VERSION_MINOR < 15 + saveDHTEntry(); +#endif + saveSessionState(); + saveFastResumeData(); + // Delete our objects + if(m_tracker) + delete m_tracker; + delete timerAlerts; + if(BigRatioTimer) + delete BigRatioTimer; + if(filterParser) + delete filterParser; + delete downloader; + if(bd_scheduler) + delete bd_scheduler; + // HTTP Server + if(httpServer) + delete httpServer; + qDebug("Deleting the session"); + delete s; + qDebug("BTSession destructor OUT"); +#ifndef DISABLE_GUI + if(m_shutdownAct != NO_SHUTDOWN) { + qDebug() << "Sending computer shutdown/suspend signal..."; + misc::shutdownComputer(m_shutdownAct == SUSPEND_COMPUTER); + } +#endif +} + +void QBtSession::preAllocateAllFiles(bool b) { + const bool change = (preAllocateAll != b); + if(change) { + qDebug("PreAllocateAll changed, reloading all torrents!"); + preAllocateAll = b; + } +} + +void QBtSession::processBigRatios() { + qDebug("Process big ratios..."); + std::vector torrents = s->get_torrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + const QTorrentHandle h(*torrentIT); + if(!h.is_valid()) continue; + if(h.is_seed()) { + const QString hash = h.hash(); + const qreal ratio = getRealRatio(hash); + qreal ratio_limit = TorrentPersistentData::getRatioLimit(hash); + if(ratio_limit == TorrentPersistentData::NO_RATIO_LIMIT) + continue; + if(ratio_limit == TorrentPersistentData::USE_GLOBAL_RATIO) + ratio_limit = global_ratio_limit; + qDebug("Ratio: %f (limit: %f)", ratio, ratio_limit); + Q_ASSERT(ratio_limit >= 0.f); + if(ratio <= MAX_RATIO && ratio >= ratio_limit) { + if(high_ratio_action == REMOVE_ACTION) { + addConsoleMessage(tr("%1 reached the maximum ratio you set.").arg(h.name())); + addConsoleMessage(tr("Removing torrent %1...").arg(h.name())); + deleteTorrent(hash); + } else { + // Pause it + if(!h.is_paused()) { + addConsoleMessage(tr("%1 reached the maximum ratio you set.").arg(h.name())); + addConsoleMessage(tr("Pausing torrent %1...").arg(h.name())); + pauseTorrent(hash); + } + } + //emit torrent_ratio_deleted(fileName); + } + } + } +} + +void QBtSession::setDownloadLimit(QString hash, long val) { + QTorrentHandle h = getTorrentHandle(hash); + if(h.is_valid()) { + h.set_download_limit(val); + } +} + +void QBtSession::setUploadLimit(QString hash, long val) { + qDebug("Set upload limit rate to %ld", val); + QTorrentHandle h = getTorrentHandle(hash); + if(h.is_valid()) { + h.set_upload_limit(val); + } +} + +void QBtSession::handleDownloadFailure(QString url, QString reason) { + emit downloadFromUrlFailure(url, reason); + // Clean up + const QUrl qurl = QUrl::fromEncoded(url.toUtf8()); + url_skippingDlg.removeOne(qurl); + savepathLabel_fromurl.remove(qurl); +} + +void QBtSession::startTorrentsInPause(bool b) { + addInPause = b; +} + +void QBtSession::setQueueingEnabled(bool enable) { + if(queueingEnabled != enable) { + qDebug("Queueing system is changing state..."); + queueingEnabled = enable; + } +} + +// Set BT session configuration +void QBtSession::configureSession() { + qDebug("Configuring session"); + const Preferences pref; + // * Ports binding + const unsigned short old_listenPort = getListenPort(); + const unsigned short new_listenPort = pref.getSessionPort(); + if(old_listenPort != new_listenPort) { + qDebug("Session port changes in program preferences: %d -> %d", old_listenPort, new_listenPort); + setListeningPort(new_listenPort); + addConsoleMessage(tr("qBittorrent is bound to port: TCP/%1", "e.g: qBittorrent is bound to port: 6881").arg(QString::number(new_listenPort))); + } + + // Downloads + // * Save path + defaultSavePath = pref.getSavePath(); + if(pref.isTempPathEnabled()) { + setDefaultTempPath(pref.getTempPath()); + } else { + setDefaultTempPath(QString::null); + } + setAppendLabelToSavePath(pref.appendTorrentLabel()); +#if LIBTORRENT_VERSION_MINOR > 14 + setAppendqBExtension(pref.useIncompleteFilesExtension()); +#endif + preAllocateAllFiles(pref.preAllocateAllFiles()); + startTorrentsInPause(pref.addTorrentsInPause()); + // * Export Dir + const bool newTorrentExport = pref.isTorrentExportEnabled(); + if(torrentExport != newTorrentExport) { + torrentExport = newTorrentExport; + if(torrentExport) { + qDebug("Torrent export is enabled, exporting the current torrents"); + exportTorrentFiles(pref.getExportDir()); + } + } + // Connection + // * Global download limit + const bool alternative_speeds = pref.isAltBandwidthEnabled(); + int down_limit; + if(alternative_speeds) + down_limit = pref.getAltGlobalDownloadLimit(); + else + down_limit = pref.getGlobalDownloadLimit(); + if(down_limit <= 0) { + // Download limit disabled + setDownloadRateLimit(-1); + } else { + // Enabled + setDownloadRateLimit(down_limit*1024); + } + int up_limit; + if(alternative_speeds) + up_limit = pref.getAltGlobalUploadLimit(); + else + up_limit = pref.getGlobalUploadLimit(); + // * Global Upload limit + if(up_limit <= 0) { + // Upload limit disabled + setUploadRateLimit(-1); + } else { + // Enabled + setUploadRateLimit(up_limit*1024); + } + if(pref.isSchedulerEnabled()) { + if(!bd_scheduler) { + bd_scheduler = new BandwidthScheduler(this); + connect(bd_scheduler, SIGNAL(switchToAlternativeMode(bool)), this, SLOT(useAlternativeSpeedsLimit(bool))); + } + bd_scheduler->start(); + } else { + if(bd_scheduler) delete bd_scheduler; + } +#ifndef DISABLE_GUI + // Resolve countries + qDebug("Loading country resolution settings"); + const bool new_resolv_countries = pref.resolvePeerCountries(); + if(resolve_countries != new_resolv_countries) { + qDebug("in country reoslution settings"); + resolve_countries = new_resolv_countries; + if(resolve_countries && !geoipDBLoaded) { + qDebug("Loading geoip database"); + GeoIPManager::loadDatabase(s); + geoipDBLoaded = true; + } + // Update torrent handles + std::vector torrents = s->get_torrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if(h.is_valid()) + h.resolve_countries(resolve_countries); + } + } +#endif + // * UPnP / NAT-PMP + if(pref.isUPnPEnabled()) { + enableUPnP(true); + addConsoleMessage(tr("UPnP / NAT-PMP support [ON]"), QString::fromUtf8("blue")); + } else { + enableUPnP(false); + addConsoleMessage(tr("UPnP / NAT-PMP support [OFF]"), QString::fromUtf8("blue")); + } + // * Session settings + session_settings sessionSettings = s->settings(); + sessionSettings.user_agent = "qBittorrent "VERSION; + std::cout << "HTTP user agent is " << sessionSettings.user_agent << std::endl; + addConsoleMessage(tr("HTTP user agent is %1").arg(misc::toQString(sessionSettings.user_agent))); + + sessionSettings.upnp_ignore_nonrouters = true; + sessionSettings.use_dht_as_fallback = false; + // To prevent ISPs from blocking seeding + sessionSettings.lazy_bitfields = true; + // Speed up exit + sessionSettings.stop_tracker_timeout = 1; + //sessionSettings.announce_to_all_trackers = true; + sessionSettings.auto_scrape_interval = 1200; // 20 minutes +#if LIBTORRENT_VERSION_MINOR > 14 + sessionSettings.announce_to_all_trackers = true; + sessionSettings.announce_to_all_tiers = false; + sessionSettings.auto_scrape_min_interval = 900; // 15 minutes +#endif + sessionSettings.cache_size = pref.diskCacheSize()*64; + qDebug() << "Using a disk cache size of" << pref.diskCacheSize() << "MiB"; + // Disable OS cache to avoid memory problems (uTorrent behavior) +#ifdef Q_WS_WIN +#if LIBTORRENT_VERSION_MINOR > 14 + // Fixes huge memory usage on Windows 7 (especially when checking files) + sessionSettings.disk_io_write_mode = session_settings::disable_os_cache_for_aligned_files; + sessionSettings.disk_io_read_mode = session_settings::disable_os_cache_for_aligned_files; +#endif +#endif + // Queueing System + if(pref.isQueueingSystemEnabled()) { + sessionSettings.active_downloads = pref.getMaxActiveDownloads(); + sessionSettings.active_seeds = pref.getMaxActiveUploads(); + sessionSettings.active_limit = pref.getMaxActiveTorrents(); + sessionSettings.dont_count_slow_torrents = false; + setQueueingEnabled(true); + } else { + sessionSettings.active_downloads = -1; + sessionSettings.active_seeds = -1; + sessionSettings.active_limit = -1; + setQueueingEnabled(false); + } + // Outgoing ports + sessionSettings.outgoing_ports = std::make_pair(pref.outgoingPortsMin(), pref.outgoingPortsMax()); + // Ignore limits on LAN + qDebug() << "Ignore limits on LAN" << pref.ignoreLimitsOnLAN(); + sessionSettings.ignore_limits_on_local_network = pref.ignoreLimitsOnLAN(); + // Include overhead in transfer limits + sessionSettings.rate_limit_ip_overhead = pref.includeOverheadInLimits(); + // IP address to announce to trackers + QString announce_ip = pref.getNetworkAddress(); + if(!announce_ip.isEmpty()) { +#if LIBTORRENT_VERSION_MINOR > 15 + sessionSettings.announce_ip = announce_ip.toStdString(); +#else + boost::system::error_code ec; + boost::asio::ip::address addr = boost::asio::ip::address::from_string(announce_ip.toStdString(), ec); + if(!ec) { + addConsoleMessage(tr("Reporting IP address %1 to trackers...").arg(announce_ip)); + sessionSettings.announce_ip = addr; + } +#endif + } + // Super seeding +#if LIBTORRENT_VERSION_MINOR > 14 + sessionSettings.strict_super_seeding = pref.isSuperSeedingEnabled(); +#endif +#if LIBTORRENT_VERSION_MINOR > 15 + // * Max Half-open connections + sessionSettings.half_open_limit = pref.getMaxHalfOpenConnections(); + // * Max connections limit + sessionSettings.connections_limit = pref.getMaxConnecs(); +#else + // * Max Half-open connections + s->set_max_half_open_connections(pref.getMaxHalfOpenConnections()); + // * Max connections limit + setMaxConnections(pref.getMaxConnecs()); +#endif +#if LIBTORRENT_VERSION_MINOR > 15 + // uTP + if(pref.isuTPEnabled()) { + sessionSettings.enable_incoming_utp = true; + sessionSettings.enable_outgoing_utp = true; + } else { + sessionSettings.enable_incoming_utp = false; + sessionSettings.enable_outgoing_utp = false; + } + // uTP rate limiting + sessionSettings.rate_limit_utp = pref.isuTPRateLimited(); + if(sessionSettings.rate_limit_utp) + sessionSettings.mixed_mode_algorithm = session_settings::prefer_tcp; + else + sessionSettings.mixed_mode_algorithm = session_settings::peer_proportional; +#endif + qDebug() << "Settings SessionSettings"; + setSessionSettings(sessionSettings); + // Bittorrent + // * Max connections per torrent limit + setMaxConnectionsPerTorrent(pref.getMaxConnecsPerTorrent()); + // * Max uploads per torrent limit + setMaxUploadsPerTorrent(pref.getMaxUploadsPerTorrent()); + // * DHT + if(pref.isDHTEnabled()) { + // Set DHT Port + if(enableDHT(true)) { + int dht_port; + if(pref.isDHTPortSameAsBT()) + dht_port = 0; + else + dht_port = pref.getDHTPort(); + setDHTPort(dht_port); + if(dht_port == 0) dht_port = new_listenPort; + addConsoleMessage(tr("DHT support [ON], port: UDP/%1").arg(dht_port), QString::fromUtf8("blue")); + } else { + addConsoleMessage(tr("DHT support [OFF]"), QString::fromUtf8("red")); + } + } else { + enableDHT(false); + addConsoleMessage(tr("DHT support [OFF]"), QString::fromUtf8("blue")); + } + // * PeX + if(PeXEnabled) { + addConsoleMessage(tr("PeX support [ON]"), QString::fromUtf8("blue")); + } else { + addConsoleMessage(tr("PeX support [OFF]"), QString::fromUtf8("red")); + } + if(PeXEnabled != pref.isPeXEnabled()) { + addConsoleMessage(tr("Restart is required to toggle PeX support"), QString::fromUtf8("red")); + } + // * LSD + if(pref.isLSDEnabled()) { + enableLSD(true); + addConsoleMessage(tr("Local Peer Discovery support [ON]"), QString::fromUtf8("blue")); + } else { + enableLSD(false); + addConsoleMessage(tr("Local Peer Discovery support [OFF]"), QString::fromUtf8("blue")); + } + // * Encryption + const int encryptionState = pref.getEncryptionSetting(); + // The most secure, rc4 only so that all streams and encrypted + pe_settings encryptionSettings; + encryptionSettings.allowed_enc_level = pe_settings::rc4; + encryptionSettings.prefer_rc4 = true; + switch(encryptionState) { + case 0: //Enabled + encryptionSettings.out_enc_policy = pe_settings::enabled; + encryptionSettings.in_enc_policy = pe_settings::enabled; + addConsoleMessage(tr("Encryption support [ON]"), QString::fromUtf8("blue")); + break; + case 1: // Forced + encryptionSettings.out_enc_policy = pe_settings::forced; + encryptionSettings.in_enc_policy = pe_settings::forced; + addConsoleMessage(tr("Encryption support [FORCED]"), QString::fromUtf8("blue")); + break; + default: // Disabled + encryptionSettings.out_enc_policy = pe_settings::disabled; + encryptionSettings.in_enc_policy = pe_settings::disabled; + addConsoleMessage(tr("Encryption support [OFF]"), QString::fromUtf8("blue")); + } + applyEncryptionSettings(encryptionSettings); + // * Maximum ratio + high_ratio_action = pref.getMaxRatioAction(); + setGlobalMaxRatio(pref.getGlobalMaxRatio()); + updateRatioTimer(); + // Ip Filter + FilterParserThread::processFilterList(s, pref.bannedIPs()); + if(pref.isFilteringEnabled()) { + enableIPFilter(pref.getFilter()); + }else{ + disableIPFilter(); + } + // Update Web UI + // Use a QTimer because the function can be called from qBtSession constructor + QTimer::singleShot(0, this, SLOT(initWebUi())); + // * Proxy settings + proxy_settings proxySettings; + if(pref.isProxyEnabled()) { + qDebug("Enabling P2P proxy"); + proxySettings.hostname = pref.getProxyIp().toStdString(); + qDebug("hostname is %s", proxySettings.hostname.c_str()); + proxySettings.port = pref.getProxyPort(); + qDebug("port is %d", proxySettings.port); + if(pref.isProxyAuthEnabled()) { + proxySettings.username = pref.getProxyUsername().toStdString(); + proxySettings.password = pref.getProxyPassword().toStdString(); + qDebug("username is %s", proxySettings.username.c_str()); + qDebug("password is %s", proxySettings.password.c_str()); + } + } + switch(pref.getProxyType()) { + case Proxy::HTTP: + qDebug("type: http"); + proxySettings.type = proxy_settings::http; + break; + case Proxy::HTTP_PW: + qDebug("type: http_pw"); + proxySettings.type = proxy_settings::http_pw; + break; + case Proxy::SOCKS4: + proxySettings.type = proxy_settings::socks4; + case Proxy::SOCKS5: + qDebug("type: socks5"); + proxySettings.type = proxy_settings::socks5; + break; + case Proxy::SOCKS5_PW: + qDebug("type: socks5_pw"); + proxySettings.type = proxy_settings::socks5_pw; + break; + default: + proxySettings.type = proxy_settings::none; + } + setProxySettings(proxySettings); + // Tracker + if(pref.isTrackerEnabled()) { + if(!m_tracker) { + m_tracker = new QTracker(this); + } + if(m_tracker->start()) { + addConsoleMessage(tr("Embedded Tracker [ON]"), QString::fromUtf8("blue")); + } else { + addConsoleMessage(tr("Failed to start the embedded tracker!"), QString::fromUtf8("red")); + } + } else { + addConsoleMessage(tr("Embedded Tracker [OFF]")); + if(m_tracker) + delete m_tracker; + } + // * Scan dirs + const QStringList scan_dirs = pref.getScanDirs(); + QList downloadInDirList = pref.getDownloadInScanDirs(); + while(scan_dirs.size() > downloadInDirList.size()) { + downloadInDirList << false; + } + int i = 0; + foreach (const QString &dir, scan_dirs) { + qDebug() << "Adding scan dir" << dir << downloadInDirList.at(i); + m_scanFolders->addPath(dir, downloadInDirList.at(i)); + ++i; + } + qDebug("Session configured"); +} + +void QBtSession::initWebUi() { + Preferences pref; + if (pref.isWebUiEnabled()) { + const quint16 port = pref.getWebUiPort(); + const QString username = pref.getWebUiUsername(); + const QString password = pref.getWebUiPassword(); + + if(httpServer) { + if(httpServer->serverPort() != port) { + httpServer->close(); + } + } else { + httpServer = new HttpServer(3000, this); + } + +#ifndef QT_NO_OPENSSL + if (pref.isWebUiHttpsEnabled()) { + QSslCertificate cert(pref.getWebUiHttpsCertificate()); + QSslKey key; + const QByteArray raw_key = pref.getWebUiHttpsKey(); + key = QSslKey(raw_key, QSsl::Rsa); + if (!cert.isNull() && !key.isNull()) + httpServer->enableHttps(cert, key); + else + httpServer->disableHttps(); + } else { + httpServer->disableHttps(); + } +#endif + + httpServer->setAuthorization(username, password); + httpServer->setlocalAuthEnabled(pref.isWebUiLocalAuthEnabled()); + if(!httpServer->isListening()) { + bool success = httpServer->listen(QHostAddress::Any, port); + if (success) + addConsoleMessage(tr("The Web UI is listening on port %1").arg(port)); + else + addConsoleMessage(tr("Web User Interface Error - Unable to bind Web UI to port %1").arg(port), "red"); + } + // DynDNS + if(pref.isDynDNSEnabled()) { + if(!m_dynDNSUpdater) + m_dynDNSUpdater = new DNSUpdater(this); + else + m_dynDNSUpdater->updateCredentials(); + } else { + if(m_dynDNSUpdater) { + delete m_dynDNSUpdater; + m_dynDNSUpdater = 0; + } + } + } else { + if(httpServer) + delete httpServer; + if(m_dynDNSUpdater) { + delete m_dynDNSUpdater; + m_dynDNSUpdater = 0; + } + } +} + +void QBtSession::useAlternativeSpeedsLimit(bool alternative) { + qDebug() << Q_FUNC_INFO << alternative; + // Save new state to remember it on startup + Preferences pref; + pref.setAltBandwidthEnabled(alternative); + // Apply settings to the bittorrent session + int down_limit = alternative ? pref.getAltGlobalDownloadLimit() : pref.getGlobalDownloadLimit(); + if(down_limit <= 0) { + down_limit = -1; + } else { + down_limit *= 1024; + } + setDownloadRateLimit(down_limit); + // Upload rate + int up_limit = alternative ? pref.getAltGlobalUploadLimit() : pref.getGlobalUploadLimit(); + if(up_limit <= 0) { + up_limit = -1; + } else { + up_limit *= 1024; + } + setUploadRateLimit(up_limit); + // Notify + emit alternativeSpeedsModeChanged(alternative); +} + +// Return the torrent handle, given its hash +QTorrentHandle QBtSession::getTorrentHandle(const QString &hash) const{ + return QTorrentHandle(s->find_torrent(misc::QStringToSha1(hash))); +} + +bool QBtSession::hasActiveTorrents() const { + std::vector torrents = s->get_torrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + const QTorrentHandle h(*torrentIT); + if(h.is_valid() && !h.is_paused() && !h.is_queued()) + return true; + } + return false; +} + +bool QBtSession::hasDownloadingTorrents() const { + std::vector torrents = s->get_torrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + if(torrentIT->is_valid()) { + try { + const torrent_status::state_t state = torrentIT->status().state; + if(state != torrent_status::finished && state != torrent_status::seeding) + return true; + } catch(std::exception) {} + } + } + return false; +} + +void QBtSession::banIP(QString ip) { + FilterParserThread::processFilterList(s, QStringList(ip)); + Preferences().banIP(ip); +} + +// Delete a torrent from the session, given its hash +// permanent = true means that the torrent will be removed from the hard-drive too +void QBtSession::deleteTorrent(const QString &hash, bool delete_local_files) { + qDebug("Deleting torrent with hash: %s", qPrintable(hash)); + const QTorrentHandle h = getTorrentHandle(hash); + if(!h.is_valid()) { + qDebug("/!\\ Error: Invalid handle"); + return; + } + emit torrentAboutToBeRemoved(h); + qDebug("h is valid, getting name or hash..."); + QString fileName; + if(h.has_metadata()) + fileName = h.name(); + else + fileName = h.hash(); + // Remove it from session + if(delete_local_files) { + if(h.has_metadata()) { + QDir save_dir(h.save_path()); + if(save_dir != QDir(defaultSavePath) && (defaultTempPath.isEmpty() || save_dir != QDir(defaultTempPath))) + savePathsToRemove[hash] = save_dir.absolutePath(); + } + s->remove_torrent(h, session::delete_files); + } else { + QStringList uneeded_files; + if(h.has_metadata()) + uneeded_files = h.absolute_files_path_uneeded(); + s->remove_torrent(h); + // Remove unneeded and incomplete files + foreach(const QString &uneeded_file, uneeded_files) { + qDebug("Removing uneeded file: %s", qPrintable(uneeded_file)); + misc::safeRemove(uneeded_file); + const QString parent_folder = misc::branchPath(uneeded_file); + qDebug("Attempt to remove parent folder (if empty): %s", qPrintable(parent_folder)); + misc::removeEmptyFolder(parent_folder); + } + } + // Remove it from torrent backup directory + QDir torrentBackup(misc::BTBackupLocation()); + QStringList filters; + filters << hash+".*"; + const QStringList files = torrentBackup.entryList(filters, QDir::Files, QDir::Unsorted); + foreach(const QString &file, files) { + misc::safeRemove(torrentBackup.absoluteFilePath(file)); + } + TorrentPersistentData::deletePersistentData(hash); + // Remove tracker errors + trackersInfos.remove(hash); + if(delete_local_files) + addConsoleMessage(tr("'%1' was removed from transfer list and hard disk.", "'xxx.avi' was removed...").arg(fileName)); + else + addConsoleMessage(tr("'%1' was removed from transfer list.", "'xxx.avi' was removed...").arg(fileName)); + qDebug("Torrent deleted."); + emit deletedTorrent(hash); + qDebug("Deleted signal emitted."); +} + +void QBtSession::pauseAllTorrents() { + std::vector torrents = s->get_torrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + try { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if(!h.is_paused()) { + h.pause(); + emit pausedTorrent(h); + } + } catch(invalid_handle&) {} + } +} + +std::vector QBtSession::getTorrents() const { + return s->get_torrents(); +} + +void QBtSession::resumeAllTorrents() { + std::vector torrents = s->get_torrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + try { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if(h.is_paused()) { + h.resume(); + emit resumedTorrent(h); + } + } catch(invalid_handle&) {} + } +} + +void QBtSession::pauseTorrent(const QString &hash) { + QTorrentHandle h = getTorrentHandle(hash); + if(!h.is_paused()) { + h.pause(); + emit pausedTorrent(h); + } +} + +void QBtSession::resumeTorrent(const QString &hash) { + QTorrentHandle h = getTorrentHandle(hash); + if(h.is_paused()) { + h.resume(); + emit resumedTorrent(h); + } +} + +bool QBtSession::loadFastResumeData(const QString &hash, std::vector &buf) { + const QString fastresume_path = QDir(misc::BTBackupLocation()).absoluteFilePath(hash+QString(".fastresume")); + qDebug("Trying to load fastresume data: %s", qPrintable(fastresume_path)); + QFile fastresume_file(fastresume_path); + if(!fastresume_file.open(QIODevice::ReadOnly)) return false; + const QByteArray content = fastresume_file.readAll(); + const int content_size = content.size(); + buf.resize(content_size); + memcpy(&buf[0], content.data(), content_size); + return true; +} + +void QBtSession::loadTorrentSettings(QTorrentHandle& h) { + Preferences pref; + // Connections limit per torrent + h.set_max_connections(pref.getMaxConnecsPerTorrent()); + // Uploads limit per torrent + h.set_max_uploads(pref.getMaxUploadsPerTorrent()); +#ifndef DISABLE_GUI + // Resolve countries + h.resolve_countries(resolve_countries); +#endif +} + +QTorrentHandle QBtSession::addMagnetUri(QString magnet_uri, bool resumed) { + QTorrentHandle h; + const QString hash(misc::magnetUriToHash(magnet_uri)); + if(hash.isEmpty()) { + addConsoleMessage(tr("'%1' is not a valid magnet URI.").arg(magnet_uri)); + return h; + } + const QDir torrentBackup(misc::BTBackupLocation()); + if(resumed) { + // Load metadata + const QString torrent_path = torrentBackup.absoluteFilePath(hash+".torrent"); + if(QFile::exists(torrent_path)) + return addTorrent(torrent_path, false, QString::null, true); + } + qDebug("Adding a magnet URI: %s", qPrintable(hash)); + Q_ASSERT(magnet_uri.startsWith("magnet:", Qt::CaseInsensitive)); + + // Check for duplicate torrent + if(s->find_torrent(misc::toSha1Hash(hash)).is_valid()) { + qDebug("/!\\ Torrent is already in download list"); + addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(magnet_uri)); + return h; + } + + add_torrent_params p = initializeAddTorrentParams(hash); + + // Get save path + const QString savePath(getSavePath(hash, false)); + if(!defaultTempPath.isEmpty() && !TorrentPersistentData::isSeed(hash) && resumed) { + qDebug("addMagnetURI: Temp folder is enabled."); + QString torrent_tmp_path = defaultTempPath.replace("\\", "/"); + p.save_path = torrent_tmp_path.toUtf8().constData(); + // Check if save path exists, creating it otherwise + if(!QDir(torrent_tmp_path).exists()) + QDir().mkpath(torrent_tmp_path); + qDebug("addMagnetURI: using save_path: %s", qPrintable(torrent_tmp_path)); + } else { + p.save_path = savePath.toUtf8().constData(); + // Check if save path exists, creating it otherwise + if(!QDir(savePath).exists()) QDir().mkpath(savePath); + qDebug("addMagnetURI: using save_path: %s", qPrintable(savePath)); + } + + qDebug("Adding magnet URI: %s", qPrintable(magnet_uri)); + + // Adding torrent to Bittorrent session + try { + h = QTorrentHandle(add_magnet_uri(*s, magnet_uri.toStdString(), p)); + }catch(std::exception e){ + qDebug("Error: %s", e.what()); + } + // Check if it worked + if(!h.is_valid()) { + // No need to keep on, it failed. + qDebug("/!\\ Error: Invalid handle"); + return h; + } + Q_ASSERT(h.hash() == hash); + + // If temp path is enabled, move torrent + if(!defaultTempPath.isEmpty() && !resumed) { + qDebug("Temp folder is enabled, moving new torrent to temp folder"); + h.move_storage(defaultTempPath); + } + + loadTorrentSettings(h); + + // Load filtered files + if(!resumed) { + loadTorrentTempData(h, savePath, true); + } + if(!addInPause || (Preferences().useAdditionDialog())) { + // Start torrent because it was added in paused state + h.resume(); + } + // Send torrent addition signal + addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(magnet_uri)); + emit addedTorrent(h); + return h; +} + +// Add a torrent to the Bittorrent session +QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString from_url, bool resumed) { + QTorrentHandle h; + + // Check if BT_backup directory exists + const QDir torrentBackup(misc::BTBackupLocation()); + if(!torrentBackup.exists()) return h; + + // Fix the input path if necessary +#ifdef Q_WS_WIN + // Windows hack + if(!path.endsWith(".torrent")) + if(QFile::rename(path, path+".torrent")) path += ".torrent"; +#endif + if(path.startsWith("file:", Qt::CaseInsensitive)) + path = QUrl::fromEncoded(path.toLocal8Bit()).toLocalFile(); + if(path.isEmpty()) return h; + + Q_ASSERT(!misc::isUrl(path)); + + qDebug("Adding %s to download list", qPrintable(path)); + boost::intrusive_ptr t; + try { + qDebug() << "Loading torrent at" << path; + // Getting torrent file informations + t = new torrent_info(path.toUtf8().constData()); + if(!t->is_valid()) + throw std::exception(); + } catch(std::exception&) { + if(!from_url.isNull()) { + addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(from_url), QString::fromUtf8("red")); + //emit invalidTorrent(from_url); + misc::safeRemove(path); + }else{ +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + QString displayed_path = path; + displayed_path.replace("/", "\\"); + addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(displayed_path), QString::fromUtf8("red")); +#else + addConsoleMessage(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(path), QString::fromUtf8("red")); +#endif + //emit invalidTorrent(path); + } + addConsoleMessage(tr("This file is either corrupted or this isn't a torrent."),QString::fromUtf8("red")); + if(fromScanDir) { + // Remove file + misc::safeRemove(path); + } + return h; + } + + const QString hash = misc::toQString(t->info_hash()); + + qDebug(" -> Hash: %s", qPrintable(hash)); + qDebug(" -> Name: %s", t->name().c_str()); + + // Check for duplicate + if(s->find_torrent(t->info_hash()).is_valid()) { + qDebug("/!\\ Torrent is already in download list"); + // Update info Bar + if(!from_url.isNull()) { + addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(from_url)); + }else{ +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + QString displayed_path = path; + displayed_path.replace("/", "\\"); + addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(displayed_path)); +#else + addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(path)); +#endif + } + // Check if the torrent contains trackers or url seeds we don't know about + // and add them + QTorrentHandle h_ex = getTorrentHandle(hash); + mergeTorrents(h_ex, t); + + // Delete file if temporary + if(!from_url.isNull() || fromScanDir) misc::safeRemove(path); + return h; + } + + // Check number of files + if(t->num_files() < 1) { + addConsoleMessage(tr("Error: The torrent %1 does not contain any file.").arg(misc::toQStringU(t->name()))); + // Delete file if temporary + if(!from_url.isNull() || fromScanDir) misc::safeRemove(path); + return h; + } + + // Actually add the torrent + QString root_folder = misc::truncateRootFolder(t); + qDebug("Truncated root folder: %s", qPrintable(root_folder)); + + add_torrent_params p = initializeAddTorrentParams(hash); + p.ti = t; + + // Get fast resume data if existing + bool fastResume = false; + std::vector buf; // Needs to stay in the function scope + if(resumed) { + if(loadFastResumeData(hash, buf)) { + fastResume = true; + p.resume_data = &buf; + qDebug("Successfully loaded fast resume data"); + } + } +#if LIBTORRENT_VERSION_MINOR < 16 + else { + // Generate fake resume data to make sure unwanted files + // are not allocated + if(preAllocateAll) { + vector fp; + TorrentTempData::getFilesPriority(hash, fp); + if((int)fp.size() == t->num_files()) { + entry rd = generateFilePriorityResumeData(t, fp); + bencode(std::back_inserter(buf), rd); + p.resume_data = &buf; + } + } + } +#endif + + QString savePath; + if(!from_url.isEmpty() && savepathLabel_fromurl.contains(QUrl::fromEncoded(from_url.toUtf8()))) { + // Enforcing the save path defined before URL download (from RSS for example) + QPair savePath_label = savepathLabel_fromurl.take(QUrl::fromEncoded(from_url.toUtf8())); + if(savePath_label.first.isEmpty()) + savePath = getSavePath(hash, fromScanDir, path, root_folder); + else + savePath = savePath_label.first; + // Remember label + TorrentTempData::setLabel(hash, savePath_label.second); + } else { + savePath = getSavePath(hash, fromScanDir, path, root_folder); + } + if(!defaultTempPath.isEmpty() && !TorrentPersistentData::isSeed(hash) && resumed) { + qDebug("addTorrent::Temp folder is enabled."); + QString torrent_tmp_path = defaultTempPath.replace("\\", "/"); + if(!root_folder.isEmpty()) { + if(!torrent_tmp_path.endsWith("/")) torrent_tmp_path += "/"; + torrent_tmp_path += root_folder; + } + p.save_path = torrent_tmp_path.toUtf8().constData(); + // Check if save path exists, creating it otherwise + if(!QDir(torrent_tmp_path).exists()) QDir().mkpath(torrent_tmp_path); + qDebug("addTorrent: using save_path: %s", qPrintable(torrent_tmp_path)); + } else { + p.save_path = savePath.toUtf8().constData(); + // Check if save path exists, creating it otherwise + if(!QDir(savePath).exists()) QDir().mkpath(savePath); + qDebug("addTorrent: using save_path: %s", qPrintable(savePath)); + } + + // Adding torrent to Bittorrent session + try { + h = QTorrentHandle(s->add_torrent(p)); + }catch(std::exception e){ + qDebug("Error: %s", e.what()); + } + // Check if it worked + if(!h.is_valid()) { + qDebug("/!\\ Error: Invalid handle"); + if(!from_url.isNull()) misc::safeRemove(path); + return h; + } + // Remember root folder + TorrentPersistentData::setRootFolder(hash, root_folder); + + // If temp path is enabled, move torrent + // XXX: The torrent is moved after the torrent_checked_alert + // is received to make sure we don't move a completed torrent (#602938) + /*if(!defaultTempPath.isEmpty() && !resumed) { + qDebug("Temp folder is enabled, moving new torrent to temp folder"); + QString torrent_tmp_path = defaultTempPath.replace("\\", "/"); + if(!root_folder.isEmpty()) { + if(!torrent_tmp_path.endsWith("/")) torrent_tmp_path += "/"; + torrent_tmp_path += root_folder; + } + h.move_storage(torrent_tmp_path); + }*/ + + loadTorrentSettings(h); + + if(!resumed) { + qDebug("This is a NEW torrent (first time)..."); + loadTorrentTempData(h, savePath, false); + +#if LIBTORRENT_VERSION_MINOR > 14 + // Append .!qB to incomplete files + if(appendqBExtension) + appendqBextensionToTorrent(h, true); +#endif + // Backup torrent file + const QString newFile = torrentBackup.absoluteFilePath(hash + ".torrent"); + if(path != newFile) + QFile::copy(path, newFile); + // Copy the torrent file to the export folder + if(torrentExport) + exportTorrentFile(h); + } + + if(!fastResume && (!addInPause || (Preferences().useAdditionDialog() && !fromScanDir))) { + // Start torrent because it was added in paused state + h.resume(); + } + + // If temporary file, remove it + if(!from_url.isNull() || fromScanDir) misc::safeRemove(path); + + // Display console message + if(!from_url.isNull()) { + if(fastResume) + addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(from_url)); + else + addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(from_url)); + }else{ +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + QString displayed_path = path; + displayed_path.replace("/", "\\"); + if(fastResume) + addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(displayed_path)); + else + addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(displayed_path)); +#else + if(fastResume) + addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(path)); + else + addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(path)); +#endif + } + + // Send torrent addition signal + emit addedTorrent(h); + return h; +} + +void QBtSession::exportTorrentFile(const QTorrentHandle &h) { + Q_ASSERT(torrentExport); + QString torrent_path = QDir(misc::BTBackupLocation()).absoluteFilePath(h.hash()+".torrent"); + QDir exportPath(Preferences().getExportDir()); + if(exportPath.exists() || exportPath.mkpath(exportPath.absolutePath())) { + QString new_torrent_path = exportPath.absoluteFilePath(h.name()+".torrent"); + if(QFile::exists(new_torrent_path) && misc::sameFiles(torrent_path, new_torrent_path)) { + // Append hash to torrent name to make it unique + new_torrent_path = exportPath.absoluteFilePath(h.name()+"-"+h.hash()+".torrent"); + } + QFile::copy(torrent_path, new_torrent_path); + //h.save_torrent_file(torrent_path); + } +} + +add_torrent_params QBtSession::initializeAddTorrentParams(const QString &hash) { + add_torrent_params p; + + // Seeding mode +#if LIBTORRENT_VERSION_MINOR > 14 + // Skip checking and directly start seeding (new in libtorrent v0.15) + if(TorrentTempData::isSeedingMode(hash)) + p.seed_mode=true; + else + p.seed_mode=false; +#else + Q_UNUSED(hash); +#endif + + // Preallocation mode + if(preAllocateAll) + p.storage_mode = storage_mode_allocate; + else + p.storage_mode = storage_mode_sparse; + + // Priorities +#if LIBTORRENT_VERSION_MINOR > 15 + if(TorrentTempData::hasTempData(hash)) { + std::vector fp; + TorrentTempData::getFilesPriority(hash, fp); + if(!fp.empty()) { + std::vector *fp_conv = new std::vector(); + for(uint i=0; ipush_back(fp[i]); + } + p.file_priorities = fp_conv; + } + } +#endif + + // Start in pause + p.paused = true; + p.duplicate_is_error = false; // Already checked + p.auto_managed = false; // Because it is added in paused state + + return p; +} + +void QBtSession::loadTorrentTempData(QTorrentHandle &h, QString savePath, bool magnet) { + qDebug("loadTorrentTempdata() - ENTER"); + const QString hash = h.hash(); + // Sequential download + if(TorrentTempData::hasTempData(hash)) { + // sequential download + h.set_sequential_download(TorrentTempData::isSequential(hash)); + + // The following is useless for newly added magnet + if(!magnet) { +#if LIBTORRENT_VERSION_MINOR < 16 + // Files priorities + vector fp; + TorrentTempData::getFilesPriority(hash, fp); + h.prioritize_files(fp); +#endif + + // Prioritize first/last piece + h.prioritize_first_last_piece(TorrentTempData::isSequential(hash)); + + // Update file names + const QStringList files_path = TorrentTempData::getFilesPath(hash); + bool force_recheck = false; + if(files_path.size() == h.num_files()) { + for(int i=0; i t) { + // Check if the torrent contains trackers or url seeds we don't know about + // and add them + if(!h_ex.is_valid()) return; + std::vector old_trackers = h_ex.trackers(); + std::vector new_trackers = t->trackers(); + bool trackers_added = false; + for(std::vector::iterator it=new_trackers.begin();it!=new_trackers.end();it++) { + std::string tracker_url = it->url; + bool found = false; + for(std::vector::iterator itold=old_trackers.begin();itold!=old_trackers.end();itold++) { + if(tracker_url == itold->url) { + found = true; + break; + } + } + if(found) { + trackers_added = true; + announce_entry entry(tracker_url); + h_ex.add_tracker(entry); + } + } + if(trackers_added) { + addConsoleMessage(tr("Note: new trackers were added to the existing torrent.")); + } + bool urlseeds_added = false; + const QStringList old_urlseeds = h_ex.url_seeds(); +#if LIBTORRENT_VERSION_MINOR > 15 + std::vector new_urlseeds = t->web_seeds(); + std::vector::iterator it; + for(it = new_urlseeds.begin(); it != new_urlseeds.end(); it++) { + const QString new_url = misc::toQString(it->url.c_str()); + if(!old_urlseeds.contains(new_url)) { + urlseeds_added = true; + h_ex.add_url_seed(new_url); + } + } +#else + std::vector new_urlseeds = t->url_seeds(); + std::vector::iterator it; + for(it = new_urlseeds.begin(); it != new_urlseeds.end(); it++) { + const QString new_url = misc::toQString(it->c_str()); + if(!old_urlseeds.contains(new_url)) { + urlseeds_added = true; + h_ex.add_url_seed(new_url); + } + } +#endif + if(urlseeds_added) { + addConsoleMessage(tr("Note: new URL seeds were added to the existing torrent.")); + } +} + +void QBtSession::exportTorrentFiles(QString path) { + Q_ASSERT(torrentExport); + QDir exportDir(path); + if(!exportDir.exists()) { + if(!exportDir.mkpath(exportDir.absolutePath())) { + std::cerr << "Error: Could not create torrent export directory: " << qPrintable(exportDir.absolutePath()) << std::endl; + return; + } + } + QDir torrentBackup(misc::BTBackupLocation()); + std::vector handles = s->get_torrents(); + std::vector::iterator itr; + for(itr=handles.begin(); itr != handles.end(); itr++) { + const QTorrentHandle h(*itr); + if(!h.is_valid()) { + std::cerr << "Torrent Export: torrent is invalid, skipping..." << std::endl; + continue; + } + const QString src_path(torrentBackup.absoluteFilePath(h.hash()+".torrent")); + if(QFile::exists(src_path)) { + QString dst_path = exportDir.absoluteFilePath(h.name()+".torrent"); + if(QFile::exists(dst_path)) { + if(!misc::sameFiles(src_path, dst_path)) { + dst_path = exportDir.absoluteFilePath(h.name()+"-"+h.hash()+".torrent"); + } else { + qDebug("Torrent Export: Destination file exists, skipping..."); + continue; + } + } + qDebug("Export Torrent: %s -> %s", qPrintable(src_path), qPrintable(dst_path)); + QFile::copy(src_path, dst_path); + } else { + std::cerr << "Error: could not export torrent "<< qPrintable(h.hash()) << ", maybe it has not metadata yet." < 15 + Q_UNUSED(maxConnec); + Q_ASSERT(0); // Should not be used +#else + qDebug() << Q_FUNC_INFO << maxConnec; + s->set_max_connections(maxConnec); +#endif +} + +void QBtSession::setMaxConnectionsPerTorrent(int max) { + qDebug() << Q_FUNC_INFO << max; + // Apply this to all session torrents + std::vector handles = s->get_torrents(); + std::vector::const_iterator it; + for(it = handles.begin(); it != handles.end(); it++) { + if(!it->is_valid()) + continue; + try { + it->set_max_connections(max); + } catch(std::exception) {} + } +} + +void QBtSession::setMaxUploadsPerTorrent(int max) { + qDebug() << Q_FUNC_INFO << max; + // Apply this to all session torrents + std::vector handles = s->get_torrents(); + std::vector::const_iterator it; + for(it = handles.begin(); it != handles.end(); it++) { + if(!it->is_valid()) + continue; + try { + it->set_max_uploads(max); + } catch(std::exception) {} + } +} + +void QBtSession::enableUPnP(bool b) { + Preferences pref; + if(b) { + if(!m_upnp) { + qDebug("Enabling UPnP / NAT-PMP"); + m_upnp = s->start_upnp(); + m_natpmp = s->start_natpmp(); + } + // Use UPnP/NAT-PMP for Web UI too + if(pref.isWebUiEnabled() && pref.useUPnPForWebUIPort()) { + const qint16 port = pref.getWebUiPort(); + m_upnp->add_mapping(upnp::tcp, port, port); + m_natpmp->add_mapping(natpmp::tcp, port, port); + } + } else { + if(m_upnp) { + qDebug("Disabling UPnP / NAT-PMP"); + s->stop_upnp(); + s->stop_natpmp(); + m_upnp = 0; + m_natpmp = 0; + } + } +} + +void QBtSession::enableLSD(bool b) { + if(b) { + if(!LSDEnabled) { + qDebug("Enabling Local Peer Discovery"); + s->start_lsd(); + LSDEnabled = true; + } + } else { + if(LSDEnabled) { + qDebug("Disabling Local Peer Discovery"); + s->stop_lsd(); + LSDEnabled = false; + } + } +} + +void QBtSession::loadSessionState() { + const QString state_path = misc::cacheLocation()+QDir::separator()+QString::fromUtf8("ses_state"); + if(!QFile::exists(state_path)) return; + if(QFile(state_path).size() == 0) { + // Remove empty invalid state file + misc::safeRemove(state_path); + return; + } +#if LIBTORRENT_VERSION_MINOR > 14 + QFile state_file(state_path); + if(!state_file.open(QIODevice::ReadOnly)) return; + std::vector in; + const qint64 content_size = state_file.bytesAvailable(); + if(content_size <= 0) return; + in.resize(content_size); + state_file.read(&in[0], content_size); + // bdecode + lazy_entry e; +#if LIBTORRENT_VERSION_MINOR > 15 + error_code ec; + lazy_bdecode(&in[0], &in[0] + in.size(), e, ec); + if(!ec) { +#else + if (lazy_bdecode(&in[0], &in[0] + in.size(), e) == 0) { +#endif + s->load_state(e); + } +#else + boost::filesystem::ifstream ses_state_file(state_path.toLocal8Bit().constData() + , std::ios_base::binary); + ses_state_file.unsetf(std::ios_base::skipws); + s->load_state(bdecode( + std::istream_iterator(ses_state_file) + , std::istream_iterator())); +#endif +} + +void QBtSession::saveSessionState() { + qDebug("Saving session state to disk..."); + const QString state_path = misc::cacheLocation()+QDir::separator()+QString::fromUtf8("ses_state"); +#if LIBTORRENT_VERSION_MINOR > 14 + entry session_state; + s->save_state(session_state); + vector out; + bencode(back_inserter(out), session_state); + QFile session_file(state_path); + if (!out.empty() && session_file.open(QIODevice::WriteOnly)) { + session_file.write(&out[0], out.size()); + session_file.close(); + } +#else + entry session_state = s->state(); + boost::filesystem::ofstream out(state_path.toLocal8Bit().constData() + , std::ios_base::binary); + out.unsetf(std::ios_base::skipws); + bencode(std::ostream_iterator(out), session_state); +#endif +} + +// Enable DHT +bool QBtSession::enableDHT(bool b) { + if(b) { + if(!DHTEnabled) { +#if LIBTORRENT_VERSION_MINOR < 15 + entry dht_state; + const QString dht_state_path = misc::cacheLocation()+QDir::separator()+QString::fromUtf8("dht_state"); + if(QFile::exists(dht_state_path)) { + boost::filesystem::ifstream dht_state_file(dht_state_path.toLocal8Bit().constData(), std::ios_base::binary); + dht_state_file.unsetf(std::ios_base::skipws); + try{ + dht_state = bdecode(std::istream_iterator(dht_state_file), std::istream_iterator()); + }catch (std::exception&) {} + } +#endif + try { + qDebug() << "Starting DHT..."; +#if LIBTORRENT_VERSION_MINOR > 14 + Q_ASSERT(!s->is_dht_running()); + s->start_dht(); +#else + s->start_dht(dht_state); +#endif + s->add_dht_router(std::make_pair(std::string("router.bittorrent.com"), 6881)); + s->add_dht_router(std::make_pair(std::string("router.utorrent.com"), 6881)); + s->add_dht_router(std::make_pair(std::string("router.bitcomet.com"), 6881)); + s->add_dht_router(std::make_pair(std::string("dht.transmissionbt.com"), 6881)); + s->add_dht_router(std::make_pair(std::string("dht.aelitis.com "), 6881)); // Vuze + DHTEnabled = true; + qDebug("DHT enabled"); + }catch(std::exception e) { + qDebug("Could not enable DHT, reason: %s", e.what()); + return false; + } + } + } else { + if(DHTEnabled) { + DHTEnabled = false; + s->stop_dht(); + qDebug("DHT disabled"); + } + } + return true; +} + +qreal QBtSession::getRealRatio(const QString &hash) const{ + QTorrentHandle h = getTorrentHandle(hash); + if(!h.is_valid()) { + return 0.; + } + Q_ASSERT(h.total_done() >= 0); + Q_ASSERT(h.all_time_upload() >= 0); + if(h.total_done() == 0) { + if(h.all_time_upload() == 0) + return 0; + return MAX_RATIO+1; + } + qreal ratio = (float)h.all_time_upload()/(float)h.total_done(); + Q_ASSERT(ratio >= 0.); + if(ratio > MAX_RATIO) + ratio = MAX_RATIO; + return ratio; +} + +// Called periodically +void QBtSession::saveTempFastResumeData() { + std::vector torrents = s->get_torrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + try { + if(!h.is_valid() || !h.has_metadata() /*|| h.is_seed() || h.is_paused()*/) continue; +#if LIBTORRENT_VERSION_MINOR > 15 + if(!h.need_save_resume_data()) continue; +#endif + if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking) continue; + qDebug("Saving fastresume data for %s", qPrintable(h.name())); + h.save_resume_data(); + }catch(std::exception e){} + } +} + +// Only save fast resume data for unfinished and unpaused torrents (Optimization) +// Called on exit +void QBtSession::saveFastResumeData() { + qDebug("Saving fast resume data..."); + // Stop listening for alerts + resumeDataTimer.stop(); + timerAlerts->stop(); + int num_resume_data = 0; + // Pause session + s->pause(); + std::vector torrents = s->get_torrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if(!h.is_valid() || !h.has_metadata()) continue; + try { + if(isQueueingEnabled()) + TorrentPersistentData::savePriority(h); + // Actually with should save fast resume data for paused files too + //if(h.is_paused()) continue; + if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking) continue; + h.save_resume_data(); + ++num_resume_data; + } catch(libtorrent::invalid_handle&) {} + } + while (num_resume_data > 0) { + alert const* a = s->wait_for_alert(seconds(30)); + if (a == 0) { + std::cerr << " aborting with " << num_resume_data << " outstanding " + "torrents to save resume data for" << std::endl; + break; + } + // Saving fastresume data can fail + save_resume_data_failed_alert const* rda = dynamic_cast(a); + if (rda) { + --num_resume_data; + s->pop_alert(); + try { + // Remove torrent from session + if(rda->handle.is_valid()) + s->remove_torrent(rda->handle); + }catch(libtorrent::libtorrent_exception){} + continue; + } + save_resume_data_alert const* rd = dynamic_cast(a); + if (!rd) { + s->pop_alert(); + continue; + } + // Saving fast resume data was successful + --num_resume_data; + if (!rd->resume_data) continue; + QDir torrentBackup(misc::BTBackupLocation()); + const QTorrentHandle h(rd->handle); + if(!h.is_valid()) continue; + try { + // Remove old fastresume file if it exists + vector out; + bencode(back_inserter(out), *rd->resume_data); + const QString filepath = torrentBackup.absoluteFilePath(h.hash()+".fastresume"); + QFile resume_file(filepath); + if(resume_file.exists()) + misc::safeRemove(filepath); + if(!out.empty() && resume_file.open(QIODevice::WriteOnly)) { + resume_file.write(&out[0], out.size()); + resume_file.close(); + } + // Remove torrent from session + s->remove_torrent(rd->handle); + s->pop_alert(); + } catch(libtorrent::invalid_handle&){} + } +} + +#ifdef DISABLE_GUI +void QBtSession::addConsoleMessage(QString msg, QString) { + emit newConsoleMessage(QDateTime::currentDateTime().toString("dd/MM/yyyy hh:mm:ss") + " - " + msg); +#else +void QBtSession::addConsoleMessage(QString msg, QColor color) { + if(consoleMessages.size() > 100) { + consoleMessages.removeLast(); + } + msg = ""+ QDateTime::currentDateTime().toString(QString::fromUtf8("dd/MM/yyyy hh:mm:ss")) + " - " + msg + ""; + consoleMessages.prepend(msg); + emit newConsoleMessage(msg); +#endif +} + +void QBtSession::addPeerBanMessage(QString ip, bool from_ipfilter) { + if(peerBanMessages.size() > 100) { + peerBanMessages.removeLast(); + } + QString msg; + if(from_ipfilter) + msg = "" + QDateTime::currentDateTime().toString(QString::fromUtf8("dd/MM/yyyy hh:mm:ss")) + " - " + tr("%1 was blocked due to your IP filter", "x.y.z.w was blocked").arg(ip); + else + msg = "" + QDateTime::currentDateTime().toString(QString::fromUtf8("dd/MM/yyyy hh:mm:ss")) + " - " + tr("%1 was banned due to corrupt pieces", "x.y.z.w was banned").arg(ip); + peerBanMessages.prepend(msg); + emit newBanMessage(msg); +} + +bool QBtSession::isFilePreviewPossible(const QString &hash) const{ + // See if there are supported files in the torrent + const QTorrentHandle h = getTorrentHandle(hash); + if(!h.is_valid() || !h.has_metadata()) { + return false; + } + const unsigned int nbFiles = h.num_files(); + for(unsigned int i=0; i torrents = s->get_torrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if(!h.is_valid()) continue; + h.move_storage(getSavePath(h.hash())); + } + } else { + qDebug("Enabling default temp path..."); + // Moving all downloading torrents to temporary save path + std::vector torrents = s->get_torrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + if(!h.is_valid()) continue; + if(!h.is_seed()) { + QString root_folder = TorrentPersistentData::getRootFolder(h.hash()); + QString torrent_tmp_path = temppath.replace("\\", "/"); + if(!root_folder.isEmpty()) { + if(!torrent_tmp_path.endsWith("/")) torrent_tmp_path += "/"; + torrent_tmp_path += root_folder; + } + qDebug("Moving torrent to its temp save path: %s", qPrintable(torrent_tmp_path)); + h.move_storage(torrent_tmp_path); + } + } + } + defaultTempPath = temppath; +} + +#if LIBTORRENT_VERSION_MINOR > 14 +void QBtSession::appendqBextensionToTorrent(const QTorrentHandle &h, bool append) { + if(!h.is_valid() || !h.has_metadata()) return; + std::vector fp; + h.file_progress(fp); + for(int i=0; i 0 && (fp[i]/(double)file_size) < 1.) { + const QString name = h.filepath_at(i); + if(!name.endsWith(".!qB")) { + const QString new_name = name+".!qB"; + qDebug("Renaming %s to %s", qPrintable(name), qPrintable(new_name)); + h.rename_file(i, new_name); + } + } + } else { + QString name = h.filepath_at(i); + if(name.endsWith(".!qB")) { + const QString old_name = name; + name.chop(4); + qDebug("Renaming %s to %s", qPrintable(old_name), qPrintable(name)); + h.rename_file(i, name); + } + } + } +} +#endif + +void QBtSession::changeLabelInTorrentSavePath(const QTorrentHandle &h, QString old_label, QString new_label) { + if(!h.is_valid()) return; + if(!appendLabelToSavePath) return; + QString old_save_path = TorrentPersistentData::getSavePath(h.hash()); + if(!old_save_path.startsWith(defaultSavePath)) return; + QString new_save_path = misc::updateLabelInSavePath(defaultSavePath, old_save_path, old_label, new_label); + if(new_save_path != old_save_path) { + // Move storage + qDebug("Moving storage to %s", qPrintable(new_save_path)); + QDir().mkpath(new_save_path); + h.move_storage(new_save_path); + } +} + +void QBtSession::appendLabelToTorrentSavePath(const QTorrentHandle& h) { + if(!h.is_valid()) return; + const QString label = TorrentPersistentData::getLabel(h.hash()); + if(label.isEmpty()) return; + // Current save path + QString old_save_path = TorrentPersistentData::getSavePath(h.hash()); + QString new_save_path = misc::updateLabelInSavePath(defaultSavePath, old_save_path, "", label); + if(old_save_path != new_save_path) { + // Move storage + QDir().mkpath(new_save_path); + h.move_storage(new_save_path); + } +} + +void QBtSession::setAppendLabelToSavePath(bool append) { + if(appendLabelToSavePath != append) { + appendLabelToSavePath = !appendLabelToSavePath; + if(appendLabelToSavePath) { + // Move torrents storage to sub folder with label name + std::vector torrents = s->get_torrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + appendLabelToTorrentSavePath(h); + } + } + } +} + +#if LIBTORRENT_VERSION_MINOR > 14 +void QBtSession::setAppendqBExtension(bool append) { + if(appendqBExtension != append) { + appendqBExtension = !appendqBExtension; + // append or remove .!qB extension for incomplete files + std::vector torrents = s->get_torrents(); + std::vector::iterator torrentIT; + for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { + QTorrentHandle h = QTorrentHandle(*torrentIT); + appendqBextensionToTorrent(h, appendqBExtension); + } + } +} +#endif + +// Set the ports range in which is chosen the port the Bittorrent +// session will listen to +void QBtSession::setListeningPort(int port) { + qDebug() << Q_FUNC_INFO << port; + Preferences pref; + std::pair ports(port, port); +#if LIBTORRENT_VERSION_MINOR > 15 + error_code ec; +#endif + const QString iface_name = pref.getNetworkInterface(); + if(iface_name.isEmpty()) { +#if LIBTORRENT_VERSION_MINOR > 15 + s->listen_on(ports, ec); +#else + s->listen_on(ports); +#endif + return; + } + // Attempt to listen on provided interface + const QNetworkInterface network_iface = QNetworkInterface::interfaceFromName(iface_name); + if(!network_iface.isValid()) { + qDebug("Invalid network interface: %s", qPrintable(iface_name)); + addConsoleMessage(tr("The network interface defined is invalid: %1").arg(iface_name), "red"); + addConsoleMessage(tr("Trying any other network interface available instead.")); +#if LIBTORRENT_VERSION_MINOR > 15 + s->listen_on(ports, ec); +#else + s->listen_on(ports); +#endif + return; + } + QString ip; + qDebug("This network interface has %d IP addresses", network_iface.addressEntries().size()); + foreach(const QNetworkAddressEntry &entry, network_iface.addressEntries()) { + qDebug("Trying to listen on IP %s (%s)", qPrintable(entry.ip().toString()), qPrintable(iface_name)); +#if LIBTORRENT_VERSION_MINOR > 15 + s->listen_on(ports, ec, entry.ip().toString().toAscii().constData()); + if(!ec) { +#else + if(s->listen_on(ports, entry.ip().toString().toAscii().constData())) { +#endif + ip = entry.ip().toString(); + break; + } + } + if(s->is_listening()) { + addConsoleMessage(tr("Listening on IP address %1 on network interface %2...").arg(ip).arg(iface_name)); + } else { + qDebug("Failed to listen on any of the IP addresses"); + addConsoleMessage(tr("Failed to listen on network interface %1").arg(iface_name), "red"); + } +} + +// Set download rate limit +// -1 to disable +void QBtSession::setDownloadRateLimit(long rate) { + qDebug() << Q_FUNC_INFO << rate; + Q_ASSERT(rate == -1 || rate >= 0); +#if LIBTORRENT_VERSION_MINOR > 15 + session_settings settings = s->settings(); + settings.download_rate_limit = rate; + s->set_settings(settings); +#else + s->set_download_rate_limit(rate); +#endif +} + +// Set upload rate limit +// -1 to disable +void QBtSession::setUploadRateLimit(long rate) { + qDebug() << Q_FUNC_INFO << rate; + Q_ASSERT(rate == -1 || rate >= 0); +#if LIBTORRENT_VERSION_MINOR > 15 + session_settings settings = s->settings(); + settings.upload_rate_limit = rate; + s->set_settings(settings); +#else + s->set_upload_rate_limit(rate); +#endif +} + +// Torrents will a ratio superior to the given value will +// be automatically deleted +void QBtSession::setGlobalMaxRatio(qreal ratio) { + if(ratio < 0) ratio = -1.; + if(global_ratio_limit != ratio) { + global_ratio_limit = ratio; + qDebug("* Set global deleteRatio to %.1f", global_ratio_limit); + updateRatioTimer(); + } +} + +void QBtSession::setMaxRatioPerTorrent(const QString &hash, qreal ratio) +{ + if (ratio < 0) + ratio = -1; + if (ratio > MAX_RATIO) + ratio = MAX_RATIO; + qDebug("* Set individual max ratio for torrent %s to %.1f.", + qPrintable(hash), ratio); + TorrentPersistentData::setRatioLimit(hash, ratio); + updateRatioTimer(); +} + +void QBtSession::removeRatioPerTorrent(const QString &hash) +{ + qDebug("* Remove individual max ratio for torrent %s.", qPrintable(hash)); + TorrentPersistentData::setRatioLimit(hash, TorrentPersistentData::USE_GLOBAL_RATIO); + updateRatioTimer(); +} + +qreal QBtSession::getMaxRatioPerTorrent(const QString &hash, bool *usesGlobalRatio) const +{ + qreal ratio_limit = TorrentPersistentData::getRatioLimit(hash); + if(ratio_limit == TorrentPersistentData::USE_GLOBAL_RATIO) { + ratio_limit = global_ratio_limit; + *usesGlobalRatio = true; + } else { + *usesGlobalRatio = false; + } + return ratio_limit; +} + +void QBtSession::updateRatioTimer() +{ + if (global_ratio_limit == -1 && !TorrentPersistentData::hasPerTorrentRatioLimit()) { + if (BigRatioTimer->isActive()) + BigRatioTimer->stop(); + } else if (!BigRatioTimer->isActive()) { + BigRatioTimer->start(); + } +} + +// Set DHT port (>= 1 or 0 if same as BT) +void QBtSession::setDHTPort(int dht_port) { + if(dht_port >= 0) { + if(dht_port == current_dht_port) return; + struct dht_settings DHTSettings; + DHTSettings.service_port = dht_port; + s->set_dht_settings(DHTSettings); + current_dht_port = dht_port; + qDebug("Set DHT Port to %d", dht_port); + } +} + +// Enable IP Filtering +void QBtSession::enableIPFilter(const QString &filter_path, bool force) { + qDebug("Enabling IPFiler"); + if(!filterParser) { + filterParser = new FilterParserThread(this, s); + connect(filterParser.data(), SIGNAL(IPFilterParsed(int)), SLOT(handleIPFilterParsed(int))); + connect(filterParser.data(), SIGNAL(IPFilterError()), SLOT(handleIPFilterError())); + } + if(filterPath.isEmpty() || filterPath != filter_path || force) { + filterPath = filter_path; + filterParser->processFilterFile(filter_path); + } +} + +// Disable IP Filtering +void QBtSession::disableIPFilter() { + qDebug("Disabling IPFilter"); + s->set_ip_filter(ip_filter()); + if(filterParser) { + disconnect(filterParser.data(), 0, this, 0); + delete filterParser; + } + filterPath = ""; +} + +// Set BT session settings (user_agent) +void QBtSession::setSessionSettings(const session_settings &sessionSettings) { + qDebug("Set session settings"); + s->set_settings(sessionSettings); +} + +// Set Proxy +void QBtSession::setProxySettings(proxy_settings proxySettings) { + qDebug() << Q_FUNC_INFO; + +#if LIBTORRENT_VERSION_MINOR > 15 + proxySettings.proxy_peer_connections = Preferences().proxyPeerConnections(); + s->set_proxy(proxySettings); +#else + s->set_tracker_proxy(proxySettings); + proxy_settings peer_proxy; + if (Preferences().proxyPeerConnections()) + peer_proxy = proxySettings; + s->set_peer_proxy(peer_proxy); + s->set_web_seed_proxy(peer_proxy); + s->set_dht_proxy(peer_proxy); +#endif + + // Define environment variable + QString proxy_str; + switch(proxySettings.type) { + case proxy_settings::http_pw: + proxy_str = "http://"+misc::toQString(proxySettings.username)+":"+misc::toQString(proxySettings.password)+"@"+misc::toQString(proxySettings.hostname)+":"+QString::number(proxySettings.port); + break; + case proxy_settings::http: + proxy_str = "http://"+misc::toQString(proxySettings.hostname)+":"+QString::number(proxySettings.port); + break; + case proxy_settings::socks5: + proxy_str = misc::toQString(proxySettings.hostname)+":"+QString::number(proxySettings.port); + break; + case proxy_settings::socks5_pw: + proxy_str = misc::toQString(proxySettings.username)+":"+misc::toQString(proxySettings.password)+"@"+misc::toQString(proxySettings.hostname)+":"+QString::number(proxySettings.port); + break; + default: + qDebug("Disabling HTTP communications proxy"); +#ifdef Q_WS_WIN + putenv("http_proxy="); + putenv("sock_proxy="); +#else + unsetenv("http_proxy"); + unsetenv("sock_proxy"); +#endif + return; + } + // We need this for urllib in search engine plugins +#ifdef Q_WS_WIN + QString type_str; + if(proxySettings.type == proxy_settings::socks5 || proxySettings.type == proxy_settings::socks5_pw) + type_str = "sock_proxy"; + else + type_str = "http_proxy"; + QString tmp = type_str+"="+proxy_str; + putenv(tmp.toLocal8Bit().constData()); +#else + qDebug("HTTP communications proxy string: %s", qPrintable(proxy_str)); + if(proxySettings.type == proxy_settings::socks5 || proxySettings.type == proxy_settings::socks5_pw) + setenv("sock_proxy", proxy_str.toLocal8Bit().constData(), 1); + else + setenv("http_proxy", proxy_str.toLocal8Bit().constData(), 1); +#endif +} + +void QBtSession::recursiveTorrentDownload(const QTorrentHandle &h) { + try { + for(int i=0; i t = new torrent_info(torrent_fullpath.toUtf8().constData()); + const QString sub_hash = misc::toQString(t->info_hash()); + // Passing the save path along to the sub torrent file + TorrentTempData::setSavePath(sub_hash, h.save_path()); + addTorrent(torrent_fullpath); + } + } + } catch(std::exception&) { + qDebug("Caught error loading torrent"); + } +} + +void QBtSession::cleanUpAutoRunProcess(int) { + sender()->deleteLater(); +} + +void QBtSession::autoRunExternalProgram(const QTorrentHandle &h, bool async) { + if(!h.is_valid()) return; + QString program = Preferences().getAutoRunProgram().trimmed(); + if(program.isEmpty()) return; + // Replace %f by torrent path + QString torrent_path; + if(h.num_files() == 1) + torrent_path = h.firstFileSavePath(); + else + torrent_path = h.save_path(); + program.replace("%f", torrent_path); + // Replace %n by torrent name + program.replace("%n", h.name()); + QProcess *process = new QProcess; + if(async) { + connect(process, SIGNAL(finished(int)), this, SLOT(cleanUpAutoRunProcess(int))); + process->start(program); + } else { + process->execute(program); + delete process; + } +} + +void QBtSession::sendNotificationEmail(const QTorrentHandle &h) { + // Prepare mail content + QString content = tr("Torrent name: %1").arg(h.name()) + "\n"; + content += tr("Torrent size: %1").arg(misc::friendlyUnit(h.actual_size())) + "\n"; + content += tr("Save path: %1").arg(TorrentPersistentData::getSavePath(h.hash())) + "\n\n"; + content += tr("The torrent was downloaded in %1.", "The torrent was downloaded in 1 hour and 20 seconds").arg(misc::userFriendlyDuration(h.active_time())) + "\n\n\n"; + content += tr("Thank you for using qBittorrent.") + "\n"; + // Send the notification email + Smtp *sender = new Smtp(this); + sender->sendMail("notification@qbittorrent.org", Preferences().getMailNotificationEmail(), tr("[qBittorrent] %1 has finished downloading").arg(h.name()), content); +} + +// Read alerts sent by the Bittorrent session +void QBtSession::readAlerts() { + // look at session alerts and display some infos + std::auto_ptr a = s->pop_alert(); + while (a.get()) { + if (torrent_finished_alert* p = dynamic_cast(a.get())) { + QTorrentHandle h(p->handle); + if(h.is_valid()) { + const QString hash = h.hash(); + qDebug("Got a torrent finished alert for %s", qPrintable(h.name())); +#if LIBTORRENT_VERSION_MINOR > 14 + // Remove .!qB extension if necessary + if(appendqBExtension) + appendqBextensionToTorrent(h, false); +#endif + const bool was_already_seeded = TorrentPersistentData::isSeed(hash); + qDebug("Was already seeded: %d", was_already_seeded); + if(!was_already_seeded) { + h.save_resume_data(); + qDebug("Checking if the torrent contains torrent files to download"); + // Check if there are torrent files inside + for(int i=0; i t = new torrent_info(torrent_fullpath.toUtf8().constData()); + if(t->is_valid()) { + qDebug("emitting recursiveTorrentDownloadPossible()"); + emit recursiveTorrentDownloadPossible(h); + break; + } + } catch(std::exception&) { + qDebug("Caught error loading torrent"); +#if defined(Q_WS_WIN) || defined(Q_OS_OS2) + QString displayed_path = torrent_fullpath; + displayed_path.replace("/", "\\"); + addConsoleMessage(tr("Unable to decode %1 torrent file.").arg(displayed_path), QString::fromUtf8("red")); +#else + addConsoleMessage(tr("Unable to decode %1 torrent file.").arg(torrent_fullpath), QString::fromUtf8("red")); +#endif + } + } + } + // Move to download directory if necessary + if(!defaultTempPath.isEmpty()) { + // Check if directory is different + const QDir current_dir(h.save_path()); + const QDir save_dir(getSavePath(hash)); + if(current_dir != save_dir) { + qDebug("Moving torrent from the temp folder"); + h.move_storage(save_dir.absolutePath()); + } + } + // Remember finished state + qDebug("Saving seed status"); + TorrentPersistentData::saveSeedStatus(h); + // Recheck if the user asked to + Preferences pref; + if(pref.recheckTorrentsOnCompletion()) { + h.force_recheck(); + } + qDebug("Emitting finishedTorrent() signal"); + emit finishedTorrent(h); + qDebug("Received finished alert for %s", qPrintable(h.name())); +#ifndef DISABLE_GUI + bool will_shutdown = (pref.shutdownWhenDownloadsComplete() || + pref.shutdownqBTWhenDownloadsComplete() || + pref.suspendWhenDownloadsComplete()) + && !hasDownloadingTorrents(); +#else + bool will_shutdown = false; +#endif + // AutoRun program + if(pref.isAutoRunEnabled()) + autoRunExternalProgram(h, will_shutdown); + // Mail notification + if(pref.isMailNotificationEnabled()) + sendNotificationEmail(h); +#ifndef DISABLE_GUI + // Auto-Shutdown + if(will_shutdown) { + bool suspend = pref.suspendWhenDownloadsComplete(); + bool shutdown = pref.shutdownWhenDownloadsComplete(); + // Confirm shutdown + QString confirm_msg; + if(suspend) { + confirm_msg = tr("The computer will now go to sleep mode unless you cancel within the next 15 seconds..."); + } else if(shutdown) { + confirm_msg = tr("The computer will now be switched off unless you cancel within the next 15 seconds..."); + } else { + confirm_msg = tr("qBittorrent will now exit unless you cancel within the next 15 seconds..."); + } + if(!ShutdownConfirmDlg::askForConfirmation(confirm_msg)) + return; + // Actually shut down + if(suspend || shutdown) { + qDebug("Preparing for auto-shutdown because all downloads are complete!"); + // Disabling it for next time + pref.setShutdownWhenDownloadsComplete(false); + pref.setSuspendWhenDownloadsComplete(false); + // Make sure preferences are synced before exiting + if(suspend) + m_shutdownAct = SUSPEND_COMPUTER; + else + m_shutdownAct = SHUTDOWN_COMPUTER; + } + qDebug("Exiting the application"); + qApp->exit(); + return; + } +#endif // DISABLE_GUI + } + } + } + else if (save_resume_data_alert* p = dynamic_cast(a.get())) { + const QDir torrentBackup(misc::BTBackupLocation()); + const QTorrentHandle h(p->handle); + if(h.is_valid() && p->resume_data) { + const QString filepath = torrentBackup.absoluteFilePath(h.hash()+".fastresume"); + QFile resume_file(filepath); + if(resume_file.exists()) + misc::safeRemove(filepath); + qDebug("Saving fastresume data in %s", qPrintable(filepath)); + vector out; + bencode(back_inserter(out), *p->resume_data); + if(!out.empty() && resume_file.open(QIODevice::WriteOnly)) { + resume_file.write(&out[0], out.size()); + resume_file.close(); + } + } + } + else if (file_renamed_alert* p = dynamic_cast(a.get())) { + QTorrentHandle h(p->handle); + if(h.is_valid()) { + if(h.num_files() > 1) { + // Check if folders were renamed + QStringList old_path_parts = h.orig_filepath_at(p->index).split("/"); + old_path_parts.removeLast(); + QString old_path = old_path_parts.join("/"); + QStringList new_path_parts = misc::toQStringU(p->name).split("/"); + new_path_parts.removeLast(); + if(!new_path_parts.isEmpty() && old_path != new_path_parts.join("/")) { + qDebug("Old_path(%s) != new_path(%s)", qPrintable(old_path), qPrintable(new_path_parts.join("/"))); + old_path = h.save_path()+"/"+old_path; + qDebug("Detected folder renaming, attempt to delete old folder: %s", qPrintable(old_path)); + QDir().rmpath(old_path); + } + } else { + // Single-file torrent + // Renaming a file corresponds to changing the save path + emit savePathChanged(h); + } + } + } + else if (torrent_deleted_alert* p = dynamic_cast(a.get())) { + qDebug("A torrent was deleted from the hard disk, attempting to remove the root folder too..."); + QString hash; +#if LIBTORRENT_VERSION_MINOR > 14 + hash = misc::toQString(p->info_hash); +#else + // Unfortunately libtorrent v0.14 does not provide the hash, + // only the torrent handle that is often invalid when it arrives + try { + if(p->handle.is_valid()) { + hash = misc::toQString(p->handle.info_hash()); + } + }catch(std::exception){} +#endif + if(!hash.isEmpty()) { + if(savePathsToRemove.contains(hash)) { + const QString dirpath = savePathsToRemove.take(hash); + qDebug() << "Removing save path: " << dirpath << "..."; + bool ok = misc::removeEmptyFolder(dirpath); + Q_UNUSED(ok); + qDebug() << "Folder was removed: " << ok; + } + } else { + // Fallback + qDebug() << "hash is empty, use fallback to remove save path"; + foreach(const QString& key, savePathsToRemove.keys()) { + // Attempt to delete + if(misc::removeEmptyFolder(savePathsToRemove[key])) { + savePathsToRemove.remove(key); + } + } + } + } + else if (storage_moved_alert* p = dynamic_cast(a.get())) { + QTorrentHandle h(p->handle); + if(h.is_valid()) { + // Attempt to remove old folder if empty + const QString old_save_path = TorrentPersistentData::getPreviousPath(h.hash()); + const QString new_save_path = misc::toQStringU(p->path.c_str()); + qDebug("Torrent moved from %s to %s", qPrintable(old_save_path), qPrintable(new_save_path)); + QDir old_save_dir(old_save_path); + if(old_save_dir != QDir(defaultSavePath) && old_save_dir != QDir(defaultTempPath)) { + qDebug("Attempting to remove %s", qPrintable(old_save_path)); + QDir().rmpath(old_save_path); + } + if(defaultTempPath.isEmpty() || !new_save_path.startsWith(defaultTempPath)) { + qDebug("Storage has been moved, updating save path to %s", qPrintable(new_save_path)); + TorrentPersistentData::saveSavePath(h.hash(), new_save_path); + } + emit savePathChanged(h); + //h.force_recheck(); + } + } + else if (metadata_received_alert* p = dynamic_cast(a.get())) { + QTorrentHandle h(p->handle); + if(h.is_valid()) { + qDebug("Received metadata for %s", qPrintable(h.hash())); + // Save metadata + const QDir torrentBackup(misc::BTBackupLocation()); + if(!QFile::exists(torrentBackup.absoluteFilePath(h.hash()+QString(".torrent")))) + h.save_torrent_file(torrentBackup.absoluteFilePath(h.hash()+QString(".torrent"))); + // Copy the torrent file to the export folder + if(torrentExport) + exportTorrentFile(h); +#if LIBTORRENT_VERSION_MINOR > 14 + // Append .!qB to incomplete files + if(appendqBExtension) + appendqBextensionToTorrent(h, true); +#endif + // Truncate root folder + const QString root_folder = misc::truncateRootFolder(p->handle); + TorrentPersistentData::setRootFolder(h.hash(), root_folder); + + // Move to a subfolder corresponding to the torrent root folder if necessary + if(!root_folder.isEmpty()) { + if(!h.is_seed() && !defaultTempPath.isEmpty()) { + QString torrent_tmp_path = defaultTempPath.replace("\\", "/"); + if(!torrent_tmp_path.endsWith("/")) torrent_tmp_path += "/"; + torrent_tmp_path += root_folder; + h.move_storage(torrent_tmp_path); + } else { + QString save_path = h.save_path(); + h.move_storage(QDir(save_path).absoluteFilePath(root_folder)); + } + } + emit metadataReceived(h); + if(h.is_paused()) { + // XXX: Unfortunately libtorrent-rasterbar does not send a torrent_paused_alert + // and the torrent can be paused when metadata is received + emit pausedTorrent(h); + } + + } + } + else if (file_error_alert* p = dynamic_cast(a.get())) { + QTorrentHandle h(p->handle); + if(h.is_valid()) { + h.pause(); + std::cerr << "File Error: " << p->message().c_str() << std::endl; + addConsoleMessage(tr("An I/O error occured, '%1' paused.").arg(h.name())); + addConsoleMessage(tr("Reason: %1").arg(misc::toQString(p->message()))); + if(h.is_valid()) { + emit fullDiskError(h, misc::toQString(p->message())); + //h.pause(); + emit pausedTorrent(h); + } + } + } +#if LIBTORRENT_VERSION_MINOR > 14 + else if (file_completed_alert* p = dynamic_cast(a.get())) { + QTorrentHandle h(p->handle); + qDebug("A file completed download in torrent %s", qPrintable(h.name())); + if(appendqBExtension) { + qDebug("appendqBTExtension is true"); + QString name = h.filepath_at(p->index); + if(name.endsWith(".!qB")) { + const QString old_name = name; + name.chop(4); + qDebug("Renaming %s to %s", qPrintable(old_name), qPrintable(name)); + h.rename_file(p->index, name); + } + } + } +#endif + else if (torrent_paused_alert* p = dynamic_cast(a.get())) { + if(p->handle.is_valid()) { + QTorrentHandle h(p->handle); + if(!h.has_error()) + h.save_resume_data(); + emit pausedTorrent(h); + } + } + else if (tracker_error_alert* p = dynamic_cast(a.get())) { + // Level: fatal + QTorrentHandle h(p->handle); + if(h.is_valid()){ + // Authentication + if(p->status_code != 401) { + qDebug("Received a tracker error for %s: %s", p->url.c_str(), p->msg.c_str()); + const QString tracker_url = misc::toQString(p->url); + QHash trackers_data = trackersInfos.value(h.hash(), QHash()); + TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); + data.last_message = misc::toQString(p->msg); +#if LIBTORRENT_VERSION_MINOR < 15 + data.verified = false; + ++data.fail_count; +#endif + trackers_data.insert(tracker_url, data); + trackersInfos[h.hash()] = trackers_data; + } else { + emit trackerAuthenticationRequired(h); + } + } + } + else if (tracker_reply_alert* p = dynamic_cast(a.get())) { + const QTorrentHandle h(p->handle); + if(h.is_valid()){ + qDebug("Received a tracker reply from %s (Num_peers=%d)", p->url.c_str(), p->num_peers); + // Connection was successful now. Remove possible old errors + QHash trackers_data = trackersInfos.value(h.hash(), QHash()); + const QString tracker_url = misc::toQString(p->url); + TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); + data.last_message = ""; // Reset error/warning message + data.num_peers = p->num_peers; +#if LIBTORRENT_VERSION_MINOR < 15 + data.fail_count = 0; + data.verified = true; +#endif + trackers_data.insert(tracker_url, data); + trackersInfos[h.hash()] = trackers_data; + } + } else if (tracker_warning_alert* p = dynamic_cast(a.get())) { + const QTorrentHandle h(p->handle); + if(h.is_valid()){ + // Connection was successful now but there is a warning message + QHash trackers_data = trackersInfos.value(h.hash(), QHash()); + const QString tracker_url = misc::toQString(p->url); + TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); + data.last_message = misc::toQString(p->msg); // Store warning message +#if LIBTORRENT_VERSION_MINOR < 15 + data.verified = true; + data.fail_count = 0; +#endif + trackers_data.insert(tracker_url, data); + trackersInfos[h.hash()] = trackers_data; + qDebug("Received a tracker warning from %s: %s", p->url.c_str(), p->msg.c_str()); + } + } + else if (portmap_error_alert* p = dynamic_cast(a.get())) { + addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping failure, message: %1").arg(misc::toQString(p->message())), "red"); + //emit UPnPError(QString(p->msg().c_str())); + } + else if (portmap_alert* p = dynamic_cast(a.get())) { + qDebug("UPnP Success, msg: %s", p->message().c_str()); + addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping successful, message: %1").arg(misc::toQString(p->message())), "blue"); + //emit UPnPSuccess(QString(p->msg().c_str())); + } + else if (peer_blocked_alert* p = dynamic_cast(a.get())) { + boost::system::error_code ec; + string ip = p->ip.to_string(ec); + if (!ec) { + addPeerBanMessage(QString::fromAscii(ip.c_str()), true); + //emit peerBlocked(QString::fromAscii(ip.c_str())); + } + } + else if (peer_ban_alert* p = dynamic_cast(a.get())) { + boost::system::error_code ec; + string ip = p->ip.address().to_string(ec); + if (!ec) { + addPeerBanMessage(QString::fromAscii(ip.c_str()), false); + //emit peerBlocked(QString::fromAscii(ip.c_str())); + } + } + else if (fastresume_rejected_alert* p = dynamic_cast(a.get())) { + QTorrentHandle h(p->handle); + if(h.is_valid()) { + qDebug("/!\\ Fast resume failed for %s, reason: %s", qPrintable(h.name()), p->message().c_str()); +#if LIBTORRENT_VERSION_MINOR < 15 + QString msg = QString::fromLocal8Bit(p->message().c_str()); + if(msg.contains("filesize", Qt::CaseInsensitive) && msg.contains("mismatch", Qt::CaseInsensitive) && TorrentPersistentData::isSeed(h.hash()) && h.has_missing_files()) { +#else + if(p->error.value() == 134 && TorrentPersistentData::isSeed(h.hash()) && h.has_missing_files()) { +#endif + const QString hash = h.hash(); + // Mismatching file size (files were probably moved + addConsoleMessage(tr("File sizes mismatch for torrent %1, pausing it.").arg(h.name())); + TorrentPersistentData::setErrorState(hash, true); + pauseTorrent(hash); + } else { + addConsoleMessage(tr("Fast resume data was rejected for torrent %1, checking again...").arg(h.name()), QString::fromUtf8("red")); + addConsoleMessage(tr("Reason: %1").arg(misc::toQString(p->message()))); + } + } + } + else if (url_seed_alert* p = dynamic_cast(a.get())) { + addConsoleMessage(tr("Url seed lookup failed for url: %1, message: %2").arg(misc::toQString(p->url)).arg(misc::toQString(p->message())), QString::fromUtf8("red")); + //emit urlSeedProblem(QString::fromUtf8(p->url.c_str()), QString::fromUtf8(p->msg().c_str())); + } + else if (listen_succeeded_alert *p = dynamic_cast(a.get())) { + boost::system::error_code ec; + qDebug() << "Sucessfully listening on" << p->endpoint.address().to_string(ec).c_str() << "/" << p->endpoint.port(); + // Force reannounce on all torrents because some trackers blacklist some ports + std::vector torrents = s->get_torrents(); + std::vector::iterator it; + for(it = torrents.begin(); it != torrents.end(); it++) { + it->force_reannounce(); + } + emit listenSucceeded(); + } + else if (torrent_checked_alert* p = dynamic_cast(a.get())) { + QTorrentHandle h(p->handle); + if(h.is_valid()){ + const QString hash = h.hash(); + qDebug("%s have just finished checking", qPrintable(hash)); + // Save seed status + TorrentPersistentData::saveSeedStatus(h); + // Move to temp directory if necessary + if(!h.is_seed() && !defaultTempPath.isEmpty()) { + // Check if directory is different + const QDir current_dir(h.save_path()); + const QDir save_dir(getSavePath(h.hash())); + if(current_dir == save_dir) { + qDebug("Moving the torrent to the temp directory..."); + QString root_folder = TorrentPersistentData::getRootFolder(hash); + QString torrent_tmp_path = defaultTempPath.replace("\\", "/"); + if(!root_folder.isEmpty()) { + if(!torrent_tmp_path.endsWith("/")) torrent_tmp_path += "/"; + torrent_tmp_path += root_folder; + } + h.move_storage(torrent_tmp_path); + } + } + emit torrentFinishedChecking(h); + if(torrentsToPausedAfterChecking.contains(hash)) { + torrentsToPausedAfterChecking.removeOne(hash); + h.pause(); + emit pausedTorrent(h); + } + } + } + a = s->pop_alert(); + } +} + +void QBtSession::recheckTorrent(const QString &hash) { + QTorrentHandle h = getTorrentHandle(hash); + if(h.is_valid() && h.has_metadata()) { + if(h.is_paused()) { + if(!torrentsToPausedAfterChecking.contains(h.hash())) { + torrentsToPausedAfterChecking << h.hash(); + h.resume(); + } + } + h.force_recheck(); + } +} + +QHash QBtSession::getTrackersInfo(const QString &hash) const{ + return trackersInfos.value(hash, QHash()); +} + +int QBtSession::getListenPort() const{ + qDebug() << Q_FUNC_INFO << s->listen_port(); + return s->listen_port(); +} + +session_status QBtSession::getSessionStatus() const{ + return s->status(); +} + +QString QBtSession::getSavePath(const QString &hash, bool fromScanDir, QString filePath, QString root_folder) { + QString savePath; + if(TorrentTempData::hasTempData(hash)) { + savePath = TorrentTempData::getSavePath(hash); + if(savePath.isEmpty()) { + savePath = defaultSavePath; + } + if(appendLabelToSavePath) { + qDebug("appendLabelToSavePath is true"); + const QString label = TorrentTempData::getLabel(hash); + if(!label.isEmpty()) { + savePath = misc::updateLabelInSavePath(defaultSavePath, savePath, "", label); + } + } + qDebug("getSavePath, got save_path from temp data: %s", qPrintable(savePath)); + } else { + savePath = TorrentPersistentData::getSavePath(hash); + qDebug("SavePath got from persistant data is %s", qPrintable(savePath)); + bool append_root_folder = false; + if(savePath.isEmpty()) { + if(fromScanDir && m_scanFolders->downloadInTorrentFolder(filePath)) { + savePath = QFileInfo(filePath).dir().path(); + } else { + savePath = defaultSavePath; + } + append_root_folder = true; + } + if(!fromScanDir && appendLabelToSavePath) { + const QString label = TorrentPersistentData::getLabel(hash); + if(!label.isEmpty()) { + qDebug("Torrent label is %s", qPrintable(label)); + savePath = misc::updateLabelInSavePath(defaultSavePath, savePath, "", label); + } + } + if(append_root_folder && !root_folder.isEmpty()) { + // Append torrent root folder to the save path + savePath = QDir(savePath).absoluteFilePath(root_folder); + qDebug("Torrent root folder is %s", qPrintable(root_folder)); + TorrentPersistentData::saveSavePath(hash, savePath); + } + qDebug("getSavePath, got save_path from persistent data: %s", qPrintable(savePath)); + } + // Clean path + savePath = savePath.replace("\\", "/"); + savePath = misc::expandPath(savePath); + if(!savePath.endsWith("/")) + savePath += "/"; + return savePath; +} + +// Take an url string to a torrent file, +// download the torrent file to a tmp location, then +// add it to download list +void QBtSession::downloadFromUrl(const QString &url) { + addConsoleMessage(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(url) + #ifndef DISABLE_GUI + , QPalette::WindowText + #endif + ); + //emit aboutToDownloadFromUrl(url); + // Launch downloader thread + downloader->downloadTorrentUrl(url); +} + +void QBtSession::downloadFromURLList(const QStringList& urls) { + foreach(const QString &url, urls) { + downloadFromUrl(url); + } +} + +void QBtSession::addMagnetSkipAddDlg(QString uri) { + addMagnetUri(uri, false); +} + +void QBtSession::downloadUrlAndSkipDialog(QString url, QString save_path, QString label) { + //emit aboutToDownloadFromUrl(url); + const QUrl qurl = QUrl::fromEncoded(url.toUtf8()); + savepathLabel_fromurl[qurl] = qMakePair(save_path, label); + url_skippingDlg << qurl; + // Launch downloader thread + downloader->downloadTorrentUrl(url); +} + +// Add to Bittorrent session the downloaded torrent file +void QBtSession::processDownloadedFile(QString url, QString file_path) { + const int index = url_skippingDlg.indexOf(QUrl::fromEncoded(url.toUtf8())); + if(index < 0) { + // Add file to torrent download list +#ifdef Q_WS_WIN + // Windows hack + if(!file_path.endsWith(".torrent", Qt::CaseInsensitive)) { + Q_ASSERT(QFile::exists(file_path)); + qDebug("Torrent name does not end with .torrent, from %s", qPrintable(file_path)); + if(QFile::rename(file_path, file_path+".torrent")) { + file_path += ".torrent"; + } else { + qDebug("Failed to rename torrent file!"); + } + } + qDebug("Downloading torrent at path: %s", qPrintable(file_path)); +#endif + emit newDownloadedTorrent(file_path, url); + } else { + url_skippingDlg.removeAt(index); + addTorrent(file_path, false, url, false); + } +} + +// Return current download rate for the BT +// session. Payload means that it only take into +// account "useful" part of the rate +qreal QBtSession::getPayloadDownloadRate() const{ + return s->status().payload_download_rate; +} + +// Return current upload rate for the BT +// session. Payload means that it only take into +// account "useful" part of the rate +qreal QBtSession::getPayloadUploadRate() const{ + return s->status().payload_upload_rate; +} + +#if LIBTORRENT_VERSION_MINOR < 15 +// Save DHT entry to hard drive +void QBtSession::saveDHTEntry() { + // Save DHT entry + if(DHTEnabled) { + try{ + entry dht_state = s->dht_state(); + const QString dht_path = misc::cacheLocation()+QDir::separator()+QString::fromUtf8("dht_state"); + if(QFile::exists(dht_path)) + misc::safeRemove(dht_path); + boost::filesystem::ofstream out(dht_path.toLocal8Bit().constData(), std::ios_base::binary); + out.unsetf(std::ios_base::skipws); + bencode(std::ostream_iterator(out), dht_state); + qDebug("DHT entry saved"); + }catch (std::exception& e) { + std::cerr << e.what() << std::endl; + } + } +} +#endif + +void QBtSession::applyEncryptionSettings(pe_settings se) { + qDebug("Applying encryption settings"); + s->set_pe_settings(se); +} + +// Will fast resume torrents in +// backup directory +void QBtSession::startUpTorrents() { + qDebug("Resuming unfinished torrents"); + const QDir torrentBackup(misc::BTBackupLocation()); + const QStringList known_torrents = TorrentPersistentData::knownTorrents(); + + // Safety measure because some people reported torrent loss since + // we switch the v1.5 way of resuming torrents on startup + QStringList filters; + filters << "*.torrent"; + const QStringList torrents_on_hd = torrentBackup.entryList(filters, QDir::Files, QDir::Unsorted); + foreach(QString hash, torrents_on_hd) { + hash.chop(8); // remove trailing .torrent + if(!known_torrents.contains(hash)) { + qDebug("found torrent with hash: %s on hard disk", qPrintable(hash)); + std::cerr << "ERROR Detected!!! Adding back torrent " << qPrintable(hash) << " which got lost for some reason." << std::endl; + addTorrent(torrentBackup.path()+QDir::separator()+hash+".torrent", false, QString(), true); + } + } + // End of safety measure + + qDebug("Starting up torrents"); + if(isQueueingEnabled()) { + priority_queue, vector >, std::greater > > torrent_queue; + foreach(const QString &hash, known_torrents) { + QString filePath; + if(TorrentPersistentData::isMagnet(hash)) { + filePath = TorrentPersistentData::getMagnetUri(hash); + } else { + filePath = torrentBackup.path()+QDir::separator()+hash+".torrent"; + } + const int prio = TorrentPersistentData::getPriority(hash); + torrent_queue.push(qMakePair(prio, hash)); + } + qDebug("Priority_queue size: %ld", (long)torrent_queue.size()); + // Resume downloads + while(!torrent_queue.empty()) { + const QString hash = torrent_queue.top().second; + torrent_queue.pop(); + qDebug("Starting up torrent %s", qPrintable(hash)); + if(TorrentPersistentData::isMagnet(hash)) { + addMagnetUri(TorrentPersistentData::getMagnetUri(hash), true); + } else { + addTorrent(torrentBackup.path()+QDir::separator()+hash+".torrent", false, QString(), true); + } + } + } else { + // Resume downloads + foreach(const QString &hash, known_torrents) { + qDebug("Starting up torrent %s", qPrintable(hash)); + if(TorrentPersistentData::isMagnet(hash)) + addMagnetUri(TorrentPersistentData::getMagnetUri(hash), true); + else + addTorrent(torrentBackup.path()+QDir::separator()+hash+".torrent", false, QString(), true); + } + } + QIniSettings settings("qBittorrent", "qBittorrent"); + settings.setValue("ported_to_new_savepath_system", true); + qDebug("Unfinished torrents resumed"); +} + +QBtSession * QBtSession::instance() +{ + if(!m_instance) { + m_instance = new QBtSession; + } + return m_instance; +} + +void QBtSession::drop() +{ + if(m_instance) { + delete m_instance; + m_instance = 0; + } +} + +qlonglong QBtSession::getETA(const QString &hash) const +{ + return m_speedMonitor->getETA(hash); +} + +void QBtSession::handleIPFilterParsed(int ruleCount) +{ + addConsoleMessage(tr("Successfuly parsed the provided IP filter: %1 rules were applied.", "%1 is a number").arg(ruleCount)); + emit ipFilterParsed(false, ruleCount); +} + +void QBtSession::handleIPFilterError() +{ + addConsoleMessage(tr("Error: Failed to parse the provided IP filter."), "red"); + emit ipFilterParsed(true, 0); +} + +entry QBtSession::generateFilePriorityResumeData(boost::intrusive_ptr &t, const std::vector &fp) +{ + entry::dictionary_type rd; + rd["file-format"] = "libtorrent resume file"; + rd["file-version"] = 1; + rd["libtorrent-version"] = LIBTORRENT_VERSION; + rd["allocation"] = "full"; + sha1_hash info_hash = t->info_hash(); + rd["info-hash"] = std::string((char*)info_hash.begin(), (char*)info_hash.end()); + // Priorities + entry::list_type priorities; + for(uint i=0; inum_files(); ++i) { + entry::list_type p; + p.push_back(entry(0)); + p.push_back(entry(0)); + sizes.push_back(entry(p)); + } + rd["file sizes"] = entry(sizes); + // Slots + entry::list_type tslots; + for(int i=0; inum_pieces(); ++i) { + tslots.push_back(-1); + } + rd["slots"] = entry(tslots); + + entry::string_type pieces; + pieces.resize(t->num_pieces()); + std::memset(&pieces[0], 0, pieces.size()); + rd["pieces"] = entry(pieces); + + entry ret(rd); + Q_ASSERT(ret.type() == entry::dictionary_t); + return ret; +} diff --git a/src/qtlibtorrent/qbtsession.h b/src/qtlibtorrent/qbtsession.h new file mode 100644 index 000000000..079d618b4 --- /dev/null +++ b/src/qtlibtorrent/qbtsession.h @@ -0,0 +1,280 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ +#ifndef __BITTORRENT_H__ +#define __BITTORRENT_H__ + +#include +#include +#include +#ifdef DISABLE_GUI +#include +#else +#include +#include +#endif +#include +#include + +#include +#include +#include + +#include "qtracker.h" +#include "qtorrenthandle.h" +#include "trackerinfos.h" + +#define MAX_SAMPLES 20 + +class DownloadThread; +class FilterParserThread; +class HttpServer; +class BandwidthScheduler; +class ScanFoldersModel; +class TorrentSpeedMonitor; +class DNSUpdater; + +class QBtSession : public QObject { + Q_OBJECT + Q_DISABLE_COPY(QBtSession) + +public: + static const qreal MAX_RATIO; + +private: + explicit QBtSession(); + static QBtSession* m_instance; + enum shutDownAction { NO_SHUTDOWN, SHUTDOWN_COMPUTER, SUSPEND_COMPUTER }; + +public: + static QBtSession* instance(); + static void drop(); + ~QBtSession(); + QTorrentHandle getTorrentHandle(const QString &hash) const; + std::vector getTorrents() const; + bool isFilePreviewPossible(const QString& hash) const; + qreal getPayloadDownloadRate() const; + qreal getPayloadUploadRate() const; + libtorrent::session_status getSessionStatus() const; + int getListenPort() const; + qreal getRealRatio(const QString& hash) const; + QHash getTrackersInfo(const QString &hash) const; + bool hasActiveTorrents() const; + bool hasDownloadingTorrents() const; + //int getMaximumActiveDownloads() const; + //int getMaximumActiveTorrents() const; + inline QStringList getConsoleMessages() const { return consoleMessages; } + inline QStringList getPeerBanMessages() const { return peerBanMessages; } + inline libtorrent::session* getSession() const { return s; } + inline bool useTemporaryFolder() const { return !defaultTempPath.isEmpty(); } + inline QString getDefaultSavePath() const { return defaultSavePath; } + inline ScanFoldersModel* getScanFoldersModel() const { return m_scanFolders; } + inline bool isDHTEnabled() const { return DHTEnabled; } + inline bool isLSDEnabled() const { return LSDEnabled; } + inline bool isPexEnabled() const { return PeXEnabled; } + inline bool isQueueingEnabled() const { return queueingEnabled; } + +public slots: + QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false); + QTorrentHandle addMagnetUri(QString magnet_uri, bool resumed=false); + void loadSessionState(); + void saveSessionState(); + void downloadFromUrl(const QString &url); + void deleteTorrent(const QString &hash, bool delete_local_files = false); + void startUpTorrents(); + void recheckTorrent(const QString &hash); + void useAlternativeSpeedsLimit(bool alternative); + qlonglong getETA(const QString& hash) const; + /* Needed by Web UI */ + void pauseAllTorrents(); + void pauseTorrent(const QString &hash); + void resumeTorrent(const QString &hash); + void resumeAllTorrents(); + /* End Web UI */ + void preAllocateAllFiles(bool b); + void saveFastResumeData(); + void enableIPFilter(const QString &filter_path, bool force=false); + void disableIPFilter(); + void setQueueingEnabled(bool enable); + void handleDownloadFailure(QString url, QString reason); + void downloadUrlAndSkipDialog(QString url, QString save_path=QString(), QString label=QString()); + // Session configuration - Setters + void setListeningPort(int port); + void setMaxConnections(int maxConnec); + void setMaxConnectionsPerTorrent(int max); + void setMaxUploadsPerTorrent(int max); + void setDownloadRateLimit(long rate); + void setUploadRateLimit(long rate); + void setGlobalMaxRatio(qreal ratio); + qreal getGlobalMaxRatio() const { return global_ratio_limit; } + void setMaxRatioPerTorrent(const QString &hash, qreal ratio); + qreal getMaxRatioPerTorrent(const QString &hash, bool *usesGlobalRatio) const; + void removeRatioPerTorrent(const QString &hash); + void setDHTPort(int dht_port); + void setProxySettings(libtorrent::proxy_settings proxySettings); + void setSessionSettings(const libtorrent::session_settings &sessionSettings); + void startTorrentsInPause(bool b); + void setDefaultTempPath(QString temppath); + void setAppendLabelToSavePath(bool append); + void appendLabelToTorrentSavePath(const QTorrentHandle &h); + void changeLabelInTorrentSavePath(const QTorrentHandle &h, QString old_label, QString new_label); +#if LIBTORRENT_VERSION_MINOR > 14 + void appendqBextensionToTorrent(const QTorrentHandle &h, bool append); + void setAppendqBExtension(bool append); +#endif + void applyEncryptionSettings(libtorrent::pe_settings se); + void setDownloadLimit(QString hash, long val); + void setUploadLimit(QString hash, long val); + void enableUPnP(bool b); + void enableLSD(bool b); + bool enableDHT(bool b); +#ifdef DISABLE_GUI + void addConsoleMessage(QString msg, QString color=QString::null); +#else + void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText)); +#endif + void addPeerBanMessage(QString msg, bool from_ipfilter); + void processDownloadedFile(QString, QString); + void addMagnetSkipAddDlg(QString uri); + void downloadFromURLList(const QStringList& urls); + void configureSession(); + void banIP(QString ip); + void recursiveTorrentDownload(const QTorrentHandle &h); + +private: + QString getSavePath(const QString &hash, bool fromScanDir = false, QString filePath = QString::null, QString root_folder=QString::null); + bool loadFastResumeData(const QString &hash, std::vector &buf); + void loadTorrentSettings(QTorrentHandle &h); + void loadTorrentTempData(QTorrentHandle &h, QString savePath, bool magnet); + libtorrent::add_torrent_params initializeAddTorrentParams(const QString &hash); + libtorrent::entry generateFilePriorityResumeData(boost::intrusive_ptr &t, const std::vector &fp); + void updateRatioTimer(); + +private slots: + void addTorrentsFromScanFolder(QStringList&); + void readAlerts(); + void processBigRatios(); + void exportTorrentFiles(QString path); + void saveTempFastResumeData(); + void sendNotificationEmail(const QTorrentHandle &h); + void autoRunExternalProgram(const QTorrentHandle &h, bool async=true); + void cleanUpAutoRunProcess(int); + void mergeTorrents(QTorrentHandle &h_ex, boost::intrusive_ptr t); + void exportTorrentFile(const QTorrentHandle &h); + void initWebUi(); + void handleIPFilterParsed(int ruleCount); + void handleIPFilterError(); + +signals: + void addedTorrent(const QTorrentHandle& h); + void deletedTorrent(const QString &hash); + void torrentAboutToBeRemoved(const QTorrentHandle &h); + void pausedTorrent(const QTorrentHandle& h); + void resumedTorrent(const QTorrentHandle& h); + void finishedTorrent(const QTorrentHandle& h); + void fullDiskError(const QTorrentHandle& h, QString msg); + void trackerError(const QString &hash, QString time, QString msg); + void trackerAuthenticationRequired(const QTorrentHandle& h); + void newDownloadedTorrent(QString path, QString url); + void updateFileSize(const QString &hash); + void downloadFromUrlFailure(QString url, QString reason); + void torrentFinishedChecking(const QTorrentHandle& h); + void metadataReceived(const QTorrentHandle &h); + void savePathChanged(const QTorrentHandle &h); + void newConsoleMessage(const QString &msg); + void newBanMessage(const QString &msg); + void alternativeSpeedsModeChanged(bool alternative); + void recursiveTorrentDownloadPossible(const QTorrentHandle &h); + void ipFilterParsed(bool error, int ruleCount); + void listenSucceeded(); + +private: +#if LIBTORRENT_VERSION_MINOR < 15 + void saveDHTEntry(); +#endif + +private: + // Bittorrent + libtorrent::session *s; + QPointer timerAlerts; + QPointer bd_scheduler; + QMap > savepathLabel_fromurl; // Use QMap for compatibility with Qt < 4.7: qHash(QUrl) + QHash > trackersInfos; + QHash savePathsToRemove; + QStringList torrentsToPausedAfterChecking; + QTimer resumeDataTimer; + // Ratio + QPointer BigRatioTimer; + // HTTP + DownloadThread* downloader; + // File System + ScanFoldersModel *m_scanFolders; + // Console / Log + QStringList consoleMessages; + QStringList peerBanMessages; + // Settings + bool preAllocateAll; + bool addInPause; + qreal global_ratio_limit; + int high_ratio_action; + bool LSDEnabled; + bool DHTEnabled; + int current_dht_port; + bool PeXEnabled; + bool queueingEnabled; + bool appendLabelToSavePath; + bool torrentExport; +#if LIBTORRENT_VERSION_MINOR > 14 + bool appendqBExtension; +#endif + QString defaultSavePath; + QString defaultTempPath; + // IP filtering + QPointer filterParser; + QString filterPath; + // Web UI + QPointer httpServer; + QList url_skippingDlg; + // GeoIP +#ifndef DISABLE_GUI + bool geoipDBLoaded; + bool resolve_countries; +#endif + // Tracker + QPointer m_tracker; + TorrentSpeedMonitor *m_speedMonitor; + shutDownAction m_shutdownAct; + // Port forwarding + libtorrent::upnp *m_upnp; + libtorrent::natpmp *m_natpmp; + // DynDNS + DNSUpdater *m_dynDNSUpdater; +}; + +#endif diff --git a/src/qtlibtorrent/qtlibtorrent.pri b/src/qtlibtorrent/qtlibtorrent.pri new file mode 100644 index 000000000..5ded68dcd --- /dev/null +++ b/src/qtlibtorrent/qtlibtorrent.pri @@ -0,0 +1,19 @@ +INCLUDEPATH += $$PWD + +HEADERS += $$PWD/qbtsession.h \ + $$PWD/qtorrenthandle.h \ + $$PWD/bandwidthscheduler.h \ + $$PWD/trackerinfos.h \ + $$PWD/torrentspeedmonitor.h \ + $$PWD/filterparserthread.h + +SOURCES += $$PWD/qbtsession.cpp \ + $$PWD/qtorrenthandle.cpp \ + $$PWD/torrentspeedmonitor.cpp + +!contains(DEFINES, DISABLE_GUI) { + HEADERS += $$PWD/torrentmodel.h \ + $$PWD/shutdownconfirm.h + + SOURCES += $$PWD/torrentmodel.cpp +} diff --git a/src/qtlibtorrent/qtorrenthandle.cpp b/src/qtlibtorrent/qtorrenthandle.cpp new file mode 100644 index 000000000..bbba3f7b7 --- /dev/null +++ b/src/qtlibtorrent/qtorrenthandle.cpp @@ -0,0 +1,799 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include +#include +#include +#include "misc.h" +#include "preferences.h" +#include "qtorrenthandle.h" +#include "torrentpersistentdata.h" +#include +#include +#include +#include +#include +#include + +#ifdef Q_WS_WIN +#include +#endif + +using namespace libtorrent; +using namespace std; + +QTorrentHandle::QTorrentHandle(torrent_handle h): torrent_handle(h) {} + +// +// Getters +// + +QString QTorrentHandle::hash() const { + return misc::toQString(torrent_handle::info_hash()); +} + +QString QTorrentHandle::name() const { + QString name = TorrentPersistentData::getName(hash()); + if(name.isEmpty()) { + name = misc::toQStringU(torrent_handle::name()); + } + return name; +} + +QString QTorrentHandle::creation_date() const { +#if LIBTORRENT_VERSION_MINOR > 15 + boost::optional t = torrent_handle::get_torrent_info().creation_date(); + return misc::time_tToQString(t); +#else + boost::optional boostDate = torrent_handle::get_torrent_info().creation_date(); + return misc::boostTimeToQString(boostDate); +#endif +} + +QString QTorrentHandle::next_announce() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return misc::userFriendlyDuration(torrent_handle::status(0x0).next_announce.total_seconds()); +#else + return misc::userFriendlyDuration(torrent_handle::status().next_announce.total_seconds()); +#endif +} + +qlonglong QTorrentHandle::next_announce_s() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).next_announce.total_seconds(); +#else + return torrent_handle::status().next_announce.total_seconds(); +#endif +} + +qreal QTorrentHandle::progress() const { +#if LIBTORRENT_VERSION_MINOR > 15 + torrent_status st = torrent_handle::status(query_accurate_download_counters); +#else + torrent_status st = torrent_handle::status(); +#endif + if(!st.total_wanted) + return 0.; + if (st.total_wanted_done == st.total_wanted) + return 1.; + qreal progress = (float)st.total_wanted_done/(float)st.total_wanted; + Q_ASSERT(progress >= 0. && progress <= 1.); + return progress; +} + +bitfield QTorrentHandle::pieces() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).pieces; +#else + return torrent_handle::status().pieces; +#endif +} + +QString QTorrentHandle::current_tracker() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return misc::toQString(torrent_handle::status(0x0).current_tracker); +#else + return misc::toQString(torrent_handle::status().current_tracker); +#endif +} + +bool QTorrentHandle::is_paused() const { +#if LIBTORRENT_VERSION_MINOR > 15 + torrent_status st = torrent_handle::status(0x0); + return st.paused && !st.auto_managed; +#else + return torrent_handle::is_paused() && !torrent_handle::is_auto_managed(); +#endif +} + +bool QTorrentHandle::is_queued() const { +#if LIBTORRENT_VERSION_MINOR > 15 + torrent_status st = torrent_handle::status(0x0); + return st.paused && st.auto_managed; +#else + return torrent_handle::is_paused() && torrent_handle::is_auto_managed(); +#endif +} + +size_type QTorrentHandle::total_size() const { + return torrent_handle::get_torrent_info().total_size(); +} + +size_type QTorrentHandle::piece_length() const { + return torrent_handle::get_torrent_info().piece_length(); +} + +int QTorrentHandle::num_pieces() const { + return torrent_handle::get_torrent_info().num_pieces(); +} + +bool QTorrentHandle::first_last_piece_first() const { + // Detect first media file + int index = 0; + for(index = 0; index < num_files(); ++index) { +#if LIBTORRENT_VERSION_MINOR > 15 + QString path = misc::toQStringU(get_torrent_info().file_at(index).path); +#else + QString path = misc::toQStringU(get_torrent_info().file_at(index).path.string()); +#endif + const QString ext = misc::file_extension(path); + if(misc::isPreviewable(ext) && torrent_handle::file_priority(index) > 0) { + break; + } + ++index; + } + if(index >= torrent_handle::get_torrent_info().num_files()) return false; + file_entry media_file = torrent_handle::get_torrent_info().file_at(index); + int piece_size = torrent_handle::get_torrent_info().piece_length(); + Q_ASSERT(piece_size>0); + int first_piece = floor((media_file.offset+1)/(double)piece_size); + Q_ASSERT(first_piece >= 0 && first_piece < torrent_handle::get_torrent_info().num_pieces()); + qDebug("First piece of the file is %d/%d", first_piece, torrent_handle::get_torrent_info().num_pieces()-1); + int num_pieces_in_file = ceil(media_file.size/(double)piece_size); + int last_piece = first_piece+num_pieces_in_file-1; + Q_ASSERT(last_piece >= 0 && last_piece < torrent_handle::get_torrent_info().num_pieces()); + qDebug("last piece of the file is %d/%d", last_piece, torrent_handle::get_torrent_info().num_pieces()-1); + return (torrent_handle::piece_priority(first_piece) == 7) && (torrent_handle::piece_priority(last_piece) == 7); +} + +size_type QTorrentHandle::total_wanted_done() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(query_accurate_download_counters).total_wanted_done; +#else + return torrent_handle::status().total_wanted_done; +#endif +} + +size_type QTorrentHandle::total_wanted() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).total_wanted; +#else + return torrent_handle::status().total_wanted; +#endif +} + +qreal QTorrentHandle::download_payload_rate() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).download_payload_rate; +#else + return torrent_handle::status().download_payload_rate; +#endif +} + +qreal QTorrentHandle::upload_payload_rate() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).upload_payload_rate; +#else + return torrent_handle::status().upload_payload_rate; +#endif +} + +int QTorrentHandle::num_peers() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).num_peers; +#else + return torrent_handle::status().num_peers; +#endif +} + +int QTorrentHandle::num_seeds() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).num_seeds; +#else + return torrent_handle::status().num_seeds; +#endif +} + +int QTorrentHandle::num_complete() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).num_complete; +#else + return torrent_handle::status().num_complete; +#endif +} + +int QTorrentHandle::num_incomplete() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).num_incomplete; +#else + return torrent_handle::status().num_incomplete; +#endif +} + +QString QTorrentHandle::save_path() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return misc::toQStringU(torrent_handle::save_path()).replace("\\", "/"); +#else + return misc::toQStringU(torrent_handle::save_path().string()).replace("\\", "/"); +#endif +} + +QStringList QTorrentHandle::url_seeds() const { + QStringList res; + try { + const std::set existing_seeds = torrent_handle::url_seeds(); + std::set::const_iterator it; + for(it = existing_seeds.begin(); it != existing_seeds.end(); it++) { + qDebug("URL Seed: %s", it->c_str()); + res << misc::toQString(*it); + } + } catch(std::exception e) { + std::cout << "ERROR: Failed to convert the URL seed" << std::endl; + } + return res; +} + +// get the size of the torrent without the filtered files +size_type QTorrentHandle::actual_size() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(query_accurate_download_counters).total_wanted; +#else + return torrent_handle::status().total_wanted; +#endif +} + +bool QTorrentHandle::has_filtered_pieces() const { + std::vector piece_priorities = torrent_handle::piece_priorities(); + for(unsigned int i = 0; i 15 + return misc::fileName(filepath_at(index)); +#else + return misc::toQStringU(torrent_handle::get_torrent_info().file_at(index).path.leaf()); +#endif +} + +size_type QTorrentHandle::filesize_at(unsigned int index) const { + Q_ASSERT(index < (unsigned int)torrent_handle::get_torrent_info().num_files()); + return torrent_handle::get_torrent_info().file_at(index).size; +} + +QString QTorrentHandle::filepath_at(unsigned int index) const { +#if LIBTORRENT_VERSION_MINOR > 15 + return misc::toQStringU(torrent_handle::get_torrent_info().file_at(index).path); +#else + return misc::toQStringU(torrent_handle::get_torrent_info().file_at(index).path.string()); +#endif +} + +QString QTorrentHandle::orig_filepath_at(unsigned int index) const { +#if LIBTORRENT_VERSION_MINOR > 15 + return misc::toQStringU(torrent_handle::get_torrent_info().orig_files().at(index).path); +#else + return misc::toQStringU(torrent_handle::get_torrent_info().orig_files().at(index).path.string()); +#endif +} + +torrent_status::state_t QTorrentHandle::state() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).state; +#else + return torrent_handle::status().state; +#endif +} + +QString QTorrentHandle::creator() const { + return misc::toQStringU(torrent_handle::get_torrent_info().creator()); +} + +QString QTorrentHandle::comment() const { + return misc::toQStringU(torrent_handle::get_torrent_info().comment()); +} + +size_type QTorrentHandle::total_failed_bytes() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).total_failed_bytes; +#else + return torrent_handle::status().total_failed_bytes; +#endif +} + +size_type QTorrentHandle::total_redundant_bytes() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).total_redundant_bytes; +#else + return torrent_handle::status().total_redundant_bytes; +#endif +} + +bool QTorrentHandle::is_checking() const { +#if LIBTORRENT_VERSION_MINOR > 15 + torrent_status st = torrent_handle::status(0x0); +#else + torrent_status st = torrent_handle::status(); +#endif + return st.state == torrent_status::checking_files || st.state == torrent_status::checking_resume_data; +} + +size_type QTorrentHandle::total_done() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).total_done; +#else + return torrent_handle::status().total_done; +#endif +} + +size_type QTorrentHandle::all_time_download() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).all_time_download; +#else + return torrent_handle::status().all_time_download; +#endif +} + +size_type QTorrentHandle::all_time_upload() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).all_time_upload; +#else + return torrent_handle::status().all_time_upload; +#endif +} + +size_type QTorrentHandle::total_payload_download() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).total_payload_download; +#else + return torrent_handle::status().total_payload_download; +#endif +} + +size_type QTorrentHandle::total_payload_upload() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).total_payload_upload; +#else + return torrent_handle::status().total_payload_upload; +#endif +} + +// Return a list of absolute paths corresponding +// to all files in a torrent +QStringList QTorrentHandle::absolute_files_path() const { + QDir saveDir(save_path()); + QStringList res; + for(int i = 0; i fp = torrent_handle::file_priorities(); + for(uint i = 0; i < fp.size(); ++i) { + if(fp[i] == 0) { + const QString file_path = QDir::cleanPath(saveDir.absoluteFilePath(filepath_at(i))); + if(file_path.contains(".unwanted")) + res << file_path; + } + } + return res; +} + +bool QTorrentHandle::has_missing_files() const { + const QStringList paths = absolute_files_path(); + foreach(const QString &path, paths) { + if(!QFile::exists(path)) return true; + } + return false; +} + +int QTorrentHandle::queue_position() const { + if(torrent_handle::queue_position() < 0) + return -1; + return torrent_handle::queue_position()+1; +} + +int QTorrentHandle::num_uploads() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).num_uploads; +#else + return torrent_handle::status().num_uploads; +#endif +} + +bool QTorrentHandle::is_seed() const { + // Affected by bug http://code.rasterbar.com/libtorrent/ticket/402 + //return torrent_handle::is_seed(); + // May suffer from approximation problems + //return (progress() == 1.); + // This looks safe + return (state() == torrent_status::finished || state() == torrent_status::seeding); +} + +bool QTorrentHandle::is_auto_managed() const { +#if LIBTORRENT_VERSION_MINOR > 15 + torrent_status status = torrent_handle::status(0x0); + return status.auto_managed; +#else + return torrent_handle::is_auto_managed(); +#endif +} + +bool QTorrentHandle::is_sequential_download() const { +#if LIBTORRENT_VERSION_MINOR > 15 + torrent_status status = torrent_handle::status(0x0); + return status.sequential_download; +#else + return torrent_handle::is_sequential_download(); +#endif +} + +qlonglong QTorrentHandle::active_time() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).active_time; +#else + return torrent_handle::status().active_time; +#endif +} + +qlonglong QTorrentHandle::seeding_time() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).seeding_time; +#else + return torrent_handle::status().seeding_time; +#endif +} + +int QTorrentHandle::num_connections() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).num_connections; +#else + return torrent_handle::status().num_connections; +#endif +} + +int QTorrentHandle::connections_limit() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(0x0).connections_limit; +#else + return torrent_handle::status().connections_limit; +#endif +} + +bool QTorrentHandle::priv() const { + return torrent_handle::get_torrent_info().priv(); +} + +QString QTorrentHandle::firstFileSavePath() const { + Q_ASSERT(has_metadata()); + QString fsave_path = TorrentPersistentData::getSavePath(hash()); + if(fsave_path.isEmpty()) + fsave_path = save_path(); + fsave_path = fsave_path.replace("\\", "/"); + if(!fsave_path.endsWith("/")) + fsave_path += "/"; + fsave_path += filepath_at(0); + // Remove .!qB extension + if(fsave_path.endsWith(".!qB", Qt::CaseInsensitive)) + fsave_path.chop(4); + return fsave_path; +} + +bool QTorrentHandle::has_error() const { +#if LIBTORRENT_VERSION_MINOR > 15 + torrent_status st = torrent_handle::status(0x0); + return st.paused && !st.error.empty(); +#else + return torrent_handle::is_paused() && !torrent_handle::status().error.empty(); +#endif +} + +QString QTorrentHandle::error() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return misc::toQString(torrent_handle::status(0x0).error); +#else + return misc::toQString(torrent_handle::status().error); +#endif +} + +void QTorrentHandle::downloading_pieces(bitfield &bf) const { + std::vector queue; + torrent_handle::get_download_queue(queue); + for(std::vector::iterator it=queue.begin(); it!= queue.end(); it++) { + bf.set_bit(it->piece_index); + } + return; +} + +bool QTorrentHandle::has_metadata() const { +#if LIBTORRENT_VERSION_MINOR > 15 + return torrent_handle::status(query_distributed_copies).has_metadata; +#else + return torrent_handle::has_metadata(); +#endif +} + +float QTorrentHandle::distributed_copies() const { +#if LIBTORRENT_VERSION_MINOR > 15 +return torrent_handle::status(0x0).distributed_copies; +#else + return torrent_handle::status().distributed_copies; +#endif +} + +void QTorrentHandle::file_progress(std::vector& fp) const { + torrent_handle::file_progress(fp +#if LIBTORRENT_VERSION_MINOR > 14 + , torrent_handle::piece_granularity +#endif + ); +} + +// +// Setters +// + +void QTorrentHandle::pause() const { + torrent_handle::auto_managed(false); + torrent_handle::pause(); + torrent_handle::save_resume_data(); +} + +void QTorrentHandle::resume() const { + if(has_error()) torrent_handle::clear_error(); + const QString torrent_hash = hash(); + bool has_persistant_error = TorrentPersistentData::hasError(torrent_hash); + TorrentPersistentData::setErrorState(torrent_hash, false); + bool temp_path_enabled = Preferences().isTempPathEnabled(); + if(has_persistant_error && temp_path_enabled) { + // Torrent was supposed to be seeding, checking again in final destination + qDebug("Resuming a torrent with error..."); + const QString final_save_path = TorrentPersistentData::getSavePath(torrent_hash); + qDebug("Torrent final path is: %s", qPrintable(final_save_path)); + if(!final_save_path.isEmpty()) + move_storage(final_save_path); + } + torrent_handle::auto_managed(true); + torrent_handle::resume(); + if(has_persistant_error && temp_path_enabled) { + // Force recheck + torrent_handle::force_recheck(); + } +} + +void QTorrentHandle::remove_url_seed(QString seed) const { + torrent_handle::remove_url_seed(seed.toStdString()); +} + +void QTorrentHandle::add_url_seed(QString seed) const { + const std::string str_seed = seed.toStdString(); + qDebug("calling torrent_handle::add_url_seed(%s)", str_seed.c_str()); + torrent_handle::add_url_seed(str_seed); +} + +void QTorrentHandle::set_tracker_login(QString username, QString password) const { + torrent_handle::set_tracker_login(std::string(username.toLocal8Bit().constData()), std::string(password.toLocal8Bit().constData())); +} + +void QTorrentHandle::move_storage(QString new_path) const { + if(QDir(save_path()) == QDir(new_path)) return; + TorrentPersistentData::setPreviousSavePath(hash(), save_path()); + // Create destination directory if necessary + // or move_storage() will fail... + QDir().mkpath(new_path); + // Actually move the storage + torrent_handle::move_storage(new_path.toUtf8().constData()); +} + +bool QTorrentHandle::save_torrent_file(QString path) const { + if(!has_metadata()) return false; + QFile met_file(path); + if(met_file.open(QIODevice::WriteOnly)) { + entry meta = bdecode(torrent_handle::get_torrent_info().metadata().get(), torrent_handle::get_torrent_info().metadata().get()+torrent_handle::get_torrent_info().metadata_size()); + entry torrent_file(entry::dictionary_t); + torrent_file["info"] = meta; + if(!torrent_handle::trackers().empty()) + torrent_file["announce"] = torrent_handle::trackers().front().url; + boost::filesystem::ofstream out(path.toLocal8Bit().constData(), std::ios_base::binary); + out.unsetf(std::ios_base::skipws); + bencode(std::ostream_iterator(out), torrent_file); + return true; + } + return false; +} + +void QTorrentHandle::file_priority(int index, int priority) const { + vector priorities = torrent_handle::file_priorities(); + if(priorities[index] != priority) { + priorities[index] = priority; + prioritize_files(priorities); + } +} + +void QTorrentHandle::prioritize_files(const vector &files) const { + if((int)files.size() != torrent_handle::get_torrent_info().num_files()) return; + qDebug() << Q_FUNC_INFO; + bool was_seed = is_seed(); + vector progress; + file_progress(progress); + torrent_handle::prioritize_files(files); + for(uint i=0; i 0) { + QString old_path = filepath_at(i); + QString old_name = filename_at(i); + QDir parent_path(misc::branchPath(old_path)); + if(parent_path.dirName() == ".unwanted") { + QDir new_path(misc::branchPath(parent_path.path())); + rename_file(i, new_path.filePath(old_name)); + // Remove .unwanted directory if empty + new_path.rmdir(".unwanted"); + } + } + } + if(was_seed && !is_seed()) { + // Save seed status + TorrentPersistentData::saveSeedStatus(*this); + // Move to temp folder if necessary + const Preferences pref; + if(pref.isTempPathEnabled()) { + QString tmp_path = pref.getTempPath(); + QString root_folder = TorrentPersistentData::getRootFolder(hash()); + if(!root_folder.isEmpty()) + tmp_path = QDir(tmp_path).absoluteFilePath(root_folder); + move_storage(tmp_path); + } + } +} + +void QTorrentHandle::add_tracker(const announce_entry& url) const { +#if LIBTORRENT_VERSION_MINOR > 14 + torrent_handle::add_tracker(url); +#else + std::vector trackers = torrent_handle::trackers(); + bool exists = false; + std::vector::iterator it = trackers.begin(); + while(it != trackers.end()) { + if(it->url == url.url) { + exists = true; + break; + } + it++; + } + if(!exists) { + trackers.push_back(url); + torrent_handle::replace_trackers(trackers); + } +#endif +} + +void QTorrentHandle::prioritize_first_last_piece(int file_index, bool b) const { + // Determine the priority to set + int prio = 7; // MAX + if(!b) prio = torrent_handle::file_priority(file_index); + file_entry file = get_torrent_info().file_at(file_index); + // Determine the first and last piece of the file + int piece_size = torrent_handle::get_torrent_info().piece_length(); + Q_ASSERT(piece_size>0); + int first_piece = floor((file.offset+1)/(double)piece_size); + Q_ASSERT(first_piece >= 0 && first_piece < torrent_handle::get_torrent_info().num_pieces()); + qDebug("First piece of the file is %d/%d", first_piece, torrent_handle::get_torrent_info().num_pieces()-1); + int num_pieces_in_file = ceil(file.size/(double)piece_size); + int last_piece = first_piece+num_pieces_in_file-1; + Q_ASSERT(last_piece >= 0 && last_piece < torrent_handle::get_torrent_info().num_pieces()); + qDebug("last piece of the file is %d/%d", last_piece, torrent_handle::get_torrent_info().num_pieces()-1); + torrent_handle::piece_priority(first_piece, prio); + torrent_handle::piece_priority(last_piece, prio); +} + +void QTorrentHandle::prioritize_first_last_piece(bool b) const { + if(!has_metadata()) return; + // Download first and last pieces first for all media files in the torrent + int index = 0; + for(index = 0; index < num_files(); ++index) { + const QString path = filepath_at(index); + const QString ext = misc::file_extension(path); + if(misc::isPreviewable(ext) && torrent_handle::file_priority(index) > 0) { + qDebug() << "File" << path << "is previewable, toggle downloading of first/last pieces first"; + prioritize_first_last_piece(index, b); + } + } +} + +void QTorrentHandle::rename_file(int index, QString name) const { + qDebug() << Q_FUNC_INFO << index << name; + torrent_handle::rename_file(index, std::string(name.toUtf8().constData())); +} + +// +// Operators +// + +bool QTorrentHandle::operator ==(const QTorrentHandle& new_h) const{ + const QString hash = misc::toQString(torrent_handle::info_hash()); + return (hash == new_h.hash()); +} diff --git a/src/qtlibtorrent/qtorrenthandle.h b/src/qtlibtorrent/qtorrenthandle.h new file mode 100644 index 000000000..c592d563b --- /dev/null +++ b/src/qtlibtorrent/qtorrenthandle.h @@ -0,0 +1,150 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef QTORRENTHANDLE_H +#define QTORRENTHANDLE_H + +#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE +class QStringList; +QT_END_NAMESPACE + +// A wrapper for torrent_handle in libtorrent +// to interact well with Qt types +class QTorrentHandle : public libtorrent::torrent_handle { + +public: + + // + // Constructors + // + + QTorrentHandle() {} + explicit QTorrentHandle(libtorrent::torrent_handle h); + + // + // Getters + // + QString hash() const; + QString name() const; + qreal progress() const; + libtorrent::bitfield pieces() const; + QString current_tracker() const; + bool is_paused() const; + bool has_filtered_pieces() const; + libtorrent::size_type total_size() const; + libtorrent::size_type piece_length() const; + int num_pieces() const; + libtorrent::size_type total_wanted_done() const; + libtorrent::size_type total_wanted() const; + qreal download_payload_rate() const; + qreal upload_payload_rate() const; + int num_connections() const; + int connections_limit() const; + int num_peers() const; + int num_seeds() const; + int num_complete() const; + int num_incomplete() const; + QString save_path() const; + QStringList url_seeds() const; + libtorrent::size_type actual_size() const; + int num_files() const; + int queue_position() const; + bool is_queued() const; + QString filename_at(unsigned int index) const; + libtorrent::size_type filesize_at(unsigned int index) const; + QString filepath_at(unsigned int index) const; + QString orig_filepath_at(unsigned int index) const; + libtorrent::torrent_status::state_t state() const; + QString creator() const; + QString comment() const; + libtorrent::size_type total_failed_bytes() const; + libtorrent::size_type total_redundant_bytes() const; + libtorrent::size_type total_payload_download() const; + libtorrent::size_type total_payload_upload() const; + libtorrent::size_type all_time_upload() const; + libtorrent::size_type all_time_download() const; + libtorrent::size_type total_done() const; + QStringList absolute_files_path() const; + QStringList absolute_files_path_uneeded() const; + bool has_missing_files() const; + int num_uploads() const; + bool is_seed() const; + bool is_checking() const; + bool is_auto_managed() const; + bool is_sequential_download() const; + qlonglong active_time() const; + qlonglong seeding_time() const; + QString creation_date() const; + QString next_announce() const; + qlonglong next_announce_s() const; + bool priv() const; + bool first_last_piece_first() const; + QString root_path() const; + QString firstFileSavePath() const; + bool has_error() const; + QString error() const; + void downloading_pieces(libtorrent::bitfield &bf) const; + bool has_metadata() const; + float distributed_copies() const; + void file_progress(std::vector& fp) const; + + // + // Setters + // + void pause() const; + void resume() const; + void remove_url_seed(QString seed) const; + void add_url_seed(QString seed) const; + void set_tracker_login(QString username, QString password) const; + void move_storage(QString path) const; + void add_tracker(const libtorrent::announce_entry& url) const; + void prioritize_first_last_piece(bool b) const; + void rename_file(int index, QString name) const; + bool save_torrent_file(QString path) const; + void prioritize_files(const std::vector &files) const; + void file_priority(int index, int priority) const; + + // + // Operators + // + bool operator ==(const QTorrentHandle& new_h) const; + +private: + void prioritize_first_last_piece(int file_index, bool b) const; + +}; + +#endif diff --git a/src/qtlibtorrent/shutdownconfirm.h b/src/qtlibtorrent/shutdownconfirm.h new file mode 100644 index 000000000..afb7ac051 --- /dev/null +++ b/src/qtlibtorrent/shutdownconfirm.h @@ -0,0 +1,68 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef SHUTDOWNCONFIRM_H +#define SHUTDOWNCONFIRM_H + +#include +#include +#include "misc.h" + +class ShutdownConfirmDlg : public QMessageBox { + Q_OBJECT + +public: + ShutdownConfirmDlg(const QString &message) { + // Text + setWindowTitle(tr("Shutdown confirmation")); + setText(message); + // Cancel Button + addButton(QMessageBox::Cancel); + // Icon + setIcon(QMessageBox::Warning); + // Always on top + setWindowFlags(windowFlags()|Qt::WindowStaysOnTopHint); + show(); + // Move to center + move(misc::screenCenter(this)); + } + + static bool askForConfirmation(const QString &message) { + ShutdownConfirmDlg dlg(message); + // Auto shutdown timer + QTimer timer; + connect(&timer, SIGNAL(timeout()), &dlg, SLOT(accept())); + timer.start(15000); // 15sec + dlg.exec(); + return (dlg.result() == QDialog::Accepted); + } +}; + +#endif // SHUTDOWNCONFIRM_H diff --git a/src/qtlibtorrent/torrentmodel.cpp b/src/qtlibtorrent/torrentmodel.cpp new file mode 100644 index 000000000..cddb28c99 --- /dev/null +++ b/src/qtlibtorrent/torrentmodel.cpp @@ -0,0 +1,460 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include + +#include "torrentmodel.h" +#include "torrentpersistentdata.h" +#include "qbtsession.h" + +using namespace libtorrent; + +TorrentModelItem::TorrentModelItem(const QTorrentHandle &h) +{ + m_torrent = h; + m_hash = h.hash(); + m_name = TorrentPersistentData::getName(h.hash()); + if(m_name.isEmpty()) m_name = h.name(); + m_addedTime = TorrentPersistentData::getAddedDate(h.hash()); + m_seedTime = TorrentPersistentData::getSeedDate(h.hash()); + m_label = TorrentPersistentData::getLabel(h.hash()); +} + +TorrentModelItem::State TorrentModelItem::state() const +{ + try { + // Pause or Queued + if(m_torrent.is_paused()) { + m_icon = QIcon(":/Icons/skin/paused.png"); + m_fgColor = QColor("red"); + return m_torrent.is_seed() ? STATE_PAUSED_UP : STATE_PAUSED_DL; + } + if(m_torrent.is_queued()) { + if(m_torrent.state() != torrent_status::queued_for_checking + && m_torrent.state() != torrent_status::checking_resume_data + && m_torrent.state() != torrent_status::checking_files) { + m_icon = QIcon(":/Icons/skin/queued.png"); + m_fgColor = QColor("grey"); + return m_torrent.is_seed() ? STATE_QUEUED_UP : STATE_QUEUED_DL; + } + } + // Other states + switch(m_torrent.state()) { + case torrent_status::allocating: + case torrent_status::downloading_metadata: + case torrent_status::downloading: { + if(m_torrent.download_payload_rate() > 0) { + m_icon = QIcon(":/Icons/skin/downloading.png"); + m_fgColor = QColor("green"); + return STATE_DOWNLOADING; + } else { + m_icon = QIcon(":/Icons/skin/stalledDL.png"); + m_fgColor = QColor("grey"); + return STATE_STALLED_DL; + } + } + case torrent_status::finished: + case torrent_status::seeding: + if(m_torrent.upload_payload_rate() > 0) { + m_icon = QIcon(":/Icons/skin/uploading.png"); + m_fgColor = QColor("orange"); + return STATE_SEEDING; + } else { + m_icon = QIcon(":/Icons/skin/stalledUP.png"); + m_fgColor = QColor("grey"); + return STATE_STALLED_UP; + } + case torrent_status::queued_for_checking: + case torrent_status::checking_resume_data: + case torrent_status::checking_files: + m_icon = QIcon(":/Icons/skin/checking.png"); + m_fgColor = QColor("grey"); + return m_torrent.is_seed() ? STATE_CHECKING_UP : STATE_CHECKING_DL; + default: + m_icon = QIcon(":/Icons/skin/error.png"); + m_fgColor = QColor("red"); + return STATE_INVALID; + } + } catch(invalid_handle&) { + m_icon = QIcon(":/Icons/skin/error.png"); + m_fgColor = QColor("red"); + return STATE_INVALID; + } +} + +bool TorrentModelItem::setData(int column, const QVariant &value, int role) +{ + qDebug() << Q_FUNC_INFO << column << value; + if(role != Qt::DisplayRole) return false; + // Label and Name columns can be edited + switch(column) { + case TR_NAME: + m_name = value.toString(); + TorrentPersistentData::saveName(m_torrent.hash(), m_name); + return true; + case TR_LABEL: { + QString new_label = value.toString(); + if(m_label != new_label) { + QString old_label = m_label; + m_label = new_label; + TorrentPersistentData::saveLabel(m_torrent.hash(), new_label); + emit labelChanged(old_label, new_label); + } + return true; + } + default: + break; + } + return false; +} + +QVariant TorrentModelItem::data(int column, int role) const +{ + if(role == Qt::DecorationRole && column == TR_NAME) { + return m_icon; + } + if(role == Qt::ForegroundRole) { + return m_fgColor; + } + if(role != Qt::DisplayRole && role != Qt::UserRole) return QVariant(); + switch(column) { + case TR_NAME: + return m_name.isEmpty()? m_torrent.name() : m_name; + case TR_PRIORITY: + return m_torrent.queue_position(); + case TR_SIZE: + return m_torrent.has_metadata() ? static_cast(m_torrent.actual_size()) : -1; + case TR_PROGRESS: + return m_torrent.progress(); + case TR_STATUS: + return state(); + case TR_SEEDS: { + return (role == Qt::DisplayRole) ? m_torrent.num_seeds() : m_torrent.num_complete(); + } + case TR_PEERS: { + return (role == Qt::DisplayRole) ? (m_torrent.num_peers()-m_torrent.num_seeds()) : m_torrent.num_incomplete(); + } + case TR_DLSPEED: + return m_torrent.download_payload_rate(); + case TR_UPSPEED: + return m_torrent.upload_payload_rate(); + case TR_ETA: { + // XXX: Is this correct? + if(m_torrent.is_seed() || m_torrent.is_paused() || m_torrent.is_queued()) return MAX_ETA; + return QBtSession::instance()->getETA(m_torrent.hash()); + } + case TR_RATIO: + return QBtSession::instance()->getRealRatio(m_torrent.hash()); + case TR_LABEL: + return m_label; + case TR_ADD_DATE: + return m_addedTime; + case TR_SEED_DATE: + return m_seedTime; + case TR_TRACKER: + return m_torrent.current_tracker(); + case TR_DLLIMIT: + return m_torrent.download_limit(); + case TR_UPLIMIT: + return m_torrent.upload_limit(); + case TR_AMOUNT_DOWNLOADED: + return static_cast(m_torrent.total_wanted_done()); + case TR_AMOUNT_LEFT: + return static_cast(m_torrent.total_wanted() - m_torrent.total_wanted_done()); + case TR_TIME_ELAPSED: + return (role == Qt::DisplayRole) ? m_torrent.active_time() : m_torrent.seeding_time(); + default: + return QVariant(); + } +} + +// TORRENT MODEL + +TorrentModel::TorrentModel(QObject *parent) : + QAbstractListModel(parent), m_refreshInterval(2000) +{ +} + +void TorrentModel::populate() { + // Load the torrents + std::vector torrents = QBtSession::instance()->getSession()->get_torrents(); + std::vector::const_iterator it; + for(it = torrents.begin(); it != torrents.end(); it++) { + addTorrent(QTorrentHandle(*it)); + } + // Refresh timer + connect(&m_refreshTimer, SIGNAL(timeout()), SLOT(forceModelRefresh())); + m_refreshTimer.start(m_refreshInterval); + // Listen for torrent changes + connect(QBtSession::instance(), SIGNAL(addedTorrent(QTorrentHandle)), SLOT(addTorrent(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(torrentAboutToBeRemoved(QTorrentHandle)), SLOT(handleTorrentAboutToBeRemoved(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(deletedTorrent(QString)), SLOT(removeTorrent(QString))); + connect(QBtSession::instance(), SIGNAL(finishedTorrent(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(metadataReceived(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(resumedTorrent(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(pausedTorrent(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); + connect(QBtSession::instance(), SIGNAL(torrentFinishedChecking(QTorrentHandle)), SLOT(handleTorrentUpdate(QTorrentHandle))); +} + +TorrentModel::~TorrentModel() { + qDebug() << Q_FUNC_INFO << "ENTER"; + qDeleteAll(m_torrents); + m_torrents.clear(); + qDebug() << Q_FUNC_INFO << "EXIT"; +} + +QVariant TorrentModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (orientation == Qt::Horizontal) { + if(role == Qt::DisplayRole) { + switch(section) { + case TorrentModelItem::TR_NAME: return tr("Name", "i.e: torrent name"); + case TorrentModelItem::TR_PRIORITY: return "#"; + case TorrentModelItem::TR_SIZE: return tr("Size", "i.e: torrent size"); + case TorrentModelItem::TR_PROGRESS: return tr("Done", "% Done"); + case TorrentModelItem::TR_STATUS: return tr("Status", "Torrent status (e.g. downloading, seeding, paused)"); + case TorrentModelItem::TR_SEEDS: return tr("Seeds", "i.e. full sources (often untranslated)"); + case TorrentModelItem::TR_PEERS: return tr("Peers", "i.e. partial sources (often untranslated)"); + case TorrentModelItem::TR_DLSPEED: return tr("Down Speed", "i.e: Download speed"); + case TorrentModelItem::TR_UPSPEED: return tr("Up Speed", "i.e: Upload speed"); + case TorrentModelItem::TR_RATIO: return tr("Ratio", "Share ratio"); + case TorrentModelItem::TR_ETA: return tr("ETA", "i.e: Estimated Time of Arrival / Time left"); + case TorrentModelItem::TR_LABEL: return tr("Label"); + case TorrentModelItem::TR_ADD_DATE: return tr("Added On", "Torrent was added to transfer list on 01/01/2010 08:00"); + case TorrentModelItem::TR_SEED_DATE: return tr("Completed On", "Torrent was completed on 01/01/2010 08:00"); + case TorrentModelItem::TR_TRACKER: return tr("Tracker"); + case TorrentModelItem::TR_DLLIMIT: return tr("Down Limit", "i.e: Download limit"); + case TorrentModelItem::TR_UPLIMIT: return tr("Up Limit", "i.e: Upload limit"); + case TorrentModelItem::TR_AMOUNT_DOWNLOADED: return tr("Amount downloaded", "Amount of data downloaded (e.g. in MB)"); + case TorrentModelItem::TR_AMOUNT_LEFT: return tr("Amount left", "Amount of data left to download (e.g. in MB)"); + case TorrentModelItem::TR_TIME_ELAPSED: return tr("Time Active", "Time (duration) the torrent is active (not paused)"); + default: + return QVariant(); + } + } + if(role == Qt::TextAlignmentRole) { + switch(section) { + case TorrentModelItem::TR_PRIORITY: + case TorrentModelItem::TR_SIZE: + case TorrentModelItem::TR_SEEDS: + case TorrentModelItem::TR_PEERS: + case TorrentModelItem::TR_DLSPEED: + case TorrentModelItem::TR_UPSPEED: + case TorrentModelItem::TR_RATIO: + case TorrentModelItem::TR_DLLIMIT: + case TorrentModelItem::TR_UPLIMIT: + case TorrentModelItem::TR_AMOUNT_DOWNLOADED: + case TorrentModelItem::TR_AMOUNT_LEFT: + return Qt::AlignRight; + case TorrentModelItem::TR_PROGRESS: + return Qt::AlignHCenter; + default: + return Qt::AlignLeft; + } + } + } + + return QVariant(); +} + +QVariant TorrentModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) return QVariant(); + try { + if(index.row() >= 0 && index.row() < rowCount() && index.column() >= 0 && index.column() < columnCount()) + return m_torrents[index.row()]->data(index.column(), role); + } catch(invalid_handle&) {} + return QVariant(); +} + +bool TorrentModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + qDebug() << Q_FUNC_INFO << value; + if(!index.isValid() || role != Qt::DisplayRole) return false; + qDebug("Index is valid and role is DisplayRole"); + try { + if(index.row() >= 0 && index.row() < rowCount() && index.column() >= 0 && index.column() < columnCount()) { + bool change = m_torrents[index.row()]->setData(index.column(), value, role); + if(change) + notifyTorrentChanged(index.row()); + return change; + } + } catch(invalid_handle&) {} + return false; +} + +int TorrentModel::torrentRow(const QString &hash) const +{ + QList::const_iterator it; + int row = 0; + for(it = m_torrents.constBegin(); it != m_torrents.constEnd(); it++) { + if((*it)->hash() == hash) return row; + ++row; + } + return -1; +} + +void TorrentModel::addTorrent(const QTorrentHandle &h) +{ + if(torrentRow(h.hash()) < 0) { + beginInsertTorrent(m_torrents.size()); + TorrentModelItem *item = new TorrentModelItem(h); + connect(item, SIGNAL(labelChanged(QString,QString)), SLOT(handleTorrentLabelChange(QString,QString))); + m_torrents << item; + emit torrentAdded(item); + endInsertTorrent(); + } +} + +void TorrentModel::removeTorrent(const QString &hash) +{ + const int row = torrentRow(hash); + qDebug() << Q_FUNC_INFO << hash << row; + if(row >= 0) { + beginRemoveTorrent(row); + m_torrents.removeAt(row); + endRemoveTorrent(); + } +} + +void TorrentModel::beginInsertTorrent(int row) +{ + beginInsertRows(QModelIndex(), row, row); +} + +void TorrentModel::endInsertTorrent() +{ + endInsertRows(); +} + +void TorrentModel::beginRemoveTorrent(int row) +{ + beginRemoveRows(QModelIndex(), row, row); +} + +void TorrentModel::endRemoveTorrent() +{ + endRemoveRows(); +} + +void TorrentModel::handleTorrentUpdate(const QTorrentHandle &h) +{ + const int row = torrentRow(h.hash()); + if(row >= 0) { + notifyTorrentChanged(row); + } +} + +void TorrentModel::notifyTorrentChanged(int row) +{ + emit dataChanged(index(row, 0), index(row, columnCount()-1)); +} + +void TorrentModel::setRefreshInterval(int refreshInterval) +{ + if(m_refreshInterval != refreshInterval) { + m_refreshInterval = refreshInterval; + m_refreshTimer.stop(); + m_refreshTimer.start(m_refreshInterval); + } +} + +void TorrentModel::forceModelRefresh() +{ + emit dataChanged(index(0, 0), index(rowCount()-1, columnCount()-1)); +} + +TorrentStatusReport TorrentModel::getTorrentStatusReport() const +{ + TorrentStatusReport report; + QList::const_iterator it; + for(it = m_torrents.constBegin(); it != m_torrents.constEnd(); it++) { + switch((*it)->data(TorrentModelItem::TR_STATUS).toInt()) { + case TorrentModelItem::STATE_DOWNLOADING: + ++report.nb_active; + ++report.nb_downloading; + break; + case TorrentModelItem::STATE_PAUSED_DL: + ++report.nb_paused; + case TorrentModelItem::STATE_STALLED_DL: + case TorrentModelItem::STATE_CHECKING_DL: + case TorrentModelItem::STATE_QUEUED_DL: { + ++report.nb_inactive; + ++report.nb_downloading; + break; + } + case TorrentModelItem::STATE_SEEDING: + ++report.nb_active; + ++report.nb_seeding; + break; + case TorrentModelItem::STATE_PAUSED_UP: + ++report.nb_paused; + case TorrentModelItem::STATE_STALLED_UP: + case TorrentModelItem::STATE_CHECKING_UP: + case TorrentModelItem::STATE_QUEUED_UP: { + ++report.nb_seeding; + ++report.nb_inactive; + break; + } + default: + break; + } + } + return report; +} + +Qt::ItemFlags TorrentModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return 0; + // Explicitely mark as editable + return QAbstractListModel::flags(index) | Qt::ItemIsEditable; +} + +void TorrentModel::handleTorrentLabelChange(QString previous, QString current) +{ + emit torrentChangedLabel(static_cast(sender()), previous, current); +} + +QString TorrentModel::torrentHash(int row) const +{ + if(row >= 0 && row < rowCount()) + return m_torrents.at(row)->hash(); + return QString(); +} + +void TorrentModel::handleTorrentAboutToBeRemoved(const QTorrentHandle &h) +{ + const int row = torrentRow(h.hash()); + if(row >= 0) { + emit torrentAboutToBeRemoved(m_torrents.at(row)); + } +} diff --git a/src/qtlibtorrent/torrentmodel.h b/src/qtlibtorrent/torrentmodel.h new file mode 100644 index 000000000..5cd341c1f --- /dev/null +++ b/src/qtlibtorrent/torrentmodel.h @@ -0,0 +1,124 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TORRENTMODEL_H +#define TORRENTMODEL_H + +#include +#include +#include +#include +#include + +#include "qtorrenthandle.h" + +struct TorrentStatusReport { + TorrentStatusReport(): nb_downloading(0), nb_seeding(0), nb_active(0), nb_inactive(0), nb_paused(0) {} + uint nb_downloading; uint nb_seeding; uint nb_active; uint nb_inactive; uint nb_paused; +}; + +class TorrentModelItem : public QObject { +Q_OBJECT + +public: + enum State {STATE_DOWNLOADING, STATE_STALLED_DL, STATE_STALLED_UP, STATE_SEEDING, STATE_PAUSED_DL, STATE_PAUSED_UP, STATE_QUEUED_DL, STATE_QUEUED_UP, STATE_CHECKING_UP, STATE_CHECKING_DL, STATE_INVALID}; + enum Column {TR_NAME, TR_PRIORITY, TR_SIZE, TR_PROGRESS, TR_STATUS, TR_SEEDS, TR_PEERS, TR_DLSPEED, TR_UPSPEED, TR_ETA, TR_RATIO, TR_LABEL, TR_ADD_DATE, TR_SEED_DATE, TR_TRACKER, TR_DLLIMIT, TR_UPLIMIT, TR_AMOUNT_DOWNLOADED, TR_AMOUNT_LEFT, TR_TIME_ELAPSED, NB_COLUMNS}; + +public: + TorrentModelItem(const QTorrentHandle& h); + inline int columnCount() const { return NB_COLUMNS; } + QVariant data(int column, int role = Qt::DisplayRole) const; + bool setData(int column, const QVariant &value, int role = Qt::DisplayRole); + inline QString hash() const { return m_hash; } + +signals: + void labelChanged(QString previous, QString current); + +private: + State state() const; + +private: + QTorrentHandle m_torrent; + QDateTime m_addedTime; + QDateTime m_seedTime; + QString m_label; + QString m_name; + mutable QIcon m_icon; + mutable QColor m_fgColor; + QString m_hash; // Cached for safety reasons +}; + +class TorrentModel : public QAbstractListModel +{ + Q_OBJECT + Q_DISABLE_COPY(TorrentModel) + +public: + explicit TorrentModel(QObject *parent = 0); + ~TorrentModel(); + inline int rowCount(const QModelIndex& index = QModelIndex()) const { Q_UNUSED(index); return m_torrents.size(); } + int columnCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return TorrentModelItem::NB_COLUMNS; } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole); + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int torrentRow(const QString &hash) const; + QString torrentHash(int row) const; + void setRefreshInterval(int refreshInterval); + TorrentStatusReport getTorrentStatusReport() const; + Qt::ItemFlags flags(const QModelIndex &index) const; + void populate(); + +signals: + void torrentAdded(TorrentModelItem *torrentItem); + void torrentAboutToBeRemoved(TorrentModelItem *torrentItem); + void torrentChangedLabel(TorrentModelItem *torrentItem, QString previous, QString current); + +private slots: + void addTorrent(const QTorrentHandle& h); + void removeTorrent(const QString &hash); + void handleTorrentUpdate(const QTorrentHandle &h); + void notifyTorrentChanged(int row); + void forceModelRefresh(); + void handleTorrentLabelChange(QString previous, QString current); + void handleTorrentAboutToBeRemoved(const QTorrentHandle & h); + +private: + void beginInsertTorrent(int row); + void endInsertTorrent(); + void beginRemoveTorrent(int row); + void endRemoveTorrent(); + +private: + QList m_torrents; + int m_refreshInterval; + QTimer m_refreshTimer; +}; + +#endif // TORRENTMODEL_H diff --git a/src/qtlibtorrent/torrentspeedmonitor.cpp b/src/qtlibtorrent/torrentspeedmonitor.cpp new file mode 100644 index 000000000..eff73d954 --- /dev/null +++ b/src/qtlibtorrent/torrentspeedmonitor.cpp @@ -0,0 +1,138 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include + +#include "qbtsession.h" +#include "misc.h" +#include "torrentspeedmonitor.h" + +using namespace libtorrent; + +class SpeedSample { + +public: + SpeedSample(){} + void addSample(int s); + qreal average() const; + void clear(); + +private: + static const int max_samples = 30; + +private: + QList m_speedSamples; +}; + +TorrentSpeedMonitor::TorrentSpeedMonitor(QBtSession* session) : + QThread(session), m_abort(false), m_session(session) +{ + connect(m_session, SIGNAL(deletedTorrent(QString)), SLOT(removeSamples(QString))); + connect(m_session, SIGNAL(pausedTorrent(QTorrentHandle)), SLOT(removeSamples(QTorrentHandle))); +} + +TorrentSpeedMonitor::~TorrentSpeedMonitor() { + m_abort = true; + m_abortCond.wakeOne(); + wait(); +} + +void TorrentSpeedMonitor::run() +{ + do { + m_mutex.lock(); + getSamples(); + m_abortCond.wait(&m_mutex, 1000); + m_mutex.unlock(); + } while(!m_abort); +} + +void SpeedSample::addSample(int s) +{ + m_speedSamples << s; + if(m_speedSamples.size() > max_samples) + m_speedSamples.removeFirst(); +} + +qreal SpeedSample::average() const +{ + if(m_speedSamples.empty()) return 0; + qlonglong sum = 0; + foreach (int s, m_speedSamples) { + sum += s; + } + return sum/static_cast(m_speedSamples.size()); +} + +void SpeedSample::clear() +{ + m_speedSamples.clear(); +} + +void TorrentSpeedMonitor::removeSamples(const QString &hash) +{ + m_samples.remove(hash); +} + +void TorrentSpeedMonitor::removeSamples(const QTorrentHandle& h) { + try { + m_samples.remove(h.hash()); + } catch(invalid_handle&){} +} + +qlonglong TorrentSpeedMonitor::getETA(const QString &hash) const +{ + QMutexLocker locker(&m_mutex); + QTorrentHandle h = m_session->getTorrentHandle(hash); + if(h.is_paused() || !m_samples.contains(hash)) return -1; + const qreal speed_average = m_samples.value(hash).average(); + if(speed_average == 0) return -1; + return (h.total_wanted() - h.total_done()) / speed_average; +} + +void TorrentSpeedMonitor::getSamples() +{ + const std::vector torrents = m_session->getSession()->get_torrents(); + std::vector::const_iterator it; + for(it = torrents.begin(); it != torrents.end(); it++) { + try { +#if LIBTORRENT_VERSION_MINOR > 15 + torrent_status st = it->status(0x0); + if(!st.paused) + m_samples[misc::toQString(it->info_hash())].addSample(st.download_payload_rate); +#else + if(!it->is_paused()) + m_samples[misc::toQString(it->info_hash())].addSample(it->status().download_payload_rate); +#endif + } catch(invalid_handle&){} + } +} diff --git a/src/qtlibtorrent/torrentspeedmonitor.h b/src/qtlibtorrent/torrentspeedmonitor.h new file mode 100644 index 000000000..4a29ac4e4 --- /dev/null +++ b/src/qtlibtorrent/torrentspeedmonitor.h @@ -0,0 +1,74 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2011 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TORRENTSPEEDMONITOR_H +#define TORRENTSPEEDMONITOR_H + +#include +#include +#include +#include +#include +#include "qtorrenthandle.h" + +class QBtSession; +class SpeedSample; + +class TorrentSpeedMonitor : public QThread +{ + Q_OBJECT + +public: + explicit TorrentSpeedMonitor(QBtSession* session); + ~TorrentSpeedMonitor(); + qlonglong getETA(const QString &hash) const; + +protected: + void run(); + +private: + void getSamples(); + +private slots: + void removeSamples(const QString& hash); + void removeSamples(const QTorrentHandle& h); + +private: + static const int sampling_interval = 1000; // 1s + +private: + bool m_abort; + QWaitCondition m_abortCond; + QHash m_samples; + mutable QMutex m_mutex; + QBtSession *m_session; +}; + +#endif // TORRENTSPEEDMONITOR_H diff --git a/src/qtlibtorrent/trackerinfos.h b/src/qtlibtorrent/trackerinfos.h new file mode 100644 index 000000000..127c80de0 --- /dev/null +++ b/src/qtlibtorrent/trackerinfos.h @@ -0,0 +1,65 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef TRACKERINFOS_H +#define TRACKERINFOS_H + +#include + +class TrackerInfos { +public: + QString name_or_url; + QString last_message; + unsigned long num_peers; +#if LIBTORRENT_VERSION_MINOR < 15 + bool verified; + uint fail_count; +#endif + + //TrackerInfos() {} + TrackerInfos(const TrackerInfos &b) { + name_or_url = b.name_or_url; + Q_ASSERT(!name_or_url.isEmpty()); + last_message = b.last_message; + num_peers = b.num_peers; +#if LIBTORRENT_VERSION_MINOR < 15 + verified = b.verified; + fail_count = b.fail_count; +#endif + } + TrackerInfos(QString name_or_url): name_or_url(name_or_url), last_message(""), num_peers(0) { +#if LIBTORRENT_VERSION_MINOR < 15 + fail_count = 0; + verified = false; +#endif + } +}; + +#endif // TRACKERINFOS_H diff --git a/src/qtnotify/notifications.cpp b/src/qtnotify/notifications.cpp new file mode 100644 index 000000000..57722dd91 --- /dev/null +++ b/src/qtnotify/notifications.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p notifications.h:notifications.cpp notifications.xml + * + * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "notifications.h" + +/* + * Implementation of interface class OrgFreedesktopNotificationsInterface + */ + +OrgFreedesktopNotificationsInterface::OrgFreedesktopNotificationsInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +OrgFreedesktopNotificationsInterface::~OrgFreedesktopNotificationsInterface() +{ +} + diff --git a/src/qtnotify/notifications.h b/src/qtnotify/notifications.h new file mode 100644 index 000000000..fe975fd27 --- /dev/null +++ b/src/qtnotify/notifications.h @@ -0,0 +1,84 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p notifications.h:notifications.cpp notifications.xml + * + * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef NOTIFICATIONS_H_1301681398 +#define NOTIFICATIONS_H_1301681398 + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface org.freedesktop.Notifications + */ +class OrgFreedesktopNotificationsInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.freedesktop.Notifications"; } + +public: + OrgFreedesktopNotificationsInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~OrgFreedesktopNotificationsInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> CloseNotification(uint id) + { + QList argumentList; + argumentList << qVariantFromValue(id); + return asyncCallWithArgumentList(QLatin1String("CloseNotification"), argumentList); + } + + inline QDBusPendingReply GetCapabilities() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("GetCapabilities"), argumentList); + } + + inline QDBusPendingReply GetServerInformation() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("GetServerInformation"), argumentList); + } + inline QDBusReply GetServerInformation(QString &return_vendor, QString &return_version, QString &return_spec_version) + { + QList argumentList; + QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("GetServerInformation"), argumentList); + if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 4) { + return_vendor = qdbus_cast(reply.arguments().at(1)); + return_version = qdbus_cast(reply.arguments().at(2)); + return_spec_version = qdbus_cast(reply.arguments().at(3)); + } + return reply; + } + + inline QDBusPendingReply Notify(const QString &app_name, uint id, const QString &icon, const QString &summary, const QString &body, const QStringList &actions, const QVariantMap &hints, int timeout) + { + QList argumentList; + argumentList << qVariantFromValue(app_name) << qVariantFromValue(id) << qVariantFromValue(icon) << qVariantFromValue(summary) << qVariantFromValue(body) << qVariantFromValue(actions) << qVariantFromValue(hints) << qVariantFromValue(timeout); + return asyncCallWithArgumentList(QLatin1String("Notify"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace org { + namespace freedesktop { + typedef ::OrgFreedesktopNotificationsInterface Notifications; + } +} +#endif diff --git a/src/qtnotify/notifications.xml b/src/qtnotify/notifications.xml new file mode 100644 index 000000000..7c1d2e7ad --- /dev/null +++ b/src/qtnotify/notifications.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qtnotify/qtnotify.pri b/src/qtnotify/qtnotify.pri new file mode 100644 index 000000000..84d288a4a --- /dev/null +++ b/src/qtnotify/qtnotify.pri @@ -0,0 +1,5 @@ +INCLUDEPATH += $$PWD + +HEADERS += $$PWD/notifications.h + +SOURCES += $$PWD/notifications.cpp diff --git a/src/qtsingleapp/QtLockedFile b/src/qtsingleapp/QtLockedFile new file mode 100644 index 000000000..16b48ba9d --- /dev/null +++ b/src/qtsingleapp/QtLockedFile @@ -0,0 +1 @@ +#include "qtlockedfile.h" diff --git a/src/qtsingleapp/QtSingleApplication b/src/qtsingleapp/QtSingleApplication new file mode 100644 index 000000000..d111bf72d --- /dev/null +++ b/src/qtsingleapp/QtSingleApplication @@ -0,0 +1 @@ +#include "qtsingleapplication.h" diff --git a/src/qtsingleapp/qtlocalpeer.cpp b/src/qtsingleapp/qtlocalpeer.cpp new file mode 100644 index 000000000..b329e9147 --- /dev/null +++ b/src/qtsingleapp/qtlocalpeer.cpp @@ -0,0 +1,208 @@ +/**************************************************************************** +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact Nokia at qt-info@nokia.com. +** +****************************************************************************/ + + +#include "qtlocalpeer.h" +#include +#include + +#if defined(Q_OS_WIN) +#include +#include +typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*); +static PProcessIdToSessionId pProcessIdToSessionId = 0; +#endif +#if defined(Q_OS_UNIX) +#include +#endif +#if defined(Q_OS_OS2) +#include +#endif + +#include + +namespace QtLP_Private { +#include "qtlockedfile.cpp" +#if defined(Q_OS_WIN) +#include "qtlockedfile_win.cpp" +#else +#include "qtlockedfile_unix.cpp" +#endif +} + +const char* QtLocalPeer::ack = "ack"; + +QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId) + : QObject(parent), id(appId) +{ + QString prefix = id; + if (id.isEmpty()) { + id = QCoreApplication::applicationFilePath(); +#if defined(Q_OS_WIN) + id = id.toLower(); +#endif + prefix = id.section(QLatin1Char('/'), -1); + } + prefix.remove(QRegExp("[^a-zA-Z]")); + prefix.truncate(6); + + QByteArray idc = id.toUtf8(); + quint16 idNum = qChecksum(idc.constData(), idc.size()); + socketName = QLatin1String("qtsingleapp-") + prefix + + QLatin1Char('-') + QString::number(idNum, 16); + +#if defined(Q_OS_WIN) + if (!pProcessIdToSessionId) { + QLibrary lib("kernel32"); + pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); + } + if (pProcessIdToSessionId) { + DWORD sessionId = 0; + pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); + socketName += QLatin1Char('-') + QString::number(sessionId, 16); + } +#else + socketName += QLatin1Char('-') + QString::number(::getuid(), 16); +#endif + + server = new QLocalServer(this); + QString lockName = QDir(QDir::tempPath()).absolutePath() + + QLatin1Char('/') + socketName + + QLatin1String("-lockfile"); + lockFile.setFileName(lockName); + lockFile.open(QIODevice::ReadWrite); +} + + + +bool QtLocalPeer::isClient() +{ + if (lockFile.isLocked()) + return false; + + if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) + return true; + + bool res = server->listen(socketName); +#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) + // ### Workaround + if (!res && server->serverError() == QAbstractSocket::AddressInUseError) { + QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName); + res = server->listen(socketName); + } +#endif + if (!res) + qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); + QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection())); + return false; +} + + +bool QtLocalPeer::sendMessage(const QString &message, int timeout) +{ + if (!isClient()) + return false; + + QLocalSocket socket; + bool connOk = false; + for(int i = 0; i < 2; i++) { + // Try twice, in case the other instance is just starting up + socket.connectToServer(socketName); + connOk = socket.waitForConnected(timeout/2); + if (connOk || i) + break; + int ms = 250; +#if defined(Q_OS_WIN) + Sleep(DWORD(ms)); +#else + struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; + nanosleep(&ts, NULL); +#endif + } + if (!connOk) + return false; + + QByteArray uMsg(message.toUtf8()); + QDataStream ds(&socket); + ds.writeBytes(uMsg.constData(), uMsg.size()); + bool res = socket.waitForBytesWritten(timeout); + res &= socket.waitForReadyRead(timeout); // wait for ack + res &= (socket.read(qstrlen(ack)) == ack); + return res; +} + + +void QtLocalPeer::receiveConnection() +{ + QLocalSocket* socket = server->nextPendingConnection(); + if (!socket) + return; + + while (socket->bytesAvailable() < (int)sizeof(quint32)) + socket->waitForReadyRead(); + QDataStream ds(socket); + QByteArray uMsg; + quint32 remaining; + ds >> remaining; + uMsg.resize(remaining); + int got = 0; + char* uMsgBuf = uMsg.data(); + do { + got = ds.readRawData(uMsgBuf, remaining); + remaining -= got; + uMsgBuf += got; + } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); + if (got < 0) { + qWarning() << "QtLocalPeer: Message reception failed" << socket->errorString(); + delete socket; + return; + } + QString message(QString::fromUtf8(uMsg)); + socket->write(ack, qstrlen(ack)); + socket->waitForBytesWritten(1000); + delete socket; + emit messageReceived(message); //### (might take a long time to return) +} diff --git a/src/qtsingleapp/qtlocalpeer.h b/src/qtsingleapp/qtlocalpeer.h new file mode 100644 index 000000000..b81dbd11a --- /dev/null +++ b/src/qtsingleapp/qtlocalpeer.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact Nokia at qt-info@nokia.com. +** +****************************************************************************/ + + +#include +#include +#include +#include + +namespace QtLP_Private { +#include "qtlockedfile.h" +} + +class QtLocalPeer : public QObject +{ + Q_OBJECT + +public: + QtLocalPeer(QObject *parent = 0, const QString &appId = QString()); + bool isClient(); + bool sendMessage(const QString &message, int timeout); + QString applicationId() const + { return id; } + +Q_SIGNALS: + void messageReceived(const QString &message); + +protected Q_SLOTS: + void receiveConnection(); + +protected: + QString id; + QString socketName; + QLocalServer* server; + QtLP_Private::QtLockedFile lockFile; + +private: + static const char* ack; +}; diff --git a/src/qtsingleapp/qtlockedfile.cpp b/src/qtsingleapp/qtlockedfile.cpp new file mode 100644 index 000000000..2cf080584 --- /dev/null +++ b/src/qtsingleapp/qtlockedfile.cpp @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#include "qtlockedfile.h" + +/*! + \class QtLockedFile + + \brief The QtLockedFile class extends QFile with advisory locking + functions. + + A file may be locked in read or write mode. Multiple instances of + \e QtLockedFile, created in multiple processes running on the same + machine, may have a file locked in read mode. Exactly one instance + may have it locked in write mode. A read and a write lock cannot + exist simultaneously on the same file. + + The file locks are advisory. This means that nothing prevents + another process from manipulating a locked file using QFile or + file system functions offered by the OS. Serialization is only + guaranteed if all processes that access the file use + QLockedFile. Also, while holding a lock on a file, a process + must not open the same file again (through any API), or locks + can be unexpectedly lost. + + The lock provided by an instance of \e QtLockedFile is released + whenever the program terminates. This is true even when the + program crashes and no destructors are called. +*/ + +/*! \enum QtLockedFile::LockMode + + This enum describes the available lock modes. + + \value ReadLock A read lock. + \value WriteLock A write lock. + \value NoLock Neither a read lock nor a write lock. +*/ + +/*! + Constructs an unlocked \e QtLockedFile object. This constructor + behaves in the same way as \e QFile::QFile(). + + \sa QFile::QFile() +*/ +QtLockedFile::QtLockedFile() + : QFile() +{ +#ifdef Q_OS_WIN + wmutex = 0; + rmutex = 0; +#endif + m_lock_mode = NoLock; +} + +/*! + Constructs an unlocked QtLockedFile object with file \a name. This + constructor behaves in the same way as \e QFile::QFile(const + QString&). + + \sa QFile::QFile() +*/ +QtLockedFile::QtLockedFile(const QString &name) + : QFile(name) +{ +#ifdef Q_OS_WIN + wmutex = 0; + rmutex = 0; +#endif + m_lock_mode = NoLock; +} + +/*! + Opens the file in OpenMode \a mode. + + This is identical to QFile::open(), with the one exception that the + Truncate mode flag is disallowed. Truncation would conflict with the + advisory file locking, since the file would be modified before the + write lock is obtained. If truncation is required, use resize(0) + after obtaining the write lock. + + Returns true if successful; otherwise false. + + \sa QFile::open(), QFile::resize() +*/ +bool QtLockedFile::open(OpenMode mode) +{ + if (mode & QIODevice::Truncate) { + qWarning("QtLockedFile::open(): Truncate mode not allowed."); + return false; + } + return QFile::open(mode); +} + +/*! + Returns \e true if this object has a in read or write lock; + otherwise returns \e false. + + \sa lockMode() +*/ +bool QtLockedFile::isLocked() const +{ + return m_lock_mode != NoLock; +} + +/*! + Returns the type of lock currently held by this object, or \e + QtLockedFile::NoLock. + + \sa isLocked() +*/ +QtLockedFile::LockMode QtLockedFile::lockMode() const +{ + return m_lock_mode; +} + +/*! + \fn bool QtLockedFile::lock(LockMode mode, bool block = true) + + Obtains a lock of type \a mode. The file must be opened before it + can be locked. + + If \a block is true, this function will block until the lock is + aquired. If \a block is false, this function returns \e false + immediately if the lock cannot be aquired. + + If this object already has a lock of type \a mode, this function + returns \e true immediately. If this object has a lock of a + different type than \a mode, the lock is first released and then a + new lock is obtained. + + This function returns \e true if, after it executes, the file is + locked by this object, and \e false otherwise. + + \sa unlock(), isLocked(), lockMode() +*/ + +/*! + \fn bool QtLockedFile::unlock() + + Releases a lock. + + If the object has no lock, this function returns immediately. + + This function returns \e true if, after it executes, the file is + not locked by this object, and \e false otherwise. + + \sa lock(), isLocked(), lockMode() +*/ + +/*! + \fn QtLockedFile::~QtLockedFile() + + Destroys the \e QtLockedFile object. If any locks were held, they + are released. +*/ diff --git a/src/qtsingleapp/qtlockedfile.h b/src/qtsingleapp/qtlockedfile.h new file mode 100644 index 000000000..1d3b918ec --- /dev/null +++ b/src/qtsingleapp/qtlockedfile.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#ifndef QTLOCKEDFILE_H +#define QTLOCKEDFILE_H + +#include +#ifdef Q_OS_WIN +#include +#endif + +#if defined(Q_WS_WIN) +# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) +# define QT_QTLOCKEDFILE_EXPORT +# elif defined(QT_QTLOCKEDFILE_IMPORT) +# if defined(QT_QTLOCKEDFILE_EXPORT) +# undef QT_QTLOCKEDFILE_EXPORT +# endif +# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport) +# elif defined(QT_QTLOCKEDFILE_EXPORT) +# undef QT_QTLOCKEDFILE_EXPORT +# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport) +# endif +#else +# define QT_QTLOCKEDFILE_EXPORT +#endif + +class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile +{ +public: + enum LockMode { NoLock = 0, ReadLock, WriteLock }; + + QtLockedFile(); + QtLockedFile(const QString &name); + ~QtLockedFile(); + + bool open(OpenMode mode); + + bool lock(LockMode mode, bool block = true); + bool unlock(); + bool isLocked() const; + LockMode lockMode() const; + +private: +#ifdef Q_OS_WIN + Qt::HANDLE wmutex; + Qt::HANDLE rmutex; + QVector rmutexes; + QString mutexname; + + Qt::HANDLE getMutexHandle(int idx, bool doCreate); + bool waitMutex(Qt::HANDLE mutex, bool doBlock); + +#endif + LockMode m_lock_mode; +}; + +#endif diff --git a/src/qtsingleapp/qtlockedfile_unix.cpp b/src/qtsingleapp/qtlockedfile_unix.cpp new file mode 100644 index 000000000..2881bdd2c --- /dev/null +++ b/src/qtsingleapp/qtlockedfile_unix.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#include +#include +#include +#include + +#include "qtlockedfile.h" + +bool QtLockedFile::lock(LockMode mode, bool block) +{ + if (!isOpen()) { + qWarning("QtLockedFile::lock(): file is not opened"); + return false; + } + + if (mode == NoLock) + return unlock(); + + if (mode == m_lock_mode) + return true; + + if (m_lock_mode != NoLock) + unlock(); + + struct flock fl; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; + int cmd = block ? F_SETLKW : F_SETLK; + int ret = fcntl(handle(), cmd, &fl); + + if (ret == -1) { + if (errno != EINTR && errno != EAGAIN) + qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); + return false; + } + + + m_lock_mode = mode; + return true; +} + + +bool QtLockedFile::unlock() +{ + if (!isOpen()) { + qWarning("QtLockedFile::unlock(): file is not opened"); + return false; + } + + if (!isLocked()) + return true; + + struct flock fl; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_type = F_UNLCK; + int ret = fcntl(handle(), F_SETLKW, &fl); + + if (ret == -1) { + qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); + return false; + } + + m_lock_mode = NoLock; + return true; +} + +QtLockedFile::~QtLockedFile() +{ + if (isOpen()) + unlock(); +} + diff --git a/src/qtsingleapp/qtlockedfile_win.cpp b/src/qtsingleapp/qtlockedfile_win.cpp new file mode 100644 index 000000000..d4bf9e141 --- /dev/null +++ b/src/qtsingleapp/qtlockedfile_win.cpp @@ -0,0 +1,213 @@ +/**************************************************************************** +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#include "qtlockedfile.h" +#include +#include + +#define MUTEX_PREFIX "QtLockedFile mutex " +// Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS +#define MAX_READERS MAXIMUM_WAIT_OBJECTS + +Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) +{ + if (mutexname.isEmpty()) { + QFileInfo fi(*this); + mutexname = QString::fromLatin1(MUTEX_PREFIX) + + fi.absoluteFilePath().toLower(); + } + QString mname(mutexname); + if (idx >= 0) + mname += QString::number(idx); + + Qt::HANDLE mutex; + if (doCreate) { + QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); }, + { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } ); + if (!mutex) { + qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); + return 0; + } + } + else { + QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); }, + { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } ); + if (!mutex) { + if (GetLastError() != ERROR_FILE_NOT_FOUND) + qErrnoWarning("QtLockedFile::lock(): OpenMutex failed"); + return 0; + } + } + return mutex; +} + +bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock) +{ + Q_ASSERT(mutex); + DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0); + switch (res) { + case WAIT_OBJECT_0: + case WAIT_ABANDONED: + return true; + break; + case WAIT_TIMEOUT: + break; + default: + qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed"); + } + return false; +} + + + +bool QtLockedFile::lock(LockMode mode, bool block) +{ + if (!isOpen()) { + qWarning("QtLockedFile::lock(): file is not opened"); + return false; + } + + if (mode == NoLock) + return unlock(); + + if (mode == m_lock_mode) + return true; + + if (m_lock_mode != NoLock) + unlock(); + + if (!wmutex && !(wmutex = getMutexHandle(-1, true))) + return false; + + if (!waitMutex(wmutex, block)) + return false; + + if (mode == ReadLock) { + int idx = 0; + for (; idx < MAX_READERS; idx++) { + rmutex = getMutexHandle(idx, false); + if (!rmutex || waitMutex(rmutex, false)) + break; + CloseHandle(rmutex); + } + bool ok = true; + if (idx >= MAX_READERS) { + qWarning("QtLockedFile::lock(): too many readers"); + rmutex = 0; + ok = false; + } + else if (!rmutex) { + rmutex = getMutexHandle(idx, true); + if (!rmutex || !waitMutex(rmutex, false)) + ok = false; + } + if (!ok && rmutex) { + CloseHandle(rmutex); + rmutex = 0; + } + ReleaseMutex(wmutex); + if (!ok) + return false; + } + else { + Q_ASSERT(rmutexes.isEmpty()); + for (int i = 0; i < MAX_READERS; i++) { + Qt::HANDLE mutex = getMutexHandle(i, false); + if (mutex) + rmutexes.append(mutex); + } + if (rmutexes.size()) { + DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), + TRUE, block ? INFINITE : 0); + if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) { + if (res != WAIT_TIMEOUT) + qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed"); + m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky + unlock(); + return false; + } + } + } + + m_lock_mode = mode; + return true; +} + +bool QtLockedFile::unlock() +{ + if (!isOpen()) { + qWarning("QtLockedFile::unlock(): file is not opened"); + return false; + } + + if (!isLocked()) + return true; + + if (m_lock_mode == ReadLock) { + ReleaseMutex(rmutex); + CloseHandle(rmutex); + rmutex = 0; + } + else { + foreach(Qt::HANDLE mutex, rmutexes) { + ReleaseMutex(mutex); + CloseHandle(mutex); + } + rmutexes.clear(); + ReleaseMutex(wmutex); + } + + m_lock_mode = QtLockedFile::NoLock; + return true; +} + +QtLockedFile::~QtLockedFile() +{ + if (isOpen()) + unlock(); + if (wmutex) + CloseHandle(wmutex); +} diff --git a/src/qtsingleapp/qtsingleapplication.cpp b/src/qtsingleapp/qtsingleapplication.cpp new file mode 100644 index 000000000..a3a1fd7fd --- /dev/null +++ b/src/qtsingleapp/qtsingleapplication.cpp @@ -0,0 +1,351 @@ +/**************************************************************************** +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact Nokia at qt-info@nokia.com. +** +****************************************************************************/ + + +#include "qtsingleapplication.h" +#include "qtlocalpeer.h" +#include + + +/*! + \class QtSingleApplication qtsingleapplication.h + \brief The QtSingleApplication class provides an API to detect and + communicate with running instances of an application. + + This class allows you to create applications where only one + instance should be running at a time. I.e., if the user tries to + launch another instance, the already running instance will be + activated instead. Another usecase is a client-server system, + where the first started instance will assume the role of server, + and the later instances will act as clients of that server. + + By default, the full path of the executable file is used to + determine whether two processes are instances of the same + application. You can also provide an explicit identifier string + that will be compared instead. + + The application should create the QtSingleApplication object early + in the startup phase, and call isRunning() or sendMessage() to + find out if another instance of this application is already + running. Startup parameters (e.g. the name of the file the user + wanted this new instance to open) can be passed to the running + instance in the sendMessage() function. + + If isRunning() or sendMessage() returns false, it means that no + other instance is running, and this instance has assumed the role + as the running instance. The application should continue with the + initialization of the application user interface before entering + the event loop with exec(), as normal. The messageReceived() + signal will be emitted when the application receives messages from + another instance of the same application. + + If isRunning() or sendMessage() returns true, another instance is + already running, and the application should terminate or enter + client mode. + + If a message is received it might be helpful to the user to raise + the application so that it becomes visible. To facilitate this, + QtSingleApplication provides the setActivationWindow() function + and the activateWindow() slot. + + Here's an example that shows how to convert an existing + application to use QtSingleApplication. It is very simple and does + not make use of all QtSingleApplication's functionality (see the + examples for that). + + \code + // Original + int main(int argc, char **argv) + { + QApplication app(argc, argv); + + MyMainWidget mmw; + + mmw.show(); + return app.exec(); + } + + // Single instance + int main(int argc, char **argv) + { + QtSingleApplication app(argc, argv); + + if (app.isRunning()) + return 0; + + MyMainWidget mmw; + + app.setActivationWindow(&mmw); + + mmw.show(); + return app.exec(); + } + \endcode + + Once this QtSingleApplication instance is destroyed(for example, + when the user quits), when the user next attempts to run the + application this instance will not, of course, be encountered. The + next instance to call isRunning() or sendMessage() will assume the + role as the new running instance. + + For console (non-GUI) applications, QtSingleCoreApplication may be + used instead of this class, to avoid the dependency on the QtGui + library. + + \sa QtSingleCoreApplication +*/ + + +void QtSingleApplication::sysInit(const QString &appId) +{ + actWin = 0; + peer = new QtLocalPeer(this, appId); + connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); +} + + +/*! + Creates a QtSingleApplication object. The application identifier + will be QCoreApplication::applicationFilePath(). \a argc, \a + argv, and \a GUIenabled are passed on to the QAppliation constructor. + + If you are creating a console application (i.e. setting \a + GUIenabled to false), you may consider using + QtSingleCoreApplication instead. +*/ + +QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled) + : QApplication(argc, argv, GUIenabled) +{ + sysInit(); +} + + +/*! + Creates a QtSingleApplication object with the application + identifier \a appId. \a argc and \a argv are passed on to the + QAppliation constructor. +*/ + +QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv) + : QApplication(argc, argv) +{ + sysInit(appId); +} + + +/*! + Creates a QtSingleApplication object. The application identifier + will be QCoreApplication::applicationFilePath(). \a argc, \a + argv, and \a type are passed on to the QAppliation constructor. +*/ +QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type) + : QApplication(argc, argv, type) +{ + sysInit(); +} + + +#if defined(Q_WS_X11) +/*! + Special constructor for X11, ref. the documentation of + QApplication's corresponding constructor. The application identifier + will be QCoreApplication::applicationFilePath(). \a dpy, \a visual, + and \a cmap are passed on to the QApplication constructor. +*/ +QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap) + : QApplication(dpy, visual, cmap) +{ + sysInit(); +} + +/*! + Special constructor for X11, ref. the documentation of + QApplication's corresponding constructor. The application identifier + will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a + argv, \a visual, and \a cmap are passed on to the QApplication + constructor. +*/ +QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) + : QApplication(dpy, argc, argv, visual, cmap) +{ + sysInit(); +} + +/*! + Special constructor for X11, ref. the documentation of + QApplication's corresponding constructor. The application identifier + will be \a appId. \a dpy, \a argc, \a + argv, \a visual, and \a cmap are passed on to the QApplication + constructor. +*/ +QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) + : QApplication(dpy, argc, argv, visual, cmap) +{ + sysInit(appId); +} +#endif + + +/*! + Returns true if another instance of this application is running; + otherwise false. + + This function does not find instances of this application that are + being run by a different user (on Windows: that are running in + another session). + + \sa sendMessage() +*/ + +bool QtSingleApplication::isRunning() +{ + return peer->isClient(); +} + + +/*! + Tries to send the text \a message to the currently running + instance. The QtSingleApplication object in the running instance + will emit the messageReceived() signal when it receives the + message. + + This function returns true if the message has been sent to, and + processed by, the current instance. If there is no instance + currently running, or if the running instance fails to process the + message within \a timeout milliseconds, this function return false. + + \sa isRunning(), messageReceived() +*/ +bool QtSingleApplication::sendMessage(const QString &message, int timeout) +{ + return peer->sendMessage(message, timeout); +} + + +/*! + Returns the application identifier. Two processes with the same + identifier will be regarded as instances of the same application. +*/ +QString QtSingleApplication::id() const +{ + return peer->applicationId(); +} + + +/*! + Sets the activation window of this application to \a aw. The + activation window is the widget that will be activated by + activateWindow(). This is typically the application's main window. + + If \a activateOnMessage is true (the default), the window will be + activated automatically every time a message is received, just prior + to the messageReceived() signal being emitted. + + \sa activateWindow(), messageReceived() +*/ + +void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage) +{ + actWin = aw; + if (activateOnMessage) + connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); + else + disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); +} + + +/*! + Returns the applications activation window if one has been set by + calling setActivationWindow(), otherwise returns 0. + + \sa setActivationWindow() +*/ +QWidget* QtSingleApplication::activationWindow() const +{ + return actWin; +} + + +/*! + De-minimizes, raises, and activates this application's activation window. + This function does nothing if no activation window has been set. + + This is a convenience function to show the user that this + application instance has been activated when he has tried to start + another instance. + + This function should typically be called in response to the + messageReceived() signal. By default, that will happen + automatically, if an activation window has been set. + + \sa setActivationWindow(), messageReceived(), initialize() +*/ +void QtSingleApplication::activateWindow() +{ + if (actWin) { + actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); + actWin->raise(); + actWin->activateWindow(); + } +} + + +/*! + \fn void QtSingleApplication::messageReceived(const QString& message) + + This signal is emitted when the current instance receives a \a + message from another instance of this application. + + \sa sendMessage(), setActivationWindow(), activateWindow() +*/ + + +/*! + \fn void QtSingleApplication::initialize(bool dummy = true) + + \obsolete +*/ diff --git a/src/qtsingleapp/qtsingleapplication.h b/src/qtsingleapp/qtsingleapplication.h new file mode 100644 index 000000000..5df916561 --- /dev/null +++ b/src/qtsingleapp/qtsingleapplication.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact Nokia at qt-info@nokia.com. +** +****************************************************************************/ + + +#include + +class QtLocalPeer; + +#if defined(Q_WS_WIN) +# if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT) +# define QT_QTSINGLEAPPLICATION_EXPORT +# elif defined(QT_QTSINGLEAPPLICATION_IMPORT) +# if defined(QT_QTSINGLEAPPLICATION_EXPORT) +# undef QT_QTSINGLEAPPLICATION_EXPORT +# endif +# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport) +# elif defined(QT_QTSINGLEAPPLICATION_EXPORT) +# undef QT_QTSINGLEAPPLICATION_EXPORT +# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport) +# endif +#else +# define QT_QTSINGLEAPPLICATION_EXPORT +#endif + +class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication +{ + Q_OBJECT + +public: + QtSingleApplication(int &argc, char **argv, bool GUIenabled = true); + QtSingleApplication(const QString &id, int &argc, char **argv); + QtSingleApplication(int &argc, char **argv, Type type); +#if defined(Q_WS_X11) + QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); + QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0); + QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); +#endif + + bool isRunning(); + QString id() const; + + void setActivationWindow(QWidget* aw, bool activateOnMessage = true); + QWidget* activationWindow() const; + + // Obsolete: + void initialize(bool dummy = true) + { isRunning(); Q_UNUSED(dummy) } + +public Q_SLOTS: + bool sendMessage(const QString &message, int timeout = 5000); + void activateWindow(); + + +Q_SIGNALS: + void messageReceived(const QString &message); + + +private: + void sysInit(const QString &appId = QString()); + QtLocalPeer *peer; + QWidget *actWin; +}; diff --git a/src/qtsingleapp/qtsingleapplication.pri b/src/qtsingleapp/qtsingleapplication.pri new file mode 100644 index 000000000..b8a7347e7 --- /dev/null +++ b/src/qtsingleapp/qtsingleapplication.pri @@ -0,0 +1,16 @@ +#include(../common.pri) +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD +QT *= network + +qtsingleapplication-uselib:!qtsingleapplication-buildlib { + LIBS += -L$$QTSINGLEAPPLICATION_LIBDIR -l$$QTSINGLEAPPLICATION_LIBNAME +} else { + SOURCES += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp + HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h +} + +win32 { + contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT + else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT +} diff --git a/src/qtsingleapp/qtsinglecoreapplication.cpp b/src/qtsingleapp/qtsinglecoreapplication.cpp new file mode 100644 index 000000000..307e25560 --- /dev/null +++ b/src/qtsingleapp/qtsinglecoreapplication.cpp @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact Nokia at qt-info@nokia.com. +** +****************************************************************************/ + + +#include "qtsinglecoreapplication.h" +#include "qtlocalpeer.h" + +/*! + \class QtSingleCoreApplication qtsinglecoreapplication.h + \brief A variant of the QtSingleApplication class for non-GUI applications. + + This class is a variant of QtSingleApplication suited for use in + console (non-GUI) applications. It is an extension of + QCoreApplication (instead of QApplication). It does not require + the QtGui library. + + The API and usage is identical to QtSingleApplication, except that + functions relating to the "activation window" are not present, for + obvious reasons. Please refer to the QtSingleApplication + documentation for explanation of the usage. + + A QtSingleCoreApplication instance can communicate to a + QtSingleApplication instance if they share the same application + id. Hence, this class can be used to create a light-weight + command-line tool that sends commands to a GUI application. + + \sa QtSingleApplication +*/ + +/*! + Creates a QtSingleCoreApplication object. The application identifier + will be QCoreApplication::applicationFilePath(). \a argc and \a + argv are passed on to the QCoreAppliation constructor. +*/ + +QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv) + : QCoreApplication(argc, argv) +{ + peer = new QtLocalPeer(this); + connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); +} + + +/*! + Creates a QtSingleCoreApplication object with the application + identifier \a appId. \a argc and \a argv are passed on to the + QCoreAppliation constructor. +*/ +QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv) + : QCoreApplication(argc, argv) +{ + peer = new QtLocalPeer(this, appId); + connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); +} + + +/*! + Returns true if another instance of this application is running; + otherwise false. + + This function does not find instances of this application that are + being run by a different user (on Windows: that are running in + another session). + + \sa sendMessage() +*/ + +bool QtSingleCoreApplication::isRunning() +{ + return peer->isClient(); +} + + +/*! + Tries to send the text \a message to the currently running + instance. The QtSingleCoreApplication object in the running instance + will emit the messageReceived() signal when it receives the + message. + + This function returns true if the message has been sent to, and + processed by, the current instance. If there is no instance + currently running, or if the running instance fails to process the + message within \a timeout milliseconds, this function return false. + + \sa isRunning(), messageReceived() +*/ + +bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout) +{ + return peer->sendMessage(message, timeout); +} + + +/*! + Returns the application identifier. Two processes with the same + identifier will be regarded as instances of the same application. +*/ + +QString QtSingleCoreApplication::id() const +{ + return peer->applicationId(); +} + + +/*! + \fn void QtSingleCoreApplication::messageReceived(const QString& message) + + This signal is emitted when the current instance receives a \a + message from another instance of this application. + + \sa sendMessage() +*/ diff --git a/src/qtsingleapp/qtsinglecoreapplication.h b/src/qtsingleapp/qtsinglecoreapplication.h new file mode 100644 index 000000000..8e2fda696 --- /dev/null +++ b/src/qtsingleapp/qtsinglecoreapplication.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of a Qt Solutions component. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Solutions Commercial License Agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** Please note Third Party Software included with Qt Solutions may impose +** additional restrictions and it is the user's responsibility to ensure +** that they have met the licensing requirements of the GPL, LGPL, or Qt +** Solutions Commercial license and the relevant license of the Third +** Party Software they are using. +** +** If you are unsure which license is appropriate for your use, please +** contact Nokia at qt-info@nokia.com. +** +****************************************************************************/ + + +#include + +class QtLocalPeer; + +class QtSingleCoreApplication : public QCoreApplication +{ + Q_OBJECT + +public: + QtSingleCoreApplication(int &argc, char **argv); + QtSingleCoreApplication(const QString &id, int &argc, char **argv); + + bool isRunning(); + QString id() const; + +public Q_SLOTS: + bool sendMessage(const QString &message, int timeout = 5000); + + +Q_SIGNALS: + void messageReceived(const QString &message); + + +private: + QtLocalPeer* peer; +}; diff --git a/src/qtsingleapp/qtsinglecoreapplication.pri b/src/qtsingleapp/qtsinglecoreapplication.pri new file mode 100644 index 000000000..d2d6cc3e1 --- /dev/null +++ b/src/qtsingleapp/qtsinglecoreapplication.pri @@ -0,0 +1,10 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD +HEADERS += $$PWD/qtsinglecoreapplication.h $$PWD/qtlocalpeer.h +SOURCES += $$PWD/qtsinglecoreapplication.cpp $$PWD/qtlocalpeer.cpp + +QT *= network + +win32:contains(TEMPLATE, lib):contains(CONFIG, shared) { + DEFINES += QT_QTSINGLECOREAPPLICATION_EXPORT=__declspec(dllexport) +} diff --git a/src/reverseresolution.h b/src/reverseresolution.h new file mode 100644 index 000000000..8c4377383 --- /dev/null +++ b/src/reverseresolution.h @@ -0,0 +1,111 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#ifndef REVERSERESOLUTION_H +#define REVERSERESOLUTION_H + +#include +#include +#include +#include +#include "misc.h" + +#include +#if BOOST_VERSION < 103500 +#include +#else +#include +#endif + +const int CACHE_SIZE = 500; + +class ReverseResolution: public QObject { + Q_OBJECT + Q_DISABLE_COPY(ReverseResolution) + +public: + explicit ReverseResolution(QObject* parent): QObject(parent) { + m_cache.setMaxCost(CACHE_SIZE); + } + + ~ReverseResolution() { + qDebug("Deleting host name resolver..."); + } + + QString getHostFromCache(const libtorrent::asio::ip::tcp::endpoint &ip) { + boost::system::error_code ec; + const QString ip_str = misc::toQString(ip.address().to_string(ec)); + if (ec) return QString(); + QString ret; + if(m_cache.contains(ip_str)) { + qDebug("Got host name from cache"); + ret = *m_cache.object(ip_str); + } else { + ret = QString::null; + } + return ret; + } + + void resolve(const libtorrent::asio::ip::tcp::endpoint &ip) { + boost::system::error_code ec; + const QString ip_str = misc::toQString(ip.address().to_string(ec)); + if (ec) return; + if(m_cache.contains(ip_str)) { + qDebug("Resolved host name using cache"); + emit ip_resolved(ip_str, *m_cache.object(ip_str)); + return; + } + // Actually resolve the ip + QHostInfo::lookupHost(ip_str, this, SLOT(hostResolved(QHostInfo))); + } + +signals: + void ip_resolved(const QString &ip, const QString &hostname); + +private slots: + void hostResolved(const QHostInfo& host) { + if (host.error() == QHostInfo::NoError) { + const QString hostname = host.hostName(); + if(host.addresses().isEmpty() || hostname.isEmpty()) return; + const QString ip = host.addresses().first().toString(); + if(hostname != ip) { + //qDebug() << Q_FUNC_INFO << ip << QString("->") << hostname; + m_cache.insert(ip, new QString(hostname)); + emit ip_resolved(ip, hostname); + } + } + } + +private: + QCache m_cache; +}; + + +#endif // REVERSERESOLUTION_H diff --git a/src/rss/automatedrssdownloader.cpp b/src/rss/automatedrssdownloader.cpp new file mode 100644 index 000000000..954e0d16d --- /dev/null +++ b/src/rss/automatedrssdownloader.cpp @@ -0,0 +1,582 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org + */ + +#include +#include +#include +#include +#include +#include + +#include "automatedrssdownloader.h" +#include "ui_automatedrssdownloader.h" +#include "rsssettings.h" +#include "rssdownloadrulelist.h" +#include "preferences.h" +#include "qinisettings.h" +#include "rssmanager.h" +#include "rssfeed.h" +#include "iconprovider.h" + +AutomatedRssDownloader::AutomatedRssDownloader(QWidget *parent) : + QDialog(parent), + ui(new Ui::AutomatedRssDownloader), + m_editedRule(0) +{ + ui->setupUi(this); + // Icons + ui->removeRuleBtn->setIcon(IconProvider::instance()->getIcon("list-remove")); + ui->addRuleBtn->setIcon(IconProvider::instance()->getIcon("list-add")); + + // Ui Settings + ui->listRules->setSortingEnabled(true); + ui->listRules->setSelectionMode(QAbstractItemView::ExtendedSelection); + ui->treeMatchingArticles->setSortingEnabled(true); + ui->hsplitter->setCollapsible(0, false); + ui->hsplitter->setCollapsible(1, false); + ui->hsplitter->setCollapsible(2, true); // Only the preview list is collapsible + bool ok; Q_UNUSED(ok); + ok = connect(ui->checkRegex, SIGNAL(toggled(bool)), SLOT(updateFieldsToolTips(bool))); + Q_ASSERT(ok); + ok = connect(ui->listRules, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayRulesListMenu(const QPoint&))); + Q_ASSERT(ok); + m_ruleList = RssDownloadRuleList::instance(); + initLabelCombobox(); + loadFeedList(); + loadSettings(); + ok = connect(ui->listRules, SIGNAL(itemSelectionChanged()), SLOT(updateRuleDefinitionBox())); + Q_ASSERT(ok); + ok = connect(ui->listRules, SIGNAL(itemSelectionChanged()), SLOT(updateFeedList())); + Q_ASSERT(ok); + ok = connect(ui->listFeeds, SIGNAL(itemChanged(QListWidgetItem*)), SLOT(handleFeedCheckStateChange(QListWidgetItem*))); + Q_ASSERT(ok); + // Update matching articles when necessary + ok = connect(ui->lineContains, SIGNAL(textEdited(QString)), SLOT(updateMatchingArticles())); + Q_ASSERT(ok); + ok = connect(ui->lineContains, SIGNAL(textEdited(QString)), SLOT(updateMustLineValidity())); + Q_ASSERT(ok); + ok = connect(ui->lineNotContains, SIGNAL(textEdited(QString)), SLOT(updateMatchingArticles())); + Q_ASSERT(ok); + ok = connect(ui->lineNotContains, SIGNAL(textEdited(QString)), SLOT(updateMustNotLineValidity())); + Q_ASSERT(ok); + updateRuleDefinitionBox(); + updateFeedList(); +} + +AutomatedRssDownloader::~AutomatedRssDownloader() +{ + qDebug() << Q_FUNC_INFO; + // Save current item on exit + saveEditedRule(); + saveSettings(); + delete ui; +} + +void AutomatedRssDownloader::loadSettings() +{ + // load dialog geometry + QIniSettings settings("qBittorrent", "qBittorrent"); + restoreGeometry(settings.value("RssFeedDownloader/geometry").toByteArray()); + ui->checkEnableDownloader->setChecked(RssSettings().isRssDownloadingEnabled()); + ui->hsplitter->restoreState(settings.value("RssFeedDownloader/hsplitterSizes").toByteArray()); + // Display download rules + loadRulesList(); +} + +void AutomatedRssDownloader::saveSettings() +{ + RssSettings().setRssDownloadingEnabled(ui->checkEnableDownloader->isChecked()); + // Save dialog geometry + QIniSettings settings("qBittorrent", "qBittorrent"); + settings.setValue("RssFeedDownloader/geometry", saveGeometry()); + settings.setValue("RssFeedDownloader/hsplitterSizes", ui->hsplitter->saveState()); +} + +void AutomatedRssDownloader::loadRulesList() +{ + // Make sure we save the current item before clearing + if(m_editedRule) { + saveEditedRule(); + } + ui->listRules->clear(); + foreach (const QString &rule_name, m_ruleList->ruleNames()) { + QListWidgetItem *item = new QListWidgetItem(rule_name, ui->listRules); + item->setFlags(item->flags()|Qt::ItemIsUserCheckable); + if(m_ruleList->getRule(rule_name).isEnabled()) + item->setCheckState(Qt::Checked); + else + item->setCheckState(Qt::Unchecked); + } + if(ui->listRules->count() > 0 && !ui->listRules->currentItem()) + ui->listRules->setCurrentRow(0); +} + +void AutomatedRssDownloader::loadFeedList() +{ + const RssSettings settings; + const QStringList feed_aliases = settings.getRssFeedsAliases(); + const QStringList feed_urls = settings.getRssFeedsUrls(); + QStringList existing_urls; + for(int i=0; ilistFeeds); + item->setData(Qt::UserRole, feed_url); + item->setFlags(item->flags()|Qt::ItemIsUserCheckable); + existing_urls << feed_url; + } +} + +void AutomatedRssDownloader::updateFeedList() +{ + disconnect(ui->listFeeds, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(handleFeedCheckStateChange(QListWidgetItem*))); + for(int i=0; ilistFeeds->count(); ++i) { + QListWidgetItem *item = ui->listFeeds->item(i); + const QString feed_url = item->data(Qt::UserRole).toString(); + bool all_enabled = false; + foreach(const QListWidgetItem *ruleItem, ui->listRules->selectedItems()) { + RssDownloadRule rule = m_ruleList->getRule(ruleItem->text()); + if(!rule.isValid()) continue; + qDebug() << "Rule" << rule.name() << "affects" << rule.rssFeeds().size() << "feeds."; + foreach(QString test, rule.rssFeeds()) { + qDebug() << "Feed is " << test; + } + if(rule.rssFeeds().contains(feed_url)) { + qDebug() << "Rule " << rule.name() << " affects feed " << feed_url; + all_enabled = true; + } else { + qDebug() << "Rule " << rule.name() << " does NOT affect feed " << feed_url; + all_enabled = false; + break; + } + } + if(all_enabled) + item->setCheckState(Qt::Checked); + else + item->setCheckState(Qt::Unchecked); + } + ui->listFeeds->setEnabled(!ui->listRules->selectedItems().isEmpty()); + connect(ui->listFeeds, SIGNAL(itemChanged(QListWidgetItem*)), SLOT(handleFeedCheckStateChange(QListWidgetItem*))); + updateMatchingArticles(); +} + +bool AutomatedRssDownloader::isRssDownloaderEnabled() const +{ + return ui->checkEnableDownloader->isChecked(); +} + +void AutomatedRssDownloader::updateRuleDefinitionBox() +{ + qDebug() << Q_FUNC_INFO; + // Save previous rule first + saveEditedRule(); + // Update rule definition box + const QList selection = ui->listRules->selectedItems(); + if(selection.count() == 1) { + m_editedRule = selection.first(); + RssDownloadRule rule = getCurrentRule(); + if(rule.isValid()) { + ui->lineContains->setText(rule.mustContain()); + ui->lineNotContains->setText(rule.mustNotContain()); + ui->saveDiffDir_check->setChecked(!rule.savePath().isEmpty()); + ui->lineSavePath->setText(rule.savePath()); + ui->checkRegex->setChecked(rule.useRegex()); + if(rule.label().isEmpty()) { + ui->comboLabel->setCurrentIndex(-1); + ui->comboLabel->clearEditText(); + } else { + ui->comboLabel->setCurrentIndex(ui->comboLabel->findText(rule.label())); + } + updateMustLineValidity(); + updateMustNotLineValidity(); + } else { + // New rule + clearRuleDefinitionBox(); + ui->lineContains->setText(selection.first()->text()); + } + updateFieldsToolTips(ui->checkRegex->isChecked()); + // Enable + ui->ruleDefBox->setEnabled(true); + } else { + m_editedRule = 0; + // Clear + clearRuleDefinitionBox(); + ui->ruleDefBox->setEnabled(false); + } +} + +void AutomatedRssDownloader::clearRuleDefinitionBox() +{ + ui->lineContains->clear(); + ui->lineNotContains->clear(); + ui->saveDiffDir_check->setChecked(false); + ui->lineSavePath->clear(); + ui->comboLabel->clearEditText(); + ui->checkRegex->setChecked(false); + updateFieldsToolTips(ui->checkRegex->isChecked()); + updateMustLineValidity(); + updateMustNotLineValidity(); +} + +RssDownloadRule AutomatedRssDownloader::getCurrentRule() const +{ + QListWidgetItem * current_item = ui->listRules->currentItem(); + if(current_item) + return m_ruleList->getRule(current_item->text()); + return RssDownloadRule(); +} + +void AutomatedRssDownloader::initLabelCombobox() +{ + // Load custom labels + const QStringList customLabels = Preferences().getTorrentLabels(); + foreach(const QString& label, customLabels) { + ui->comboLabel->addItem(label); + } +} + +void AutomatedRssDownloader::saveEditedRule() +{ + if(!m_editedRule) return; + qDebug() << Q_FUNC_INFO << m_editedRule; + if(ui->listRules->findItems(m_editedRule->text(), Qt::MatchExactly).isEmpty()) { + qDebug() << "Could not find rule" << m_editedRule->text() << "in the UI list"; + qDebug() << "Probably removed the item, no need to save it"; + return; + } + RssDownloadRule rule = m_ruleList->getRule(m_editedRule->text()); + if(!rule.isValid()) { + rule.setName(m_editedRule->text()); + } + if(m_editedRule->checkState() == Qt::Unchecked) + rule.setEnabled(false); + else + rule.setEnabled(true); + rule.setUseRegex(ui->checkRegex->isChecked()); + rule.setMustContain(ui->lineContains->text()); + rule.setMustNotContain(ui->lineNotContains->text()); + if(ui->saveDiffDir_check->isChecked()) + rule.setSavePath(ui->lineSavePath->text()); + else + rule.setSavePath(""); + rule.setLabel(ui->comboLabel->currentText()); + // Save new label + if(!rule.label().isEmpty()) + Preferences().addTorrentLabel(rule.label()); + //rule.setRssFeeds(getSelectedFeeds()); + // Save it + m_ruleList->saveRule(rule); +} + + +void AutomatedRssDownloader::on_addRuleBtn_clicked() +{ + // Ask for a rule name + const QString rule = QInputDialog::getText(this, tr("New rule name"), tr("Please type the name of the new download rule.")); + if(rule.isEmpty()) return; + // Check if this rule name already exists + if(m_ruleList->getRule(rule).isValid()) { + QMessageBox::warning(this, tr("Rule name conflict"), tr("A rule with this name already exists, please choose another name.")); + return; + } + // Add the new rule to the list + QListWidgetItem * item = new QListWidgetItem(rule, ui->listRules); + item->setFlags(item->flags()|Qt::ItemIsUserCheckable); + item->setCheckState(Qt::Checked); // Enable as a default + ui->listRules->clearSelection(); + ui->listRules->setCurrentItem(item); +} + +void AutomatedRssDownloader::on_removeRuleBtn_clicked() +{ + const QList selection = ui->listRules->selectedItems(); + if(selection.isEmpty()) return; + // Ask for confirmation + QString confirm_text; + if(selection.count() == 1) + confirm_text = tr("Are you sure you want to remove the download rule named %1?").arg(selection.first()->text()); + else + confirm_text = tr("Are you sure you want to remove the selected download rules?"); + if(QMessageBox::question(this, tr("Rule deletion confirmation"), confirm_text, QMessageBox::Yes, QMessageBox::No) != QMessageBox::Yes) + return; + foreach(QListWidgetItem *item, selection) { + // Actually remove the item + ui->listRules->removeItemWidget(item); + const QString rule_name = item->text(); + // Clean up memory + delete item; + qDebug("Removed item for the UI list"); + // Remove it from the m_ruleList + m_ruleList->removeRule(rule_name); + } +} + +void AutomatedRssDownloader::on_browseSP_clicked() +{ + QString save_path = QFileDialog::getExistingDirectory(this, tr("Destination directory"), QDir::homePath()); + if(!save_path.isEmpty()) + ui->lineSavePath->setText(save_path); +} + +void AutomatedRssDownloader::on_exportBtn_clicked() +{ + if(m_ruleList->isEmpty()) { + QMessageBox::warning(this, tr("Invalid action"), tr("The list is empty, there is nothing to export.")); + return; + } + // Ask for a save path + QString save_path = QFileDialog::getSaveFileName(this, tr("Where would you like to save the list?"), QDir::homePath(), tr("Rules list (*.rssrules)")); + if(save_path.isEmpty()) return; + if(!save_path.endsWith(".rssrules", Qt::CaseInsensitive)) + save_path += ".rssrules"; + if(!m_ruleList->serialize(save_path)) { + QMessageBox::warning(this, tr("I/O Error"), tr("Failed to create the destination file")); + return; + } +} + +void AutomatedRssDownloader::on_importBtn_clicked() +{ + // Ask for filter path + QString load_path = QFileDialog::getOpenFileName(this, tr("Please point to the RSS download rules file"), QDir::homePath(), tr("Rules list (*.rssrules *.filters)")); + if(load_path.isEmpty() || !QFile::exists(load_path)) return; + // Load it + if(!m_ruleList->unserialize(load_path)) { + QMessageBox::warning(this, tr("Import Error"), tr("Failed to import the selected rules file")); + return; + } + // Reload the rule list + loadRulesList(); +} + +void AutomatedRssDownloader::displayRulesListMenu(const QPoint &pos) +{ + Q_UNUSED(pos); + QMenu menu; + QAction *addAct = menu.addAction(IconProvider::instance()->getIcon("list-add"), tr("Add new rule...")); + QAction *delAct = 0; + QAction *renameAct = 0; + const QList selection = ui->listRules->selectedItems(); + if(!selection.isEmpty()) { + if(selection.count() == 1) { + delAct = menu.addAction(IconProvider::instance()->getIcon("list-remove"), tr("Delete rule")); + menu.addSeparator(); + renameAct = menu.addAction(IconProvider::instance()->getIcon("edit-rename"), tr("Rename rule...")); + } else { + delAct = menu.addAction(IconProvider::instance()->getIcon("list-remove"), tr("Delete selected rules")); + } + } + QAction *act = menu.exec(QCursor::pos()); + if(!act) return; + if(act == addAct) { + on_addRuleBtn_clicked(); + return; + } + if(act == delAct) { + on_removeRuleBtn_clicked(); + return; + } + if(act == renameAct) { + renameSelectedRule(); + return; + } +} + +void AutomatedRssDownloader::renameSelectedRule() +{ + QListWidgetItem *item = ui->listRules->currentItem(); + if(!item) return; + forever { + QString new_name = QInputDialog::getText(this, tr("Rule renaming"), tr("Please type the new rule name"), QLineEdit::Normal, item->text()); + new_name = new_name.trimmed(); + if(new_name.isEmpty()) return; + if(m_ruleList->ruleNames().contains(new_name, Qt::CaseInsensitive)) { + QMessageBox::warning(this, tr("Rule name conflict"), tr("A rule with this name already exists, please choose another name.")); + } else { + // Rename the rule + m_ruleList->renameRule(item->text(), new_name); + item->setText(new_name); + return; + } + } +} + +void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feed_item) +{ + if(ui->ruleDefBox->isEnabled()) { + // Make sure the current rule is saved + saveEditedRule(); + } + const QString feed_url = feed_item->data(Qt::UserRole).toString(); + foreach (QListWidgetItem* rule_item, ui->listRules->selectedItems()) { + RssDownloadRule rule = m_ruleList->getRule(rule_item->text()); + Q_ASSERT(rule.isValid()); + QStringList affected_feeds = rule.rssFeeds(); + if(feed_item->checkState() == Qt::Checked) { + if(!affected_feeds.contains(feed_url)) + affected_feeds << feed_url; + } else { + if(affected_feeds.contains(feed_url)) + affected_feeds.removeOne(feed_url); + } + // Save the updated rule + if(affected_feeds.size() != rule.rssFeeds().size()) { + rule.setRssFeeds(affected_feeds); + m_ruleList->saveRule(rule); + } + } + // Update Matching articles + updateMatchingArticles(); +} + +void AutomatedRssDownloader::updateMatchingArticles() +{ + ui->treeMatchingArticles->clear(); + if(ui->ruleDefBox->isEnabled()) { + saveEditedRule(); + } + const QHash all_feeds = RssManager::instance()->getAllFeedsAsHash(); + + foreach(const QListWidgetItem *rule_item, ui->listRules->selectedItems()) { + RssDownloadRule rule = m_ruleList->getRule(rule_item->text()); + if(!rule.isValid()) continue; + foreach(const QString &feed_url, rule.rssFeeds()) { + qDebug() << Q_FUNC_INFO << feed_url; + Q_ASSERT(all_feeds.contains(feed_url)); + if(!all_feeds.contains(feed_url)) continue; + const RssFeed *feed = all_feeds.value(feed_url); + Q_ASSERT(feed); + if(!feed) continue; + const QStringList matching_articles = rule.findMatchingArticles(feed); + if(!matching_articles.isEmpty()) + addFeedArticlesToTree(feed, matching_articles); + } + } +} + +void AutomatedRssDownloader::addFeedArticlesToTree(const RssFeed *feed, const QStringList &articles) +{ + // Check if this feed is already in the tree + QTreeWidgetItem *treeFeedItem = 0; + for(int i=0; itreeMatchingArticles->topLevelItemCount(); ++i) { + QTreeWidgetItem *item = ui->treeMatchingArticles->topLevelItem(i); + if(item->data(0, Qt::UserRole).toString() == feed->url()) { + treeFeedItem = item; + break; + } + } + // If there is none, create it + if(!treeFeedItem) { + treeFeedItem = new QTreeWidgetItem(QStringList() << feed->displayName()); + treeFeedItem->setToolTip(0, feed->displayName()); + QFont f = treeFeedItem->font(0); + f.setBold(true); + treeFeedItem->setFont(0, f); + treeFeedItem->setData(0, Qt::DecorationRole, IconProvider::instance()->getIcon("inode-directory")); + treeFeedItem->setData(0, Qt::UserRole, feed->url()); + ui->treeMatchingArticles->addTopLevelItem(treeFeedItem); + } + // Insert the articles + foreach(const QString &art, articles) { + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << art); + item->setToolTip(0, art); + treeFeedItem->addChild(item); + } + ui->treeMatchingArticles->expandItem(treeFeedItem); +} + +void AutomatedRssDownloader::updateFieldsToolTips(bool regex) +{ + QString tip; + if(regex) { + tip = tr("Regex mode: use Perl-like regular expressions"); + ui->lineContains->setToolTip(tip); + ui->lineNotContains->setToolTip(tip); + } else { + tip = tr("Wildcard mode: you can use