[{"data":1,"prerenderedAt":19379},["ShallowReactive",2],{"tag-posts-qt":3},[4,1597,3506,3791,4283,5617,5933,9082,10315,12003,12678,15193,16382,16579,16701,16783,17222,17473,17801,17958,18059,19099,19207],{"id":5,"title":6,"author":7,"body":8,"category":1560,"categorySlug":1561,"date":1562,"description":61,"excerpt":1563,"extension":1584,"location":1585,"meta":1586,"navigation":275,"path":1587,"published":275,"seo":1588,"slug":1589,"stem":1590,"tags":1591,"timeToRead":400,"__hash__":1596},"posts\u002Fposts\u002FProgrammation\u002F2016-12-10-findsimilarity.md","FindSimilarity - Trouver les différences entre plusieurs vidéos","Ulrich Vandenhekke",{"type":9,"value":10,"toc":1548},"minimark",[11,16,20,23,26,29,35,45,49,52,55,99,102,154,158,161,177,183,191,194,203,206,209,212,657,661,664,673,676,679,705,708,832,835,843,858,861,864,1414,1424,1428,1431,1436,1439,1442,1449,1452,1456,1462,1472,1475,1492,1509,1513,1516,1522,1525,1531,1537,1541,1544],[12,13,15],"h3",{"id":14},"introduction","Introduction",[17,18,19],"p",{},"Bonjour,",[17,21,22],{},"Je souhaite vous présenter une petite expérience que je viens d'écrire.",[17,24,25],{},"Cela fait plusieurs années que je souhaitais m'amuser sur la librairie OpenCV mais sans jamais en avoir eu l'utilité. J'ai profité d'avoir un peu de temps libre, pour écrire un petit\nprogramme dont le but est de comparer un ensemble de vidéos.",[17,27,28],{},"Le but est ensuite de dire si dans cet ensemble de vidéos, deux vidéos sont identiques, ou se ressemblent, ou sont trop éloignées.",[17,30,31],{},[32,33,34],"em",{},"J'ai souhaité faire cette expérience par amusement, je n'ai donc pas passé beaucoup de temps sur la qualité du code écrit. Ce dernier aurait pu être mieux découpé, posséder des\ncommentaires, des tests unitaires, ... . Si vous voulez utiliser ce code pour un véritable usage production, n'hésitez pas à améliorer celui ci.",[17,36,37,38,44],{},"Vous pouvez trouver le code source de cette expérience à l'adresse suivante : ",[39,40,41],"a",{"href":41,"rel":42},"https:\u002F\u002Fgogs.shadoware.org\u002FShadowareOrg\u002Ffind-similarity",[43],"nofollow",".",[12,46,48],{"id":47},"le-jeux-de-données","Le jeux de données",[17,50,51],{},"J'ai pris plusieurs films en DVD que je possède. Possédant un NAS, et une chromecast, j'encode ces DVD au format vidéo et je les y dépose. Malheureusement la qualité est dégradée\npar rapport au DVD.",[17,53,54],{},"Pour constituer le jeu de données, je prends ces films encodés, que je dépose dans un dossier. Je copie certains d'entre eux telquel",[56,57,62],"pre",{"className":58,"code":59,"language":60,"meta":61,"style":61},"language-bash shiki shiki-themes one-dark-pro","mkdir example\ncd example\ncp ..\u002Ffilm1.avi film1_copy.avi\n","bash","",[63,64,65,78,87],"code",{"__ignoreMap":61},[66,67,70,74],"span",{"class":68,"line":69},"line",1,[66,71,73],{"class":72},"sVbv2","mkdir",[66,75,77],{"class":76},"subq3"," example\n",[66,79,81,85],{"class":68,"line":80},2,[66,82,84],{"class":83},"sjrmR","cd",[66,86,77],{"class":76},[66,88,90,93,96],{"class":68,"line":89},3,[66,91,92],{"class":72},"cp",[66,94,95],{"class":76}," ..\u002Ffilm1.avi",[66,97,98],{"class":76}," film1_copy.avi\n",[17,100,101],{},"J'encode certains de ces films avec une résolution différente :",[56,103,105],{"className":58,"code":104,"language":60,"meta":61,"style":61},"avconv -i film2.m4v  -preset veryslow -s 320x240 film2.320x240.m4v\navconv -i film2.m4v  -preset veryslow -s 640x480 film2.640x480.m4v\n",[63,106,107,134],{"__ignoreMap":61},[66,108,109,112,116,119,122,125,128,131],{"class":68,"line":69},[66,110,111],{"class":72},"avconv",[66,113,115],{"class":114},"sVC51"," -i",[66,117,118],{"class":76}," film2.m4v",[66,120,121],{"class":114},"  -preset",[66,123,124],{"class":76}," veryslow",[66,126,127],{"class":114}," -s",[66,129,130],{"class":76}," 320x240",[66,132,133],{"class":76}," film2.320x240.m4v\n",[66,135,136,138,140,142,144,146,148,151],{"class":68,"line":80},[66,137,111],{"class":72},[66,139,115],{"class":114},[66,141,118],{"class":76},[66,143,121],{"class":114},[66,145,124],{"class":76},[66,147,127],{"class":114},[66,149,150],{"class":76}," 640x480",[66,152,153],{"class":76}," film2.640x480.m4v\n",[12,155,157],{"id":156},"comment-fonctionne-la-comparaison","Comment fonctionne la comparaison",[17,159,160],{},"Avant de parler de la comparaison, parlons des fichiers que nous allons comparer. Le programme va se constituer une liste des fichiers à comparer et pour chaque fichier va lire\nles informations suivantes :",[162,163,164,168,171,174],"ul",{},[165,166,167],"li",{},"la durée du film",[165,169,170],{},"la largeur",[165,172,173],{},"la hauteur",[165,175,176],{},"une miniature du film (utilisée pour comparer à l'oeil les vidéos)",[17,178,179,180,44],{},"Ensuite, une fois les méta-données récupérées, le programe se constitue une liste de paires de fichiers à comparer en sélectionnant les fichiers qui ont une durée identique à +\u002F- 5\nsecondes. Ce paramètre est modifiable au niveau de la constante ",[63,181,182],{},"DELTA_SEC",[17,184,185,186,44],{},"Enfin vient la comparaison pour laquelle je me suis simplement basé sur les exemples du site OpenCV que vous pouvez trouver dans la rubrique\n",[39,187,190],{"href":188,"rel":189},"http:\u002F\u002Fdocs.opencv.org\u002F2.4\u002Fdoc\u002Ftutorials\u002Fhighgui\u002Fvideo-input-psnr-ssim\u002Fvideo-input-psnr-ssim.html",[43],"Video Input with OpenCV and similarity measurement",[17,192,193],{},"J'ai utilisé l'algorithme PSNR (Peak signal-to-noise ratio) pour déterminer si les deux images de la vidéos sont plutôt proches ou éloignées. Cet algorithme calcul la distorsion\nentre deux images. Il est principalement utilisé pour quantifier la performance réalisée par un encodeur lors de la compression d'une vidéo. Une valeur entre 30 et 50 signifie que\nles images sont relativement proches. Plus la valeur est haute, et plus la qualité d'image est conservée entre les deux images. Si la valeur est inférieure à 30 on peut estimer qu'il\ny a une forte chance pour que les images soit différentes.",[17,195,196,197,202],{},"Vous pouvez retrouver les formules utilisées par le calcul sur le site d'OpenCV ou sur la page ",[39,198,201],{"href":199,"rel":200},"https:\u002F\u002Ffr.wikipedia.org\u002Fwiki\u002FPeak_Signal_to_Noise_Ratio",[43],"Wikipedia",". Est-ce que ce\ncalcul est le meilleur pour trouver les images similaires ? Je ne sais pas. Si vous avez d'autres propositions, on peut les tester.",[17,204,205],{},"Sur une vidéo on a une multitude d'images (sur un film d'une heure et demie à 25 images secondes, nous en avons 135 000), on pourrait comparer chaque image de la vidéo pour se faire\nune moyenne, de mon coté j'ai préféré comparer une image au milieu de la vidéo afin de parcourir plus vite les vidéos.",[17,207,208],{},"De la même manière pour m'abstraire de la taille de la vidéo qui peut avoir été modififée, je redimensionne, à tort ou à raison, les deux images à une taille identique\n(arbitrairement: 160x120).",[17,210,211],{},"Je vous présente donc ci-dessous l'algorithme que vous pouvez retrouver sur le site d'OpenCV. J'ai légèrement modifié l'algorithme pour redimensionner les images ainsi que pour\nretourner une valeur de PSNR infiniment grande quand deux vidéos sont identiques.",[56,213,217],{"className":214,"code":215,"language":216,"meta":61,"style":61},"language-cpp shiki shiki-themes one-dark-pro","double getPSNR(const cv::Mat& F1, const cv::Mat& F2) {\n    cv::Mat I1, I2;\n\n    cv::resize(F1, I1, cv::Size(160, 120));\n    cv::resize(F2, I2, cv::Size(160, 120));\n\n    cv::Mat s1;\n    cv::absdiff(I1, I2, s1);   \u002F\u002F |I1 - I2|\n    s1.convertTo(s1, CV_32F);  \u002F\u002F cannot make a square on 8 bits\n    s1 = s1.mul(s1);           \u002F\u002F |I1 - I2|^2\n\n    cv::Scalar s = sum(s1);    \u002F\u002F sum elements per channel\n\n    double sse = s.val[0] + s.val[1] + s.val[2]; \u002F\u002F sum channels\n\n    if( sse \u003C= 1e-10) {        \u002F\u002F for small values return zero\n        return std::numeric_limits\u003Cdouble>::infinity();\n    } else {\n        double mse  = sse \u002F (double)(I1.channels() * I1.total());\n        double psnr = 10.0 * log10((255 * 255) \u002F mse);\n        return psnr;\n    }\n","cpp",[63,218,219,266,271,277,305,327,332,338,353,370,393,398,414,419,483,488,518,544,556,605,643,651],{"__ignoreMap":61},[66,220,221,225,228,232,235,238,242,245,249,252,254,256,258,260,263],{"class":68,"line":69},[66,222,224],{"class":223},"seHd6","double",[66,226,227],{"class":72}," getPSNR",[66,229,231],{"class":230},"sn6KH","(",[66,233,234],{"class":223},"const",[66,236,237],{"class":230}," cv::",[66,239,241],{"class":240},"sU0A5","Mat",[66,243,244],{"class":223},"&",[66,246,248],{"class":247},"s_ZVi"," F1",[66,250,251],{"class":230},", ",[66,253,234],{"class":223},[66,255,237],{"class":230},[66,257,241],{"class":240},[66,259,244],{"class":223},[66,261,262],{"class":247}," F2",[66,264,265],{"class":230},") {\n",[66,267,268],{"class":68,"line":80},[66,269,270],{"class":230},"    cv::Mat I1, I2;\n",[66,272,273],{"class":68,"line":89},[66,274,276],{"emptyLinePlaceholder":275},true,"\n",[66,278,280,283,286,289,292,294,297,299,302],{"class":68,"line":279},4,[66,281,282],{"class":230},"    cv::",[66,284,285],{"class":72},"resize",[66,287,288],{"class":230},"(F1, I1, cv::",[66,290,291],{"class":72},"Size",[66,293,231],{"class":230},[66,295,296],{"class":114},"160",[66,298,251],{"class":230},[66,300,301],{"class":114},"120",[66,303,304],{"class":230},"));\n",[66,306,308,310,312,315,317,319,321,323,325],{"class":68,"line":307},5,[66,309,282],{"class":230},[66,311,285],{"class":72},[66,313,314],{"class":230},"(F2, I2, cv::",[66,316,291],{"class":72},[66,318,231],{"class":230},[66,320,296],{"class":114},[66,322,251],{"class":230},[66,324,301],{"class":114},[66,326,304],{"class":230},[66,328,330],{"class":68,"line":329},6,[66,331,276],{"emptyLinePlaceholder":275},[66,333,335],{"class":68,"line":334},7,[66,336,337],{"class":230},"    cv::Mat s1;\n",[66,339,341,343,346,349],{"class":68,"line":340},8,[66,342,282],{"class":230},[66,344,345],{"class":72},"absdiff",[66,347,348],{"class":230},"(I1, I2, s1);",[66,350,352],{"class":351},"sV9Aq","   \u002F\u002F |I1 - I2|\n",[66,354,356,359,361,364,367],{"class":68,"line":355},9,[66,357,358],{"class":240},"    s1",[66,360,44],{"class":230},[66,362,363],{"class":72},"convertTo",[66,365,366],{"class":230},"(s1, CV_32F);",[66,368,369],{"class":351},"  \u002F\u002F cannot make a square on 8 bits\n",[66,371,373,376,379,382,384,387,390],{"class":68,"line":372},10,[66,374,375],{"class":230},"    s1 ",[66,377,378],{"class":223},"=",[66,380,381],{"class":240}," s1",[66,383,44],{"class":230},[66,385,386],{"class":72},"mul",[66,388,389],{"class":230},"(s1);",[66,391,392],{"class":351},"           \u002F\u002F |I1 - I2|^2\n",[66,394,396],{"class":68,"line":395},11,[66,397,276],{"emptyLinePlaceholder":275},[66,399,401,404,406,409,411],{"class":68,"line":400},12,[66,402,403],{"class":230},"    cv::Scalar s ",[66,405,378],{"class":223},[66,407,408],{"class":72}," sum",[66,410,389],{"class":230},[66,412,413],{"class":351},"    \u002F\u002F sum elements per channel\n",[66,415,417],{"class":68,"line":416},13,[66,418,276],{"emptyLinePlaceholder":275},[66,420,422,425,428,430,433,435,439,442,445,448,451,453,455,457,459,462,464,466,468,470,472,474,477,480],{"class":68,"line":421},14,[66,423,424],{"class":223},"    double",[66,426,427],{"class":230}," sse ",[66,429,378],{"class":223},[66,431,432],{"class":240}," s",[66,434,44],{"class":230},[66,436,438],{"class":437},"sVyAn","val",[66,440,441],{"class":230},"[",[66,443,444],{"class":114},"0",[66,446,447],{"class":230},"] ",[66,449,450],{"class":223},"+",[66,452,432],{"class":240},[66,454,44],{"class":230},[66,456,438],{"class":437},[66,458,441],{"class":230},[66,460,461],{"class":114},"1",[66,463,447],{"class":230},[66,465,450],{"class":223},[66,467,432],{"class":240},[66,469,44],{"class":230},[66,471,438],{"class":437},[66,473,441],{"class":230},[66,475,476],{"class":114},"2",[66,478,479],{"class":230},"];",[66,481,482],{"class":351}," \u002F\u002F sum channels\n",[66,484,486],{"class":68,"line":485},15,[66,487,276],{"emptyLinePlaceholder":275},[66,489,491,494,497,500,503,506,509,512,515],{"class":68,"line":490},16,[66,492,493],{"class":223},"    if",[66,495,496],{"class":230},"( sse ",[66,498,499],{"class":223},"\u003C=",[66,501,502],{"class":114}," 1",[66,504,505],{"class":437},"e",[66,507,508],{"class":230},"-",[66,510,511],{"class":114},"10",[66,513,514],{"class":230},") {",[66,516,517],{"class":351},"        \u002F\u002F for small values return zero\n",[66,519,521,524,527,530,533,535,538,541],{"class":68,"line":520},17,[66,522,523],{"class":223},"        return",[66,525,526],{"class":230}," std::",[66,528,529],{"class":240},"numeric_limits",[66,531,532],{"class":230},"\u003C",[66,534,224],{"class":223},[66,536,537],{"class":230},">::",[66,539,540],{"class":72},"infinity",[66,542,543],{"class":230},"();\n",[66,545,547,550,553],{"class":68,"line":546},18,[66,548,549],{"class":230},"    } ",[66,551,552],{"class":223},"else",[66,554,555],{"class":230}," {\n",[66,557,559,562,565,567,569,572,575,577,580,583,585,588,591,594,597,599,602],{"class":68,"line":558},19,[66,560,561],{"class":223},"        double",[66,563,564],{"class":230}," mse  ",[66,566,378],{"class":223},[66,568,427],{"class":230},[66,570,571],{"class":223},"\u002F",[66,573,574],{"class":230}," (",[66,576,224],{"class":223},[66,578,579],{"class":230},")(",[66,581,582],{"class":240},"I1",[66,584,44],{"class":230},[66,586,587],{"class":72},"channels",[66,589,590],{"class":230},"() ",[66,592,593],{"class":223},"*",[66,595,596],{"class":240}," I1",[66,598,44],{"class":230},[66,600,601],{"class":72},"total",[66,603,604],{"class":230},"());\n",[66,606,608,610,613,615,618,621,624,627,630,632,635,638,640],{"class":68,"line":607},20,[66,609,561],{"class":223},[66,611,612],{"class":230}," psnr ",[66,614,378],{"class":223},[66,616,617],{"class":114}," 10.0",[66,619,620],{"class":223}," *",[66,622,623],{"class":72}," log10",[66,625,626],{"class":230},"((",[66,628,629],{"class":114},"255",[66,631,620],{"class":223},[66,633,634],{"class":114}," 255",[66,636,637],{"class":230},") ",[66,639,571],{"class":223},[66,641,642],{"class":230}," mse);\n",[66,644,646,648],{"class":68,"line":645},21,[66,647,523],{"class":223},[66,649,650],{"class":230}," psnr;\n",[66,652,654],{"class":68,"line":653},22,[66,655,656],{"class":230},"    }\n",[12,658,660],{"id":659},"optimisation","Optimisation",[17,662,663],{},"La raison qui fait que je voulais m'amuser avec OpenCV c'est qu'il permet de faire ces calculs à l'aide du GPU au lieu du CPU.",[17,665,666,667,672],{},"L'utilisation du GPU permet d'améliorer la vitesse de calcul pour tout ce qui est traitement d'image, ce pour quoi un GPU est prévu pour. Pour plus d'informations sur\nl'utilisation du GPU dans OpenCV peut être trouvé sur la page ",[39,668,671],{"href":669,"rel":670},"http:\u002F\u002Fopencv.org\u002Fplatforms\u002Fcuda.html",[43],"CUDA"," d'OpenCV.",[17,674,675],{},"Le problème est que sur la version de Debian jessie que j'utilise, OpenCV n'est pas compilé avec CUDA, et ne permet donc pas d'utiliser le GPU. J'ai donc dû compiler ma propre\nversion d'OpenCV.",[17,677,678],{},"Pour cela la première étape consiste à récupérer le code source et à se positionner sur la branche que l'on souhaite compiler. Pour ma part je préfère compiler sur la branche 2.4,\nplus proche de la version de Debian.",[56,680,682],{"className":58,"code":681,"language":60,"meta":61,"style":61},"git clone https:\u002F\u002Fgithub.com\u002Fopencv\u002Fopencv.git\ngit checkout 2.4\n",[63,683,684,695],{"__ignoreMap":61},[66,685,686,689,692],{"class":68,"line":69},[66,687,688],{"class":72},"git",[66,690,691],{"class":76}," clone",[66,693,694],{"class":76}," https:\u002F\u002Fgithub.com\u002Fopencv\u002Fopencv.git\n",[66,696,697,699,702],{"class":68,"line":80},[66,698,688],{"class":72},[66,700,701],{"class":76}," checkout",[66,703,704],{"class":114}," 2.4\n",[17,706,707],{},"Viens ensuite la compilation :",[56,709,711],{"className":58,"code":710,"language":60,"meta":61,"style":61},"mkdir build\ncd build\ncmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=\u002Fhome\u002Fphoenix\u002Fusr\u002Flocal  -DENABLE_SSE=ON -DENABLE_SSE2=ON -DENABLE_SSE3=ON -DWITH_TBB=ON -DWITH_1394=ON -DWITH_V4L=ON -DWITH_OPENGL=ON  -DWITH_GTK=ON -DWITH_JASPER=ON -DWITH_JPEG=ON -DWITH_PNG=ON -DWITH_TIFF=ON  -DWITH_OPENEXR=ON -DWITH_PVAPI=ON   -DWITH_EIGEN=ON -DCMAKE_SKIP_RPATH=ON -D WITH_CUDA=ON -D ENABLE_FAST_MATH=1 -D CUDA_FAST_MATH=1 -D WITH_CUBLAS=1 -DWITH_IPP=ON -D CUDA_GENERATION=Auto -D WITH_FFMPEG=ON  ..\u002F\n",[63,712,713,720,726],{"__ignoreMap":61},[66,714,715,717],{"class":68,"line":69},[66,716,73],{"class":72},[66,718,719],{"class":76}," build\n",[66,721,722,724],{"class":68,"line":80},[66,723,84],{"class":83},[66,725,719],{"class":76},[66,727,728,731,734,737,739,742,745,748,751,754,757,760,763,766,769,772,775,778,781,784,787,790,792,795,797,800,802,804,807,809,811,814,816,819,821,824,826,829],{"class":68,"line":89},[66,729,730],{"class":72},"cmake",[66,732,733],{"class":114}," -D",[66,735,736],{"class":76}," CMAKE_BUILD_TYPE=RELEASE",[66,738,733],{"class":114},[66,740,741],{"class":76}," CMAKE_INSTALL_PREFIX=\u002Fhome\u002Fphoenix\u002Fusr\u002Flocal",[66,743,744],{"class":114},"  -DENABLE_SSE=ON",[66,746,747],{"class":114}," -DENABLE_SSE2=ON",[66,749,750],{"class":114}," -DENABLE_SSE3=ON",[66,752,753],{"class":114}," -DWITH_TBB=ON",[66,755,756],{"class":114}," -DWITH_1394=ON",[66,758,759],{"class":114}," -DWITH_V4L=ON",[66,761,762],{"class":114}," -DWITH_OPENGL=ON",[66,764,765],{"class":114},"  -DWITH_GTK=ON",[66,767,768],{"class":114}," -DWITH_JASPER=ON",[66,770,771],{"class":114}," -DWITH_JPEG=ON",[66,773,774],{"class":114}," -DWITH_PNG=ON",[66,776,777],{"class":114}," -DWITH_TIFF=ON",[66,779,780],{"class":114},"  -DWITH_OPENEXR=ON",[66,782,783],{"class":114}," -DWITH_PVAPI=ON",[66,785,786],{"class":114},"   -DWITH_EIGEN=ON",[66,788,789],{"class":114}," -DCMAKE_SKIP_RPATH=ON",[66,791,733],{"class":114},[66,793,794],{"class":76}," WITH_CUDA=ON",[66,796,733],{"class":114},[66,798,799],{"class":76}," ENABLE_FAST_MATH=",[66,801,461],{"class":114},[66,803,733],{"class":114},[66,805,806],{"class":76}," CUDA_FAST_MATH=",[66,808,461],{"class":114},[66,810,733],{"class":114},[66,812,813],{"class":76}," WITH_CUBLAS=",[66,815,461],{"class":114},[66,817,818],{"class":114}," -DWITH_IPP=ON",[66,820,733],{"class":114},[66,822,823],{"class":76}," CUDA_GENERATION=Auto",[66,825,733],{"class":114},[66,827,828],{"class":76}," WITH_FFMPEG=ON",[66,830,831],{"class":76},"  ..\u002F\n",[17,833,834],{},"J'active lors de la compilation le maximum d'optimisation dont CUDA. J'active également FFMPEG sans lequel le nombre de fichier reconnu baisse énormément sur ma machine. Après\navoir lancé cmake j'obtiens le résultat suivant :",[56,836,841],{"className":837,"code":839,"language":840},[838],"language-text","-- General configuration for OpenCV 2.4.13.1 =====================================\n--   Version control:               2.4.13.1-48-gac118ae\n--\n--   Platform:\n--     Host:                        Linux 3.16.0-4-amd64 x86_64\n--     CMake:                       3.6.2\n--     CMake generator:             Unix Makefiles\n--     CMake build tool:            \u002Fusr\u002Fbin\u002Fmake\n--     Configuration:               RELEASE\n--\n--   C\u002FC++:\n--     Built as dynamic libs?:      YES\n--     C++ Compiler:                \u002Fusr\u002Fbin\u002Fc++  (ver 4.9.2)\n--     C++ flags (Release):         -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -Wno-array-bounds -Wno-aggressive-loop-optimizations -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -ffunction-sections -O3 -DNDEBUG  -DNDEBUG\n--     C++ flags (Debug):           -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -Wno-array-bounds -Wno-aggressive-loop-optimizations -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -ffunction-sections -g  -O0 -DDEBUG -D_DEBUG\n--     C Compiler:                  \u002Fusr\u002Fbin\u002Fcc\n--     C flags (Release):           -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -Wno-comment -Wno-array-bounds -Wno-aggressive-loop-optimizations -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -ffunction-sections -O3 -DNDEBUG  -DNDEBUG\n--     C flags (Debug):             -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -Wno-comment -Wno-array-bounds -Wno-aggressive-loop-optimizations -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -ffunction-sections -g  -O0 -DDEBUG -D_DEBUG\n--     Linker flags (Release):\n--     Linker flags (Debug):\n--     ccache:                      NO\n--     Precompiled headers:         YES\n--\n--   OpenCV modules:\n--     To be built:                 core flann imgproc highgui features2d calib3d ml video legacy objdetect photo gpu ocl nonfree contrib java python stitching superres ts videostab\n--     Disabled:                    world\n--     Disabled by dependency:      -\n--     Unavailable:                 androidcamera dynamicuda viz\n--\n--   GUI:\n--     QT:                          NO\n--     GTK+ 2.x:                    YES (ver 2.24.25)\n--     GThread :                    YES (ver 2.42.1)\n--     GtkGlExt:                    NO\n--     OpenGL support:              NO\n--     VTK support:                 NO\n--\n--   Media I\u002FO:\n--     ZLib:                        \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002Flibz.so (ver 1.2.8)\n--     JPEG:                        \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002Flibjpeg.so (ver )\n--     PNG:                         \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002Flibpng.so (ver 1.2.50)\n--     TIFF:                        \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002Flibtiff.so (ver 42 - 4.0.3)\n--     JPEG 2000:                   \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002Flibjasper.so (ver 1.900.1)\n--     OpenEXR:                     \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002FlibImath.so \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002FlibIlmImf.so \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002FlibIex.so \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002FlibHalf.so \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002FlibIlmThread.so (ver 1.6.1)\n--\n--   Video I\u002FO:\n--     DC1394 1.x:                  NO\n--     DC1394 2.x:                  YES (ver 2.2.3)\n--     FFMPEG:                      YES\n--       codec:                     YES (ver 56.1.0)\n--       format:                    YES (ver 56.1.0)\n--       util:                      YES (ver 54.3.0)\n--       swscale:                   YES (ver 3.0.0)\n--       resample:                  YES (ver 2.1.0)\n--       gentoo-style:              YES\n--     GStreamer:                   NO\n--     OpenNI:                      NO\n--     OpenNI PrimeSensor Modules:  NO\n--     PvAPI:                       NO\n--     GigEVisionSDK:               NO\n--     UniCap:                      NO\n--     UniCap ucil:                 NO\n--     V4L\u002FV4L2:                    NO\u002FYES\n--     XIMEA:                       NO\n--     Xine:                        NO\n--\n--   Other third-party libraries:\n--     Use IPP:                     IPP not found\n--     Use Eigen:                   NO\n--     Use TBB:                     NO\n--     Use OpenMP:                  NO\n--     Use GCD                      NO\n--     Use Concurrency              NO\n--     Use C=:                      NO\n--     Use Cuda:                    YES (ver 7.5)\n--     Use OpenCL:                  YES\n--\n--   NVIDIA CUDA\n--     Use CUFFT:                   YES\n--     Use CUBLAS:                  YES\n--     USE NVCUVID:                 NO\n--     NVIDIA GPU arch:             21\n--     NVIDIA PTX archs:\n--     Use fast math:               YES\n--     Tiny gpu module:             NO\n--\n--   OpenCL:\n--     Version:                     dynamic\n--     Include path:                \u002Fhome\u002Fphoenix\u002FDeveloppement\u002FExternalSoftware\u002Fopencv\u002F3rdparty\u002Finclude\u002Fopencl\u002F1.2\n--     Use AMD FFT:                 NO\n--     Use AMD BLAS:                NO\n--\n--   Python:\n--     Interpreter:                 \u002Fusr\u002Fbin\u002Fpython2 (ver 2.7.10)\n--     Libraries:                   \u002Fusr\u002Flib\u002Fx86_64-linux-gnu\u002Flibpython2.7.so (ver 2.7.10rc1)\n--     numpy:                       \u002Fusr\u002Flib\u002Fpython2.7\u002Fdist-packages\u002Fnumpy\u002Fcore\u002Finclude (ver 1.8.2)\n--     packages path:               lib\u002Fpython2.7\u002Fdist-packages\n--\n--   Java:\n--     ant:                         \u002Fusr\u002Fbin\u002Fant (ver 1.9.4)\n--     JNI:                         \u002Fusr\u002Flib\u002Fjvm\u002Fjava-7-openjdk-amd64\u002Finclude \u002Fusr\u002Flib\u002Fjvm\u002Fjava-7-openjdk-amd64\u002Finclude \u002Fusr\u002Flib\u002Fjvm\u002Fjava-7-openjdk-amd64\u002Finclude\n--     Java tests:                  YES\n--\n--   Documentation:\n--     Build Documentation:         NO\n--     Sphinx:                      NO\n--     PdfLaTeX compiler:           \u002Fusr\u002Fbin\u002Fpdflatex\n--     Doxygen:                     YES (\u002Fusr\u002Fbin\u002Fdoxygen)\n--\n--   Tests and samples:\n--     Tests:                       YES\n--     Performance tests:           YES\n--     C\u002FC++ Examples:              NO\n--\n--   Install path:                  \u002Fhome\u002Fphoenix\u002Fusr\u002Flocal\n--\n--   cvconfig.h is in:              \u002Fhome\u002Fphoenix\u002FDeveloppement\u002FExternalSoftware\u002Fopencv\u002Fbuild\n-- -----------------------------------------------------------------\n","text",[63,842,839],{"__ignoreMap":61},[17,844,845,846,849,850,853,854,857],{},"Pour que la compilation se déroule sans problème, il vous faudra installer certains paquets sur votre distribution. Sur Debian Jessie, j'ai installé ",[63,847,848],{},"nvidia-cuda-toolkit"," en\nversion ",[63,851,852],{},"7.5.18-4~bpo8+1",". Comme vous pouvez les voir c'est une version qui provient du repository de backports. La version ",[63,855,856],{},"6.0.37-5"," ne me permettait pas d'activer CUDA. J'ai\ndonc du monter l'ensemble du driver propriétaire sur mon poste de développement.",[17,859,860],{},"Rasssurez-vous, si vous ne voulez pas utiliser les backports ou ne pas utiliser de driver propriétaire, vous pouvez tester le programme dans sa version CPU. :)",[17,862,863],{},"Voici comment le code a été ré-écrit pour utiliser le GPU à la place du CPU:",[56,865,867],{"className":214,"code":866,"language":216,"meta":61,"style":61},"struct BufferPSNR {                                    \u002F\u002F Optimized GPU versions\n    \u002F\u002F Data allocations are very expensive on GPU. Use a buffer to solve: allocate once reuse later.\n    cv::gpu::GpuMat gF1, gF2, gI1, gI2, gs, t1,t2;\n\n    cv::gpu::GpuMat buf;\n};\n\ndouble getPSNR_GPU_optimized(const cv::Mat& F1, const cv::Mat& F2, BufferPSNR& b) {\n    b.gF1.upload(F1);\n    b.gF2.upload(F2);\n\n    cv::gpu::resize(b.gF1, b.gI1, cv::Size(160, 120));\n    cv::gpu::resize(b.gF2, b.gI2, cv::Size(160, 120));\n\n    b.gI1.convertTo(b.t1, CV_32F);\n    b.gI2.convertTo(b.t2, CV_32F);\n\n    cv::gpu::absdiff(b.t1.reshape(1), b.t2.reshape(1), b.gs);\n    cv::gpu::multiply(b.gs, b.gs, b.gs);\n\n    double sse = cv::gpu::sum(b.gs, b.buf)[0];\n\n    if( sse \u003C= 1e-10) \u002F\u002F for small values return zero\n        return std::numeric_limits\u003Cdouble>::infinity();\n    else {\n        double mse = sse \u002F(double)(F1.channels() * F1.total());\n        double psnr = 10.0*log10((255*255)\u002Fmse);\n        return psnr;\n    }\n}\n",[63,868,869,883,888,893,897,902,907,911,954,972,988,992,1037,1078,1082,1106,1129,1133,1189,1226,1230,1272,1276,1299,1318,1326,1365,1396,1403,1408],{"__ignoreMap":61},[66,870,871,874,877,880],{"class":68,"line":69},[66,872,873],{"class":223},"struct",[66,875,876],{"class":240}," BufferPSNR",[66,878,879],{"class":230}," {",[66,881,882],{"class":351},"                                    \u002F\u002F Optimized GPU versions\n",[66,884,885],{"class":68,"line":80},[66,886,887],{"class":351},"    \u002F\u002F Data allocations are very expensive on GPU. Use a buffer to solve: allocate once reuse later.\n",[66,889,890],{"class":68,"line":89},[66,891,892],{"class":230},"    cv::gpu::GpuMat gF1, gF2, gI1, gI2, gs, t1,t2;\n",[66,894,895],{"class":68,"line":279},[66,896,276],{"emptyLinePlaceholder":275},[66,898,899],{"class":68,"line":307},[66,900,901],{"class":230},"    cv::gpu::GpuMat buf;\n",[66,903,904],{"class":68,"line":329},[66,905,906],{"class":230},"};\n",[66,908,909],{"class":68,"line":334},[66,910,276],{"emptyLinePlaceholder":275},[66,912,913,915,918,920,922,924,926,928,930,932,934,936,938,940,942,944,947,949,952],{"class":68,"line":340},[66,914,224],{"class":223},[66,916,917],{"class":72}," getPSNR_GPU_optimized",[66,919,231],{"class":230},[66,921,234],{"class":223},[66,923,237],{"class":230},[66,925,241],{"class":240},[66,927,244],{"class":223},[66,929,248],{"class":247},[66,931,251],{"class":230},[66,933,234],{"class":223},[66,935,237],{"class":230},[66,937,241],{"class":240},[66,939,244],{"class":223},[66,941,262],{"class":247},[66,943,251],{"class":230},[66,945,946],{"class":240},"BufferPSNR",[66,948,244],{"class":223},[66,950,951],{"class":247}," b",[66,953,265],{"class":230},[66,955,956,959,961,964,966,969],{"class":68,"line":355},[66,957,958],{"class":240},"    b",[66,960,44],{"class":230},[66,962,963],{"class":240},"gF1",[66,965,44],{"class":230},[66,967,968],{"class":72},"upload",[66,970,971],{"class":230},"(F1);\n",[66,973,974,976,978,981,983,985],{"class":68,"line":372},[66,975,958],{"class":240},[66,977,44],{"class":230},[66,979,980],{"class":240},"gF2",[66,982,44],{"class":230},[66,984,968],{"class":72},[66,986,987],{"class":230},"(F2);\n",[66,989,990],{"class":68,"line":395},[66,991,276],{"emptyLinePlaceholder":275},[66,993,994,996,999,1002,1004,1006,1009,1011,1013,1015,1017,1019,1022,1025,1027,1029,1031,1033,1035],{"class":68,"line":400},[66,995,282],{"class":230},[66,997,998],{"class":240},"gpu",[66,1000,1001],{"class":230},"::",[66,1003,285],{"class":72},[66,1005,231],{"class":230},[66,1007,1008],{"class":240},"b",[66,1010,44],{"class":230},[66,1012,963],{"class":437},[66,1014,251],{"class":230},[66,1016,1008],{"class":240},[66,1018,44],{"class":230},[66,1020,1021],{"class":437},"gI1",[66,1023,1024],{"class":230},", cv::",[66,1026,291],{"class":72},[66,1028,231],{"class":230},[66,1030,296],{"class":114},[66,1032,251],{"class":230},[66,1034,301],{"class":114},[66,1036,304],{"class":230},[66,1038,1039,1041,1043,1045,1047,1049,1051,1053,1055,1057,1059,1061,1064,1066,1068,1070,1072,1074,1076],{"class":68,"line":416},[66,1040,282],{"class":230},[66,1042,998],{"class":240},[66,1044,1001],{"class":230},[66,1046,285],{"class":72},[66,1048,231],{"class":230},[66,1050,1008],{"class":240},[66,1052,44],{"class":230},[66,1054,980],{"class":437},[66,1056,251],{"class":230},[66,1058,1008],{"class":240},[66,1060,44],{"class":230},[66,1062,1063],{"class":437},"gI2",[66,1065,1024],{"class":230},[66,1067,291],{"class":72},[66,1069,231],{"class":230},[66,1071,296],{"class":114},[66,1073,251],{"class":230},[66,1075,301],{"class":114},[66,1077,304],{"class":230},[66,1079,1080],{"class":68,"line":421},[66,1081,276],{"emptyLinePlaceholder":275},[66,1083,1084,1086,1088,1090,1092,1094,1096,1098,1100,1103],{"class":68,"line":485},[66,1085,958],{"class":240},[66,1087,44],{"class":230},[66,1089,1021],{"class":240},[66,1091,44],{"class":230},[66,1093,363],{"class":72},[66,1095,231],{"class":230},[66,1097,1008],{"class":240},[66,1099,44],{"class":230},[66,1101,1102],{"class":437},"t1",[66,1104,1105],{"class":230},", CV_32F);\n",[66,1107,1108,1110,1112,1114,1116,1118,1120,1122,1124,1127],{"class":68,"line":490},[66,1109,958],{"class":240},[66,1111,44],{"class":230},[66,1113,1063],{"class":240},[66,1115,44],{"class":230},[66,1117,363],{"class":72},[66,1119,231],{"class":230},[66,1121,1008],{"class":240},[66,1123,44],{"class":230},[66,1125,1126],{"class":437},"t2",[66,1128,1105],{"class":230},[66,1130,1131],{"class":68,"line":520},[66,1132,276],{"emptyLinePlaceholder":275},[66,1134,1135,1137,1139,1141,1143,1145,1147,1149,1151,1153,1156,1158,1160,1163,1165,1167,1169,1171,1173,1175,1177,1179,1181,1183,1186],{"class":68,"line":546},[66,1136,282],{"class":230},[66,1138,998],{"class":240},[66,1140,1001],{"class":230},[66,1142,345],{"class":72},[66,1144,231],{"class":230},[66,1146,1008],{"class":240},[66,1148,44],{"class":230},[66,1150,1102],{"class":240},[66,1152,44],{"class":230},[66,1154,1155],{"class":72},"reshape",[66,1157,231],{"class":230},[66,1159,461],{"class":114},[66,1161,1162],{"class":230},"), ",[66,1164,1008],{"class":240},[66,1166,44],{"class":230},[66,1168,1126],{"class":240},[66,1170,44],{"class":230},[66,1172,1155],{"class":72},[66,1174,231],{"class":230},[66,1176,461],{"class":114},[66,1178,1162],{"class":230},[66,1180,1008],{"class":240},[66,1182,44],{"class":230},[66,1184,1185],{"class":437},"gs",[66,1187,1188],{"class":230},");\n",[66,1190,1191,1193,1195,1197,1200,1202,1204,1206,1208,1210,1212,1214,1216,1218,1220,1222,1224],{"class":68,"line":558},[66,1192,282],{"class":230},[66,1194,998],{"class":240},[66,1196,1001],{"class":230},[66,1198,1199],{"class":72},"multiply",[66,1201,231],{"class":230},[66,1203,1008],{"class":240},[66,1205,44],{"class":230},[66,1207,1185],{"class":437},[66,1209,251],{"class":230},[66,1211,1008],{"class":240},[66,1213,44],{"class":230},[66,1215,1185],{"class":437},[66,1217,251],{"class":230},[66,1219,1008],{"class":240},[66,1221,44],{"class":230},[66,1223,1185],{"class":437},[66,1225,1188],{"class":230},[66,1227,1228],{"class":68,"line":607},[66,1229,276],{"emptyLinePlaceholder":275},[66,1231,1232,1234,1236,1238,1240,1242,1244,1247,1249,1251,1253,1255,1257,1259,1261,1264,1267,1269],{"class":68,"line":645},[66,1233,424],{"class":223},[66,1235,427],{"class":230},[66,1237,378],{"class":223},[66,1239,237],{"class":230},[66,1241,998],{"class":240},[66,1243,1001],{"class":230},[66,1245,1246],{"class":72},"sum",[66,1248,231],{"class":230},[66,1250,1008],{"class":240},[66,1252,44],{"class":230},[66,1254,1185],{"class":437},[66,1256,251],{"class":230},[66,1258,1008],{"class":240},[66,1260,44],{"class":230},[66,1262,1263],{"class":437},"buf",[66,1265,1266],{"class":230},")[",[66,1268,444],{"class":114},[66,1270,1271],{"class":230},"];\n",[66,1273,1274],{"class":68,"line":653},[66,1275,276],{"emptyLinePlaceholder":275},[66,1277,1279,1281,1283,1285,1287,1289,1291,1293,1296],{"class":68,"line":1278},23,[66,1280,493],{"class":223},[66,1282,496],{"class":230},[66,1284,499],{"class":223},[66,1286,502],{"class":114},[66,1288,505],{"class":437},[66,1290,508],{"class":230},[66,1292,511],{"class":114},[66,1294,1295],{"class":230},")",[66,1297,1298],{"class":351}," \u002F\u002F for small values return zero\n",[66,1300,1302,1304,1306,1308,1310,1312,1314,1316],{"class":68,"line":1301},24,[66,1303,523],{"class":223},[66,1305,526],{"class":230},[66,1307,529],{"class":240},[66,1309,532],{"class":230},[66,1311,224],{"class":223},[66,1313,537],{"class":230},[66,1315,540],{"class":72},[66,1317,543],{"class":230},[66,1319,1321,1324],{"class":68,"line":1320},25,[66,1322,1323],{"class":223},"    else",[66,1325,555],{"class":230},[66,1327,1329,1331,1334,1336,1338,1340,1342,1344,1346,1349,1351,1353,1355,1357,1359,1361,1363],{"class":68,"line":1328},26,[66,1330,561],{"class":223},[66,1332,1333],{"class":230}," mse ",[66,1335,378],{"class":223},[66,1337,427],{"class":230},[66,1339,571],{"class":223},[66,1341,231],{"class":230},[66,1343,224],{"class":223},[66,1345,579],{"class":230},[66,1347,1348],{"class":240},"F1",[66,1350,44],{"class":230},[66,1352,587],{"class":72},[66,1354,590],{"class":230},[66,1356,593],{"class":223},[66,1358,248],{"class":240},[66,1360,44],{"class":230},[66,1362,601],{"class":72},[66,1364,604],{"class":230},[66,1366,1368,1370,1372,1374,1376,1378,1381,1383,1385,1387,1389,1391,1393],{"class":68,"line":1367},27,[66,1369,561],{"class":223},[66,1371,612],{"class":230},[66,1373,378],{"class":223},[66,1375,617],{"class":114},[66,1377,593],{"class":223},[66,1379,1380],{"class":72},"log10",[66,1382,626],{"class":230},[66,1384,629],{"class":114},[66,1386,593],{"class":223},[66,1388,629],{"class":114},[66,1390,1295],{"class":230},[66,1392,571],{"class":223},[66,1394,1395],{"class":230},"mse);\n",[66,1397,1399,1401],{"class":68,"line":1398},28,[66,1400,523],{"class":223},[66,1402,650],{"class":230},[66,1404,1406],{"class":68,"line":1405},29,[66,1407,656],{"class":230},[66,1409,1411],{"class":68,"line":1410},30,[66,1412,1413],{"class":230},"}\n",[17,1415,1416,1417,1419,1420,1423],{},"L'utilisation de la structure ",[63,1418,946],{}," permet de ne pas perdre de performance lors de l'initialisation relativement lourde des objets ",[63,1421,1422],{},"GpuMat",". Sans cela, l'utilisation du Gpu\nserait moins performant que la version Cpu.",[12,1425,1427],{"id":1426},"lexpérience","L'expérience",[17,1429,1430],{},"Maintenant place à l'expérience. Nous allons lancer notre programme sur notre jeu d'essai comprenant les vidéos issue des DVD, ainsi que les vidéos recompressées pour l'expérience.\nSi l'expérence se déroule bien l'algorithme devrait nous detecter les fichiers dupliqués, ainsi que les fichiers recompressés.",[1432,1433,1435],"h2",{"id":1434},"lancement-et-selection-des-dossiers","Lancement et selection des dossiers",[17,1437,1438],{},"La première étape est la sélection des dossiers que l'on souhaite comparer. Le programme ira lire récursivement l'ensemble des dossiers pour y trouver l'ensemble des fichiers\nvidéos.",[17,1440,1441],{},"La sélection d'un projet provient de mon envie de départ de pouvoir enregistrer l'avancement du projet au fur et à mesure. Cette étape n'a pas été réalisée mais l'existance du mode\nprojet existe toujours.",[17,1443,1444],{},[1445,1446],"img",{"alt":1447,"src":1448},"Selection du projet","\u002FProgrammation\u002Ffind-similarity\u002Ffind-similarity-1.png",[17,1450,1451],{},"Une fois le dossier projet choisi, il faut sélectionner la liste des dossiers contenant les vidéos et lancer le programme ...",[1432,1453,1455],{"id":1454},"comparaison-des-vidéos","Comparaison des vidéos",[17,1457,1458,1459,44],{},"Dans cette étape le programme compare l'ensemble des vidéos présentes dans les dossiers. L'ensemble du processus tourne dans des threads afin de ne pas figer l'IHM, grâce à l'API\n",[63,1460,1461],{},"QtConcurrent",[17,1463,1464,1468],{},[1445,1465],{"alt":1466,"src":1467},"Recherche","\u002FProgrammation\u002Ffind-similarity\u002Ffind-similarity-2.png",[1445,1469],{"alt":1470,"src":1471},"Recherche encore","\u002FProgrammation\u002Ffind-similarity\u002Ffind-similarity-3.png",[17,1473,1474],{},"Les étapes de la recherche sont donc :",[162,1476,1477,1480,1483,1486,1489],{},[165,1478,1479],{},"Constitution de la liste des fichiers",[165,1481,1482],{},"Récupération des méta-données",[165,1484,1485],{},"Création de la liste des paires de fichiers (en filtrant sur la durée)",[165,1487,1488],{},"Calcul du PSNR pour chaque paire de fichiers",[165,1490,1491],{},"Filtrage pour ne garder que les paires de fichiers dont le PSNR est supérieur à 30 db.",[17,1493,1494,1495,1497,1498,1500,1501,1504,1505,1508],{},"Lors de mon développement je me suis basé sur l'API ",[63,1496,1461],{}," pour faire les différentes étapes. Faisant beaucoup de développement NodeJS ces derniers temps je suis habitué à\nl'utilisation des promesses et de leur enchainement pour faire des processus complexes. J'ai trouvé dommage de ne pas retrouver la même chose dans l'API ",[63,1499,1461],{},". Pour\nreproduire un équivalent, lorsqu'un ",[63,1502,1503],{},"QFuture","se termine, le signal émis par ",[63,1506,1507],{},"QFutureWatcher"," est récupérer par un SLOT du moteur qui s'occupe de lancer l'étape suivante.",[1432,1510,1512],{"id":1511},"la-page-de-résultat","La page de résultat",[17,1514,1515],{},"La page de résultat liste les vidéos considérées identiques suite à l'étude d'une des images. Un coup d'oeil visuel permet alors de se faire un avis sur la question, et de\nsupprimer la vidéo que l'on souhaite.",[17,1517,1518],{},[1445,1519],{"alt":1520,"src":1521},"Résultat 1","\u002FProgrammation\u002Ffind-similarity\u002Ffind-similarity-4.png",[17,1523,1524],{},"Comme on peut le voir le programme retrouve les vidéos dont l'image est identique, ainsi que les films qui ont été redimensionnés sans trop de soucis.\nLe problème se situe alors au niveau du bruit qui est généré. Plusieurs films sont considérés comme proches alors que complètement différents. Pour régler ce problème, comparer\nplusieurs images d'une même vidéo à des timestamps différents pourrait peut-être régler le problème.",[17,1526,1527],{},[1445,1528],{"alt":1529,"src":1530},"Résultat 2","\u002FProgrammation\u002Ffind-similarity\u002Ffind-similarity-5.png",[17,1532,1533],{},[1534,1535,1536],"strong",{},"Je vous conseille de vérifier manuellement la qualité et la similarité de chaque vidéo manuellement avant toute suppression.",[12,1538,1540],{"id":1539},"conclusion","Conclusion",[17,1542,1543],{},"En conclusion, j'ai trouvé l'expérience intéressante, et maintenant qu'elle est terminée, je vais pouvoir en tenter une autre ;). Est-ce que le programme continuera d'évoluer ?\nPourquoi pas ? Cela dépendera des PR (Pull Request) et des demandes faites par les utilisateurs, ainsi que du temps que j'ai envie de passer dessus.",[1545,1546,1547],"style",{},"html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .s_ZVi, html code.shiki .s_ZVi{--shiki-default:#E06C75;--shiki-default-font-style:italic}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}",{"title":61,"searchDepth":80,"depth":80,"links":1549},[1550,1551,1552,1553,1554,1555,1556,1557],{"id":14,"depth":89,"text":15},{"id":47,"depth":89,"text":48},{"id":156,"depth":89,"text":157},{"id":659,"depth":89,"text":660},{"id":1426,"depth":89,"text":1427},{"id":1434,"depth":80,"text":1435},{"id":1454,"depth":80,"text":1455},{"id":1511,"depth":80,"text":1512,"children":1558},[1559],{"id":1539,"depth":89,"text":1540},"Programmation","programmation","2016-12-10",{"type":9,"value":1564},[1565,1567,1569,1571,1573,1575,1579],[12,1566,15],{"id":14},[17,1568,19],{},[17,1570,22],{},[17,1572,25],{},[17,1574,28],{},[17,1576,1577],{},[32,1578,34],{},[17,1580,37,1581,44],{},[39,1582,41],{"href":41,"rel":1583},[43],"md","Lille, France",{"planet":275},"\u002Fpost\u002Ffindsimilarity",{"title":6,"description":61},"findsimilarity","posts\u002FProgrammation\u002F2016-12-10-findsimilarity",[1592,1593,1594,1595],"qt","opencv","video","debian","LR-Ko6CoDmyd4rJj7msRVs_pkiaov-yO2_RYmY_C6cE",{"id":1598,"title":1599,"author":7,"body":1600,"category":1560,"categorySlug":1561,"date":3457,"description":61,"excerpt":3458,"extension":1584,"location":1585,"meta":3499,"navigation":275,"path":3500,"published":275,"seo":3501,"slug":3502,"stem":3503,"tags":3504,"timeToRead":355,"__hash__":3505},"posts\u002Fposts\u002FProgrammation\u002F2012-07-01-cross-compilation-compiler-un-programme-pour-ms-windows-sous-gnu-linux.md","Cross-Compilation - Compiler un programme pour MS\u002FWindows sous Gnu\u002FLinux",{"type":9,"value":1601,"toc":3447},[1602,1616,1619,1622,1625,1655,1658,1664,1668,1684,1687,1713,1716,1727,1730,1749,1758,1761,1872,1875,1878,1957,1960,2017,2020,2035,2038,2070,2073,2427,2430,2726,2729,2733,2736,2739,2857,2864,2919,2926,2932,2935,2943,2949,2952,2958,2961,2972,2975,3007,3019,3315,3318,3337,3343,3345,3348,3444],[12,1603,1605,1606,1615],{"id":1604},"quest-que-la-cross-compilation1","Qu'est que la cross-compilation",[1607,1608,1609],"sup",{},[39,1610,461],{"href":1611,"ariaDescribedBy":1612,"dataFootnoteRef":61,"id":1614},"#user-content-fn-1",[1613],"footnote-label","user-content-fnref-1"," ?",[17,1617,1618],{},"La cross compilation est la possibilité sur une machine avec un matériel\nspécifique (architecture) et avec un système d'exploitation donné, de\ncompiler des programmes pour une autre architecture, ou pour un autre\nsystème d'exploitation.",[17,1620,1621],{},"Cela peut être utilisé par exemple pour compiler un programme sur votre\nordinateur de tous les jours (sous Gnu\u002FLinux, avec une architecture\ni386) à destination de votre téléphone mobile, qui lui est sous Symbian\navec un processeur ARM.",[17,1623,1624],{},"Les raisons de faire de la compilation croisée peuvent donc être\nmultiples :",[162,1626,1627,1630,1641,1652],{},[165,1628,1629],{},"Éviter de redémarrer votre machine pour compiler vos binaires.",[165,1631,1632,1633,1640],{},"Disponibilité des outils sur votre machine \u002F Indisponibilité des\noutils de compilation sur la machine de destination (on trouve\nrarement des outils de compilation sur des téléphones\nportables",[1607,1634,1635],{},[39,1636,476],{"href":1637,"ariaDescribedBy":1638,"dataFootnoteRef":61,"id":1639},"#user-content-fn-2",[1613],"user-content-fnref-2",").",[165,1642,1643,1644,1640],{},"Puissances des calculs (la compilation prendra moins de temps sur\nvotre PC de bureau que sur votre appareil mobile",[1607,1645,1646],{},[39,1647,1651],{"href":1648,"ariaDescribedBy":1649,"dataFootnoteRef":61,"id":1650},"#user-content-fn-3",[1613],"user-content-fnref-3","3",[165,1653,1654],{},"Licence : Vous voulez compiler à destination d'un système\nd'exploitation que vous ne possédez pas",[17,1656,1657],{},"Attention: La compilation croisée ne garantie pas que programme\nfonctionnera, vous devrez toujours faire quelques tests à partir d'un\némulateur ou à partir du système d'exploitation final.",[17,1659,1660,1661,44],{},"Bref, à partir du moment où vous avez besoin de compiler un programme\npour une autre architecture, ou pour un autre système d'exploitation que\nvotre machine actuelle, vous avez besoin de faire de la ",[32,1662,1663],{},"compilation\ncroisée",[12,1665,1667],{"id":1666},"de-quoi-va-parler-ce-billet","De quoi va parler ce billet ?",[17,1669,1670,1671,1674,1675,1683],{},"Ce billet ne va pas parler de la ",[32,1672,1673],{},"compilation croisée"," entre deux\narchitectures différentes, mais uniquement de la compilation croisée à\ndestination d'une machine Windows à partir d'une machine Linux. La\ncompilation croisée entre architectures pourra être vue dans un\nfutur",[1607,1676,1677],{},[39,1678,1682],{"href":1679,"ariaDescribedBy":1680,"dataFootnoteRef":61,"id":1681},"#user-content-fn-4",[1613],"user-content-fnref-4","4"," article, ou sur d'autres sites.",[17,1685,1686],{},"Afin de pouvoir faire de la compilation croisée, il vous faudra\ninstaller les outils suivants :",[162,1688,1689,1701],{},[165,1690,1691,1692,1700],{},"MinGW",[1607,1693,1694],{},[39,1695,1699],{"href":1696,"ariaDescribedBy":1697,"dataFootnoteRef":61,"id":1698},"#user-content-fn-5",[1613],"user-content-fnref-5","5"," : utilisé en tant que cross-compilateur, il nous\ngénèrera un exécutable Windows.",[165,1702,1703,1704,1712],{},"Wine",[1607,1705,1706],{},[39,1707,1711],{"href":1708,"ariaDescribedBy":1709,"dataFootnoteRef":61,"id":1710},"#user-content-fn-6",[1613],"user-content-fnref-6","6"," : Qui nous servira à vérifier l'exécutable créé.",[17,1714,1715],{},"Les différentes étapes de la constitution de ce billet seront :",[162,1717,1718,1721,1724],{},[165,1719,1720],{},"Installation des outils",[165,1722,1723],{},"Compilation d'un programme simple",[165,1725,1726],{},"Compilation d'un programme Qt simple",[12,1728,1720],{"id":1729},"installation-des-outils",[17,1731,1732,1733,1736,1737,1740,1748],{},"Nous y sommes :). Nous allons commencer par installer les outils qui\nnous permettront de faire de la compilation croisée. Sous la\ndistribution de votre choix, il vous faudra donc installer ",[63,1734,1735],{},"mingw"," ainsi\nque ",[63,1738,1739],{},"wine",[1607,1741,1742],{},[39,1743,1747],{"href":1744,"ariaDescribedBy":1745,"dataFootnoteRef":61,"id":1746},"#user-content-fn-7",[1613],"user-content-fnref-7","7",". Sous une Gnu\u002FDebian, on pourra par exemple faire :",[56,1750,1752],{"className":58,"code":1751,"language":60,"meta":61,"style":61},"> sudo aptitude install mingw32-runtime wine\n",[63,1753,1754],{"__ignoreMap":61},[66,1755,1756],{"class":68,"line":69},[66,1757,1751],{"class":230},[17,1759,1760],{},"Pour vérifier la version actuelle de mingw vous pouvez faire :",[56,1762,1764],{"className":58,"code":1763,"language":60,"meta":61,"style":61},"> i586-mingw32msvc-gcc --version\ni586-mingw32msvc-gcc (GCC) 4.2.1-sjlj (mingw32-2)\nCopyright (C) 2007 Free Software Foundation, Inc.\nThis is free software; see the source for copying conditions.  There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",[63,1765,1766,1771,1785,1793,1836],{"__ignoreMap":61},[66,1767,1768],{"class":68,"line":69},[66,1769,1770],{"class":230},"> i586-mingw32msvc-gcc --version\n",[66,1772,1773,1776,1779,1782],{"class":68,"line":80},[66,1774,1775],{"class":72},"i586-mingw32msvc-gcc",[66,1777,1778],{"class":230}," (GCC) 4.2.1-sjlj (",[66,1780,1781],{"class":72},"mingw32-2",[66,1783,1784],{"class":230},")\n",[66,1786,1787,1790],{"class":68,"line":89},[66,1788,1789],{"class":72},"Copyright",[66,1791,1792],{"class":230}," (C) 2007 Free Software Foundation, Inc.\n",[66,1794,1795,1798,1801,1804,1807,1810,1813,1816,1819,1822,1825,1828,1831,1833],{"class":68,"line":279},[66,1796,1797],{"class":72},"This",[66,1799,1800],{"class":76}," is",[66,1802,1803],{"class":76}," free",[66,1805,1806],{"class":76}," software",[66,1808,1809],{"class":230},"; ",[66,1811,1812],{"class":72},"see",[66,1814,1815],{"class":76}," the",[66,1817,1818],{"class":76}," source",[66,1820,1821],{"class":76}," for",[66,1823,1824],{"class":76}," copying",[66,1826,1827],{"class":76}," conditions.",[66,1829,1830],{"class":76},"  There",[66,1832,1800],{"class":76},[66,1834,1835],{"class":76}," NO\n",[66,1837,1838,1841,1843,1846,1849,1851,1854,1857,1860,1863,1866,1869],{"class":68,"line":307},[66,1839,1840],{"class":72},"warranty",[66,1842,1809],{"class":230},[66,1844,1845],{"class":72},"not",[66,1847,1848],{"class":76}," even",[66,1850,1821],{"class":76},[66,1852,1853],{"class":76}," MERCHANTABILITY",[66,1855,1856],{"class":76}," or",[66,1858,1859],{"class":76}," FITNESS",[66,1861,1862],{"class":76}," FOR",[66,1864,1865],{"class":76}," A",[66,1867,1868],{"class":76}," PARTICULAR",[66,1870,1871],{"class":76}," PURPOSE.\n",[12,1873,1723],{"id":1874},"compilation-dun-programme-simple",[17,1876,1877],{},"Commençons par le programme le plus simple du monde:",[56,1879,1881],{"className":214,"code":1880,"language":216,"meta":61,"style":61},"#include \u003Ciostream>\n\nint main(int argc, char** argv)\n{\n    std::cout \u003C\u003C \"Hello\" \u003C\u003C std::endl;\n    return 0;\n}\n",[63,1882,1883,1891,1895,1920,1925,1942,1953],{"__ignoreMap":61},[66,1884,1885,1888],{"class":68,"line":69},[66,1886,1887],{"class":223},"#include",[66,1889,1890],{"class":76}," \u003Ciostream>\n",[66,1892,1893],{"class":68,"line":80},[66,1894,276],{"emptyLinePlaceholder":275},[66,1896,1897,1900,1903,1905,1907,1910,1912,1915,1918],{"class":68,"line":89},[66,1898,1899],{"class":223},"int",[66,1901,1902],{"class":72}," main",[66,1904,231],{"class":230},[66,1906,1899],{"class":223},[66,1908,1909],{"class":247}," argc",[66,1911,251],{"class":230},[66,1913,1914],{"class":223},"char**",[66,1916,1917],{"class":247}," argv",[66,1919,1784],{"class":230},[66,1921,1922],{"class":68,"line":279},[66,1923,1924],{"class":230},"{\n",[66,1926,1927,1930,1933,1936,1939],{"class":68,"line":307},[66,1928,1929],{"class":230},"    std::cout ",[66,1931,1932],{"class":223},"\u003C\u003C",[66,1934,1935],{"class":76}," \"Hello\"",[66,1937,1938],{"class":223}," \u003C\u003C",[66,1940,1941],{"class":230}," std::endl;\n",[66,1943,1944,1947,1950],{"class":68,"line":329},[66,1945,1946],{"class":223},"    return",[66,1948,1949],{"class":114}," 0",[66,1951,1952],{"class":230},";\n",[66,1954,1955],{"class":68,"line":334},[66,1956,1413],{"class":230},[17,1958,1959],{},"Puis compilons :",[56,1961,1963],{"className":58,"code":1962,"language":60,"meta":61,"style":61},"> i586-mingw32msvc-g++ -o test.exe test.cpp\n> ls\ntest.c\ntest.exe\n> file test.exe\ntest.exe: PE32 executable (console) Intel 80386, for MS Windows\n",[63,1964,1965,1970,1975,1983,1990,1995],{"__ignoreMap":61},[66,1966,1967],{"class":68,"line":69},[66,1968,1969],{"class":230},"> i586-mingw32msvc-g++ -o test.exe test.cpp\n",[66,1971,1972],{"class":68,"line":80},[66,1973,1974],{"class":230},"> ls\n",[66,1976,1977,1980],{"class":68,"line":89},[66,1978,1979],{"class":83},"test",[66,1981,1982],{"class":76},".c\n",[66,1984,1985,1987],{"class":68,"line":279},[66,1986,1979],{"class":83},[66,1988,1989],{"class":76},".exe\n",[66,1991,1992],{"class":68,"line":307},[66,1993,1994],{"class":230},"> file test.exe\n",[66,1996,1997,1999,2002,2005,2008,2011,2014],{"class":68,"line":329},[66,1998,1979],{"class":83},[66,2000,2001],{"class":76},".exe:",[66,2003,2004],{"class":76}," PE32",[66,2006,2007],{"class":76}," executable",[66,2009,2010],{"class":230}," (console) Intel 80386, ",[66,2012,2013],{"class":223},"for",[66,2015,2016],{"class":230}," MS Windows\n",[17,2018,2019],{},"Voilà nous avons donc un programme à destination de Windows. Il ne nous\nreste plus qu'à le tester :",[56,2021,2023],{"className":58,"code":2022,"language":60,"meta":61,"style":61},"> wine .\u002Ftest.exe\nHello\n",[63,2024,2025,2030],{"__ignoreMap":61},[66,2026,2027],{"class":68,"line":69},[66,2028,2029],{"class":230},"> wine .\u002Ftest.exe\n",[66,2031,2032],{"class":68,"line":80},[66,2033,2034],{"class":72},"Hello\n",[17,2036,2037],{},"Et voilà, nous avons écrit un petit programme Windows, et nous l'avons\ntesté à l'aide de Wine. Généralement, on utilise l'utilisation de\nMakefile, voir même des générateurs de Makefile. Nous allons compléter\nl'exemple avec CMake. Voici donc un exemple de fichier CMake :",[56,2039,2042],{"className":2040,"code":2041,"language":730,"meta":61,"style":61},"language-cmake shiki shiki-themes one-dark-pro","project(test)\nadd_executable(test test.cpp)\n",[63,2043,2044,2055],{"__ignoreMap":61},[66,2045,2046,2049,2051,2053],{"class":68,"line":69},[66,2047,2048],{"class":223},"project",[66,2050,231],{"class":230},[66,2052,1979],{"class":223},[66,2054,1784],{"class":230},[66,2056,2057,2060,2062,2064,2067],{"class":68,"line":80},[66,2058,2059],{"class":223},"add_executable",[66,2061,231],{"class":230},[66,2063,1979],{"class":223},[66,2065,2066],{"class":223}," test",[66,2068,2069],{"class":230},".cpp)\n",[17,2071,2072],{},"Nous allons donc lancer la compilation, sous Linux :",[56,2074,2076],{"className":58,"code":2075,"language":60,"meta":61,"style":61},"> mkdir build\n> cd build\n> cmake ..\u002F\n-- The C compiler identification is GNU\n-- The CXX compiler identification is GNU\n-- Check for working C compiler: \u002Fusr\u002Flib\u002Fccache\u002Fgcc\n-- Check for working C compiler: \u002Fusr\u002Flib\u002Fccache\u002Fgcc -- works\n-- Detecting C compiler ABI info\n-- Detecting C compiler ABI info - done\n-- Check for working CXX compiler: \u002Fusr\u002Flib\u002Fccache\u002Fc++\n-- Check for working CXX compiler: \u002Fusr\u002Flib\u002Fccache\u002Fc++ -- works\n-- Detecting CXX compiler ABI info\n-- Detecting CXX compiler ABI info - done\n-- Configuring done\n-- Generating done\n-- Build files have been written to: \u002Ftmp\u002Fbuild\n> make\nScanning dependencies of target test\n[100%] Building CXX object CMakeFiles\u002Ftest.dir\u002Ftest.cpp.o\nLinking CXX executable test\n\n[100%] Built target test\n> file test\ntest: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU\u002FLinux 2.6.26, BuildID[sha1]=0xf17337fcecb8f3b6ed589d8dce8978be08f2caca, not stripped\n",[63,2077,2078,2083,2088,2093,2115,2132,2152,2175,2192,2213,2230,2251,2265,2283,2292,2301,2326,2331,2348,2353,2364,2368,2373,2378],{"__ignoreMap":61},[66,2079,2080],{"class":68,"line":69},[66,2081,2082],{"class":230},"> mkdir build\n",[66,2084,2085],{"class":68,"line":80},[66,2086,2087],{"class":230},"> cd build\n",[66,2089,2090],{"class":68,"line":89},[66,2091,2092],{"class":230},"> cmake ..\u002F\n",[66,2094,2095,2098,2101,2104,2107,2110,2112],{"class":68,"line":279},[66,2096,2097],{"class":72},"--",[66,2099,2100],{"class":76}," The",[66,2102,2103],{"class":76}," C",[66,2105,2106],{"class":76}," compiler",[66,2108,2109],{"class":76}," identification",[66,2111,1800],{"class":76},[66,2113,2114],{"class":76}," GNU\n",[66,2116,2117,2119,2121,2124,2126,2128,2130],{"class":68,"line":307},[66,2118,2097],{"class":72},[66,2120,2100],{"class":76},[66,2122,2123],{"class":76}," CXX",[66,2125,2106],{"class":76},[66,2127,2109],{"class":76},[66,2129,1800],{"class":76},[66,2131,2114],{"class":76},[66,2133,2134,2136,2139,2141,2144,2146,2149],{"class":68,"line":329},[66,2135,2097],{"class":72},[66,2137,2138],{"class":76}," Check",[66,2140,1821],{"class":76},[66,2142,2143],{"class":76}," working",[66,2145,2103],{"class":76},[66,2147,2148],{"class":76}," compiler:",[66,2150,2151],{"class":76}," \u002Fusr\u002Flib\u002Fccache\u002Fgcc\n",[66,2153,2154,2156,2158,2160,2162,2164,2166,2169,2172],{"class":68,"line":334},[66,2155,2097],{"class":72},[66,2157,2138],{"class":76},[66,2159,1821],{"class":76},[66,2161,2143],{"class":76},[66,2163,2103],{"class":76},[66,2165,2148],{"class":76},[66,2167,2168],{"class":76}," \u002Fusr\u002Flib\u002Fccache\u002Fgcc",[66,2170,2171],{"class":114}," --",[66,2173,2174],{"class":76}," works\n",[66,2176,2177,2179,2182,2184,2186,2189],{"class":68,"line":340},[66,2178,2097],{"class":72},[66,2180,2181],{"class":76}," Detecting",[66,2183,2103],{"class":76},[66,2185,2106],{"class":76},[66,2187,2188],{"class":76}," ABI",[66,2190,2191],{"class":76}," info\n",[66,2193,2194,2196,2198,2200,2202,2204,2207,2210],{"class":68,"line":355},[66,2195,2097],{"class":72},[66,2197,2181],{"class":76},[66,2199,2103],{"class":76},[66,2201,2106],{"class":76},[66,2203,2188],{"class":76},[66,2205,2206],{"class":76}," info",[66,2208,2209],{"class":76}," -",[66,2211,2212],{"class":76}," done\n",[66,2214,2215,2217,2219,2221,2223,2225,2227],{"class":68,"line":372},[66,2216,2097],{"class":72},[66,2218,2138],{"class":76},[66,2220,1821],{"class":76},[66,2222,2143],{"class":76},[66,2224,2123],{"class":76},[66,2226,2148],{"class":76},[66,2228,2229],{"class":76}," \u002Fusr\u002Flib\u002Fccache\u002Fc++\n",[66,2231,2232,2234,2236,2238,2240,2242,2244,2247,2249],{"class":68,"line":395},[66,2233,2097],{"class":72},[66,2235,2138],{"class":76},[66,2237,1821],{"class":76},[66,2239,2143],{"class":76},[66,2241,2123],{"class":76},[66,2243,2148],{"class":76},[66,2245,2246],{"class":76}," \u002Fusr\u002Flib\u002Fccache\u002Fc++",[66,2248,2171],{"class":114},[66,2250,2174],{"class":76},[66,2252,2253,2255,2257,2259,2261,2263],{"class":68,"line":400},[66,2254,2097],{"class":72},[66,2256,2181],{"class":76},[66,2258,2123],{"class":76},[66,2260,2106],{"class":76},[66,2262,2188],{"class":76},[66,2264,2191],{"class":76},[66,2266,2267,2269,2271,2273,2275,2277,2279,2281],{"class":68,"line":416},[66,2268,2097],{"class":72},[66,2270,2181],{"class":76},[66,2272,2123],{"class":76},[66,2274,2106],{"class":76},[66,2276,2188],{"class":76},[66,2278,2206],{"class":76},[66,2280,2209],{"class":76},[66,2282,2212],{"class":76},[66,2284,2285,2287,2290],{"class":68,"line":421},[66,2286,2097],{"class":72},[66,2288,2289],{"class":76}," Configuring",[66,2291,2212],{"class":76},[66,2293,2294,2296,2299],{"class":68,"line":485},[66,2295,2097],{"class":72},[66,2297,2298],{"class":76}," Generating",[66,2300,2212],{"class":76},[66,2302,2303,2305,2308,2311,2314,2317,2320,2323],{"class":68,"line":490},[66,2304,2097],{"class":72},[66,2306,2307],{"class":76}," Build",[66,2309,2310],{"class":76}," files",[66,2312,2313],{"class":76}," have",[66,2315,2316],{"class":76}," been",[66,2318,2319],{"class":76}," written",[66,2321,2322],{"class":76}," to:",[66,2324,2325],{"class":76}," \u002Ftmp\u002Fbuild\n",[66,2327,2328],{"class":68,"line":520},[66,2329,2330],{"class":230},"> make\n",[66,2332,2333,2336,2339,2342,2345],{"class":68,"line":546},[66,2334,2335],{"class":72},"Scanning",[66,2337,2338],{"class":76}," dependencies",[66,2340,2341],{"class":76}," of",[66,2343,2344],{"class":76}," target",[66,2346,2347],{"class":76}," test\n",[66,2349,2350],{"class":68,"line":558},[66,2351,2352],{"class":230},"[100%] Building CXX object CMakeFiles\u002Ftest.dir\u002Ftest.cpp.o\n",[66,2354,2355,2358,2360,2362],{"class":68,"line":607},[66,2356,2357],{"class":72},"Linking",[66,2359,2123],{"class":76},[66,2361,2007],{"class":76},[66,2363,2347],{"class":76},[66,2365,2366],{"class":68,"line":645},[66,2367,276],{"emptyLinePlaceholder":275},[66,2369,2370],{"class":68,"line":653},[66,2371,2372],{"class":230},"[100%] Built target test\n",[66,2374,2375],{"class":68,"line":1278},[66,2376,2377],{"class":230},"> file test\n",[66,2379,2380,2382,2385,2388,2391,2394,2397,2400,2403,2406,2408,2411,2414,2417,2420,2422,2424],{"class":68,"line":1301},[66,2381,1979],{"class":83},[66,2383,2384],{"class":76},":",[66,2386,2387],{"class":76}," ELF",[66,2389,2390],{"class":76}," 32-bit",[66,2392,2393],{"class":76}," LSB",[66,2395,2396],{"class":76}," executable,",[66,2398,2399],{"class":76}," Intel",[66,2401,2402],{"class":76}," 80386,",[66,2404,2405],{"class":76}," version",[66,2407,502],{"class":114},[66,2409,2410],{"class":230}," (SYSV), dynamically linked (",[66,2412,2413],{"class":72},"uses",[66,2415,2416],{"class":76}," shared",[66,2418,2419],{"class":76}," libs",[66,2421,1162],{"class":230},[66,2423,2013],{"class":223},[66,2425,2426],{"class":230}," GNU\u002FLinux 2.6.26, BuildID[sha1]=0xf17337fcecb8f3b6ed589d8dce8978be08f2caca, not stripped\n",[17,2428,2429],{},"Nous avons donc un binaire pour Gnu\u002FLinux. Recommençons donc mais avec\nWindows :",[56,2431,2433],{"className":58,"code":2432,"language":60,"meta":61,"style":61},"> cmake -DCMAKE_C_COMPILER=i586-mingw32msvc-gcc -DCMAKE_CXX_COMPILER=i586-mingw32msvc-g++ ..\u002F\n-- The C compiler identification is GNU\n-- The CXX compiler identification is GNU\n-- Check for working C compiler: \u002Fusr\u002Flib\u002Fccache\u002Fi586-mingw32msvc-gcc\n-- Check for working C compiler: \u002Fusr\u002Flib\u002Fccache\u002Fi586-mingw32msvc-gcc -- works\n-- Detecting C compiler ABI info\n-- Detecting C compiler ABI info - done\n-- Check for working CXX compiler: \u002Fusr\u002Flib\u002Fccache\u002Fi586-mingw32msvc-g++\n-- Check for working CXX compiler: \u002Fusr\u002Flib\u002Fccache\u002Fi586-mingw32msvc-g++ -- works\n-- Detecting CXX compiler ABI info\n-- Detecting CXX compiler ABI info - done\n-- Configuring done\n-- Generating done\n-- Build files have been written to: \u002Ftmp\u002Fbuild-windows\n> make\nScanning dependencies of target test\n[100%] Building CXX object CMakeFiles\u002Ftest.dir\u002Ftest.cpp.o\n\nLinking CXX executable test\n[100%] Built target test\n> file test\ntest: PE32 executable (console) Intel 80386, for MS Windows\n",[63,2434,2435,2461,2477,2493,2510,2531,2545,2563,2580,2601,2615,2633,2641,2649,2668,2672,2684,2688,2692,2702,2706,2710],{"__ignoreMap":61},[66,2436,2437,2440,2443,2445,2447,2450,2452,2455,2458],{"class":68,"line":69},[66,2438,2439],{"class":230},"> cmake ",[66,2441,2442],{"class":437},"-DCMAKE_C_COMPILER",[66,2444,378],{"class":83},[66,2446,1775],{"class":76},[66,2448,2449],{"class":437}," -DCMAKE_CXX_COMPILER",[66,2451,378],{"class":83},[66,2453,2454],{"class":76},"i586-mingw32msvc-g++",[66,2456,2457],{"class":83}," .",[66,2459,2460],{"class":76},".\u002F\n",[66,2462,2463,2465,2467,2469,2471,2473,2475],{"class":68,"line":80},[66,2464,2097],{"class":72},[66,2466,2100],{"class":76},[66,2468,2103],{"class":76},[66,2470,2106],{"class":76},[66,2472,2109],{"class":76},[66,2474,1800],{"class":76},[66,2476,2114],{"class":76},[66,2478,2479,2481,2483,2485,2487,2489,2491],{"class":68,"line":89},[66,2480,2097],{"class":72},[66,2482,2100],{"class":76},[66,2484,2123],{"class":76},[66,2486,2106],{"class":76},[66,2488,2109],{"class":76},[66,2490,1800],{"class":76},[66,2492,2114],{"class":76},[66,2494,2495,2497,2499,2501,2503,2505,2507],{"class":68,"line":279},[66,2496,2097],{"class":72},[66,2498,2138],{"class":76},[66,2500,1821],{"class":76},[66,2502,2143],{"class":76},[66,2504,2103],{"class":76},[66,2506,2148],{"class":76},[66,2508,2509],{"class":76}," \u002Fusr\u002Flib\u002Fccache\u002Fi586-mingw32msvc-gcc\n",[66,2511,2512,2514,2516,2518,2520,2522,2524,2527,2529],{"class":68,"line":307},[66,2513,2097],{"class":72},[66,2515,2138],{"class":76},[66,2517,1821],{"class":76},[66,2519,2143],{"class":76},[66,2521,2103],{"class":76},[66,2523,2148],{"class":76},[66,2525,2526],{"class":76}," \u002Fusr\u002Flib\u002Fccache\u002Fi586-mingw32msvc-gcc",[66,2528,2171],{"class":114},[66,2530,2174],{"class":76},[66,2532,2533,2535,2537,2539,2541,2543],{"class":68,"line":329},[66,2534,2097],{"class":72},[66,2536,2181],{"class":76},[66,2538,2103],{"class":76},[66,2540,2106],{"class":76},[66,2542,2188],{"class":76},[66,2544,2191],{"class":76},[66,2546,2547,2549,2551,2553,2555,2557,2559,2561],{"class":68,"line":334},[66,2548,2097],{"class":72},[66,2550,2181],{"class":76},[66,2552,2103],{"class":76},[66,2554,2106],{"class":76},[66,2556,2188],{"class":76},[66,2558,2206],{"class":76},[66,2560,2209],{"class":76},[66,2562,2212],{"class":76},[66,2564,2565,2567,2569,2571,2573,2575,2577],{"class":68,"line":340},[66,2566,2097],{"class":72},[66,2568,2138],{"class":76},[66,2570,1821],{"class":76},[66,2572,2143],{"class":76},[66,2574,2123],{"class":76},[66,2576,2148],{"class":76},[66,2578,2579],{"class":76}," \u002Fusr\u002Flib\u002Fccache\u002Fi586-mingw32msvc-g++\n",[66,2581,2582,2584,2586,2588,2590,2592,2594,2597,2599],{"class":68,"line":355},[66,2583,2097],{"class":72},[66,2585,2138],{"class":76},[66,2587,1821],{"class":76},[66,2589,2143],{"class":76},[66,2591,2123],{"class":76},[66,2593,2148],{"class":76},[66,2595,2596],{"class":76}," \u002Fusr\u002Flib\u002Fccache\u002Fi586-mingw32msvc-g++",[66,2598,2171],{"class":114},[66,2600,2174],{"class":76},[66,2602,2603,2605,2607,2609,2611,2613],{"class":68,"line":372},[66,2604,2097],{"class":72},[66,2606,2181],{"class":76},[66,2608,2123],{"class":76},[66,2610,2106],{"class":76},[66,2612,2188],{"class":76},[66,2614,2191],{"class":76},[66,2616,2617,2619,2621,2623,2625,2627,2629,2631],{"class":68,"line":395},[66,2618,2097],{"class":72},[66,2620,2181],{"class":76},[66,2622,2123],{"class":76},[66,2624,2106],{"class":76},[66,2626,2188],{"class":76},[66,2628,2206],{"class":76},[66,2630,2209],{"class":76},[66,2632,2212],{"class":76},[66,2634,2635,2637,2639],{"class":68,"line":400},[66,2636,2097],{"class":72},[66,2638,2289],{"class":76},[66,2640,2212],{"class":76},[66,2642,2643,2645,2647],{"class":68,"line":416},[66,2644,2097],{"class":72},[66,2646,2298],{"class":76},[66,2648,2212],{"class":76},[66,2650,2651,2653,2655,2657,2659,2661,2663,2665],{"class":68,"line":421},[66,2652,2097],{"class":72},[66,2654,2307],{"class":76},[66,2656,2310],{"class":76},[66,2658,2313],{"class":76},[66,2660,2316],{"class":76},[66,2662,2319],{"class":76},[66,2664,2322],{"class":76},[66,2666,2667],{"class":76}," \u002Ftmp\u002Fbuild-windows\n",[66,2669,2670],{"class":68,"line":485},[66,2671,2330],{"class":230},[66,2673,2674,2676,2678,2680,2682],{"class":68,"line":490},[66,2675,2335],{"class":72},[66,2677,2338],{"class":76},[66,2679,2341],{"class":76},[66,2681,2344],{"class":76},[66,2683,2347],{"class":76},[66,2685,2686],{"class":68,"line":520},[66,2687,2352],{"class":230},[66,2689,2690],{"class":68,"line":546},[66,2691,276],{"emptyLinePlaceholder":275},[66,2693,2694,2696,2698,2700],{"class":68,"line":558},[66,2695,2357],{"class":72},[66,2697,2123],{"class":76},[66,2699,2007],{"class":76},[66,2701,2347],{"class":76},[66,2703,2704],{"class":68,"line":607},[66,2705,2372],{"class":230},[66,2707,2708],{"class":68,"line":645},[66,2709,2377],{"class":230},[66,2711,2712,2714,2716,2718,2720,2722,2724],{"class":68,"line":653},[66,2713,1979],{"class":83},[66,2715,2384],{"class":76},[66,2717,2004],{"class":76},[66,2719,2007],{"class":76},[66,2721,2010],{"class":230},[66,2723,2013],{"class":223},[66,2725,2016],{"class":230},[17,2727,2728],{},"Nous avons donc maintenant la possibilité de compiler notre application\nmulti-platformes depuis Linux pour les systèmes Linux, mais aussi pour\nles systèmes Windows.",[12,2730,2732],{"id":2731},"compilation-dun-programme-écrit-avec-qt","Compilation d'un programme écrit avec Qt",[17,2734,2735],{},"Nous allons maintenant nous compliquer un peu la tâche en compilant un\nprogramme ayant une dépendance avec une librairie externe : Qt. Qt est\nun framework proposant une boîte à outil de classe permettant de faire\ndes interfaces graphiques mais aussi de faire des applications consoles\nrapidement.",[17,2737,2738],{},"Nous allons donc écrire le petit programme suivant, qui affiche une\nboîte de dialogue inutile, avec un bouton inutile :",[56,2740,2742],{"className":214,"code":2741,"language":216,"meta":61,"style":61},"#include \u003CQApplication>\n#include \u003CQPushButton>\n\nint main(int argc, char** argv)\n{\n    QApplication app(argc, argv);\n    QPushButton * btn = new QPushButton(\"Do nothing\");\n    btn->show();\n\n    return app.exec();\n}\n",[63,2743,2744,2751,2758,2762,2782,2786,2797,2822,2835,2839,2853],{"__ignoreMap":61},[66,2745,2746,2748],{"class":68,"line":69},[66,2747,1887],{"class":223},[66,2749,2750],{"class":76}," \u003CQApplication>\n",[66,2752,2753,2755],{"class":68,"line":80},[66,2754,1887],{"class":223},[66,2756,2757],{"class":76}," \u003CQPushButton>\n",[66,2759,2760],{"class":68,"line":89},[66,2761,276],{"emptyLinePlaceholder":275},[66,2763,2764,2766,2768,2770,2772,2774,2776,2778,2780],{"class":68,"line":279},[66,2765,1899],{"class":223},[66,2767,1902],{"class":72},[66,2769,231],{"class":230},[66,2771,1899],{"class":223},[66,2773,1909],{"class":247},[66,2775,251],{"class":230},[66,2777,1914],{"class":223},[66,2779,1917],{"class":247},[66,2781,1784],{"class":230},[66,2783,2784],{"class":68,"line":307},[66,2785,1924],{"class":230},[66,2787,2788,2791,2794],{"class":68,"line":329},[66,2789,2790],{"class":230},"    QApplication ",[66,2792,2793],{"class":72},"app",[66,2795,2796],{"class":230},"(argc, argv);\n",[66,2798,2799,2802,2804,2807,2809,2812,2815,2817,2820],{"class":68,"line":334},[66,2800,2801],{"class":230},"    QPushButton ",[66,2803,593],{"class":223},[66,2805,2806],{"class":230}," btn ",[66,2808,378],{"class":223},[66,2810,2811],{"class":223}," new",[66,2813,2814],{"class":72}," QPushButton",[66,2816,231],{"class":230},[66,2818,2819],{"class":76},"\"Do nothing\"",[66,2821,1188],{"class":230},[66,2823,2824,2827,2830,2833],{"class":68,"line":340},[66,2825,2826],{"class":240},"    btn",[66,2828,2829],{"class":230},"->",[66,2831,2832],{"class":72},"show",[66,2834,543],{"class":230},[66,2836,2837],{"class":68,"line":355},[66,2838,276],{"emptyLinePlaceholder":275},[66,2840,2841,2843,2846,2848,2851],{"class":68,"line":372},[66,2842,1946],{"class":223},[66,2844,2845],{"class":240}," app",[66,2847,44],{"class":230},[66,2849,2850],{"class":72},"exec",[66,2852,543],{"class":230},[66,2854,2855],{"class":68,"line":395},[66,2856,1413],{"class":230},[17,2858,2859,2860,2863],{},"Avec le fichier ",[63,2861,2862],{},"qmake"," associé tout simple :",[56,2865,2869],{"className":2866,"code":2867,"language":2868,"meta":61,"style":61},"language-ini shiki shiki-themes one-dark-pro","[qmake]\nTEMPLATE = app\nTARGET =\nDEPENDPATH += .\nINCLUDEPATH += .\n\n# Input\nSOURCES += test.cpp\n","ini",[63,2870,2871,2876,2887,2895,2900,2905,2909,2914],{"__ignoreMap":61},[66,2872,2873],{"class":68,"line":69},[66,2874,2875],{"class":72},"[qmake]\n",[66,2877,2878,2881,2884],{"class":68,"line":80},[66,2879,2880],{"class":223},"TEMPLATE",[66,2882,2883],{"class":230}," =",[66,2885,2886],{"class":76}," app\n",[66,2888,2889,2892],{"class":68,"line":89},[66,2890,2891],{"class":223},"TARGET",[66,2893,2894],{"class":230}," =\n",[66,2896,2897],{"class":68,"line":279},[66,2898,2899],{"class":76},"DEPENDPATH += .\n",[66,2901,2902],{"class":68,"line":307},[66,2903,2904],{"class":76},"INCLUDEPATH += .\n",[66,2906,2907],{"class":68,"line":329},[66,2908,276],{"emptyLinePlaceholder":275},[66,2910,2911],{"class":68,"line":334},[66,2912,2913],{"class":351},"# Input\n",[66,2915,2916],{"class":68,"line":340},[66,2917,2918],{"class":76},"SOURCES += test.cpp\n",[17,2920,2921,2922,2925],{},"On test la compilation à l'aide de ",[63,2923,2924],{},"qmake ; make"," et on lance le\nprogramme :",[17,2927,2928],{},[1445,2929],{"alt":2930,"src":2931},"cross-compil1","\u002FProgrammation\u002Fcross-compilation-compiler-un-programme-pour-ms-windows-sous-gnu-linux\u002Fcross-compil1.png",[17,2933,2934],{},"Maintenant que notre programme compile et fonctionne sous Gnu\u002FLinux,\nnous allons pouvoir faire le même test mais en compilant une version\nWindows. Pour cela, il va nous falloir la version Windows de Qt (nous\nn'allons pas compiler Qt, alors que la librairie existe déjà).",[17,2936,2937,2938,2942],{},"Vous pouvez commencer par télécharger la dernière version de Qt (ou\ncelle qui vous convient) à l'adresse suivante\n",[39,2939,2940],{"href":2940,"rel":2941},"http:\u002F\u002Fqt.nokia.com\u002Fproducts\u002F",[43]," et l'installer. Vous n'avez pas besoin\nde MinGW, ni de QtCreator. Vous pouvez donc télécharger directement la\nversion qui ne contient que la librairie.",[17,2944,2945],{},[1445,2946],{"alt":2947,"src":2948},"cross-compil3","\u002FProgrammation\u002Fcross-compilation-compiler-un-programme-pour-ms-windows-sous-gnu-linux\u002Fcross-compil3.png",[17,2950,2951],{},"Si à l'installation, l'application demande l'installation ou\nl'emplacement de MinGW, vous n'avez pas besoin de le renseigner, nous\nutiliserons la version Linux de MinGW.",[17,2953,2954],{},[1445,2955],{"alt":2956,"src":2957},"cross-compil2","\u002FProgrammation\u002Fcross-compilation-compiler-un-programme-pour-ms-windows-sous-gnu-linux\u002Fcross-compil2.png",[17,2959,2960],{},"Enfin nous allons faire un peu de paramétrage. Nous allons récupérer le\ndossier de specs Qt pour windows et l'adapter pour MinGW sous Linux. Les\nadaptations à faire sont :",[162,2962,2963,2966,2969],{},[165,2964,2965],{},"Utilisation de MinGW",[165,2967,2968],{},"Définition des dossiers de Qt Windows et MinGW",[165,2970,2971],{},"Suppression de l'extension .exe",[17,2973,2974],{},"Commençons par créer le fichier qmake.conf :",[56,2976,2978],{"className":58,"code":2977,"language":60,"meta":61,"style":61},"sudo cp -Rf \u002Fusr\u002Fshare\u002Fqt4\u002Fmkspecs\u002Fwin32-g++ \u002Fusr\u002Fshare\u002Fqt4\u002Fmkspecs\u002Fwin32-x-g++\nsudo nano \u002Fusr\u002Fshare\u002Fqt4\u002Fmkspecs\u002Fwin32-x-g++\u002Fqmake.conf\n",[63,2979,2980,2997],{"__ignoreMap":61},[66,2981,2982,2985,2988,2991,2994],{"class":68,"line":69},[66,2983,2984],{"class":72},"sudo",[66,2986,2987],{"class":76}," cp",[66,2989,2990],{"class":114}," -Rf",[66,2992,2993],{"class":76}," \u002Fusr\u002Fshare\u002Fqt4\u002Fmkspecs\u002Fwin32-g++",[66,2995,2996],{"class":76}," \u002Fusr\u002Fshare\u002Fqt4\u002Fmkspecs\u002Fwin32-x-g++\n",[66,2998,2999,3001,3004],{"class":68,"line":80},[66,3000,2984],{"class":72},[66,3002,3003],{"class":76}," nano",[66,3005,3006],{"class":76}," \u002Fusr\u002Fshare\u002Fqt4\u002Fmkspecs\u002Fwin32-x-g++\u002Fqmake.conf\n",[17,3008,3009,3010,3018],{},"Voici le fichier de diff",[1607,3011,3012],{},[39,3013,3017],{"href":3014,"ariaDescribedBy":3015,"dataFootnoteRef":61,"id":3016},"#user-content-fn-8",[1613],"user-content-fnref-8","8"," qui contient les choses à modifier, vous pouvez\nle récupérer et utiliser la commande patch pour reporter les\nmodifications, ou faire les modifications à la mains :",[56,3020,3024],{"className":3021,"code":3022,"language":3023,"meta":61,"style":61},"language-diff shiki shiki-themes one-dark-pro","17c17\n\u003C QMAKE_CC              = gcc\n---\n> QMAKE_CC              = i586-mingw32msvc-gcc\n30c30\n\u003C QMAKE_CXX             = g++\n---\n> QMAKE_CXX             = i586-mingw32msvc-g++\n44,46c44,46\n\u003C QMAKE_INCDIR          =\n\u003C QMAKE_INCDIR_QT               = $$[QT_INSTALL_HEADERS]\n\u003C QMAKE_LIBDIR_QT               = $$[QT_INSTALL_LIBS]\n---\n> QMAKE_INCDIR          = \u002Fusr\u002Fi586-mingw32msvc\u002Finclude\n> QMAKE_INCDIR_QT               = \u002Fhome\u002Fphoenix\u002F.wine\u002Fdrive_c\u002FQt\u002F4.8.2\u002Finclude\n> QMAKE_LIBDIR_QT               = \u002Fhome\u002Fphoenix\u002F.wine\u002Fdrive_c\u002FQt\u002F4.8.2\u002Flib\n53,54c53,54\n\u003C QMAKE_LINK            = g++\n\u003C QMAKE_LINK_C          = gcc\n---\n> QMAKE_LINK            = i586-mingw32msvc-g++\n> QMAKE_LINK_C          = i586-mingw32msvc-gcc\n77c77\n\u003C !isEmpty(QMAKE_SH) {\n---\n> #!isEmpty(QMAKE_SH) {\n88,100c88,100\n\u003C } else {\n\u003C       QMAKE_COPY              = copy \u002Fy\n\u003C       QMAKE_COPY_DIR          = xcopy \u002Fs \u002Fq \u002Fy \u002Fi\n\u003C       QMAKE_MOVE              = move\n\u003C       QMAKE_DEL_FILE          = del\n\u003C       QMAKE_MKDIR             = mkdir\n\u003C       QMAKE_DEL_DIR           = rmdir\n\u003C     QMAKE_CHK_DIR_EXISTS      = if not exist\n\u003C }\n\u003C\n\u003C QMAKE_MOC             = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc.exe\n\u003C QMAKE_UIC             = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic.exe\n\u003C QMAKE_IDC             = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc.exe\n---\n> #} else {\n> #     QMAKE_COPY              = copy \u002Fy\n> #     QMAKE_COPY_DIR          = xcopy \u002Fs \u002Fq \u002Fy \u002Fi\n> #     QMAKE_MOVE              = move\n> #     QMAKE_DEL_FILE          = del\n> #     QMAKE_MKDIR             = mkdir\n> #     QMAKE_DEL_DIR           = rmdir\n> #    QMAKE_CHK_DIR_EXISTS     = if not exist\n> #}\n>\n> QMAKE_MOC             = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc-qt4\n> QMAKE_UIC             = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic-qt4\n> QMAKE_IDC             = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc-qt4\n","diff",[63,3025,3026,3031,3036,3041,3046,3051,3056,3060,3065,3070,3075,3080,3085,3089,3094,3099,3104,3109,3114,3119,3123,3128,3133,3138,3143,3147,3152,3157,3162,3167,3172,3178,3184,3190,3196,3202,3208,3214,3220,3226,3232,3237,3243,3249,3255,3261,3267,3273,3279,3285,3291,3297,3303,3309],{"__ignoreMap":61},[66,3027,3028],{"class":68,"line":69},[66,3029,3030],{"class":230},"17c17\n",[66,3032,3033],{"class":68,"line":80},[66,3034,3035],{"class":437},"\u003C QMAKE_CC              = gcc\n",[66,3037,3038],{"class":68,"line":89},[66,3039,3040],{"class":230},"---\n",[66,3042,3043],{"class":68,"line":279},[66,3044,3045],{"class":76},"> QMAKE_CC              = i586-mingw32msvc-gcc\n",[66,3047,3048],{"class":68,"line":307},[66,3049,3050],{"class":230},"30c30\n",[66,3052,3053],{"class":68,"line":329},[66,3054,3055],{"class":437},"\u003C QMAKE_CXX             = g++\n",[66,3057,3058],{"class":68,"line":334},[66,3059,3040],{"class":230},[66,3061,3062],{"class":68,"line":340},[66,3063,3064],{"class":76},"> QMAKE_CXX             = i586-mingw32msvc-g++\n",[66,3066,3067],{"class":68,"line":355},[66,3068,3069],{"class":230},"44,46c44,46\n",[66,3071,3072],{"class":68,"line":372},[66,3073,3074],{"class":437},"\u003C QMAKE_INCDIR          =\n",[66,3076,3077],{"class":68,"line":395},[66,3078,3079],{"class":437},"\u003C QMAKE_INCDIR_QT               = $$[QT_INSTALL_HEADERS]\n",[66,3081,3082],{"class":68,"line":400},[66,3083,3084],{"class":437},"\u003C QMAKE_LIBDIR_QT               = $$[QT_INSTALL_LIBS]\n",[66,3086,3087],{"class":68,"line":416},[66,3088,3040],{"class":230},[66,3090,3091],{"class":68,"line":421},[66,3092,3093],{"class":76},"> QMAKE_INCDIR          = \u002Fusr\u002Fi586-mingw32msvc\u002Finclude\n",[66,3095,3096],{"class":68,"line":485},[66,3097,3098],{"class":76},"> QMAKE_INCDIR_QT               = \u002Fhome\u002Fphoenix\u002F.wine\u002Fdrive_c\u002FQt\u002F4.8.2\u002Finclude\n",[66,3100,3101],{"class":68,"line":490},[66,3102,3103],{"class":76},"> QMAKE_LIBDIR_QT               = \u002Fhome\u002Fphoenix\u002F.wine\u002Fdrive_c\u002FQt\u002F4.8.2\u002Flib\n",[66,3105,3106],{"class":68,"line":520},[66,3107,3108],{"class":230},"53,54c53,54\n",[66,3110,3111],{"class":68,"line":546},[66,3112,3113],{"class":437},"\u003C QMAKE_LINK            = g++\n",[66,3115,3116],{"class":68,"line":558},[66,3117,3118],{"class":437},"\u003C QMAKE_LINK_C          = gcc\n",[66,3120,3121],{"class":68,"line":607},[66,3122,3040],{"class":230},[66,3124,3125],{"class":68,"line":645},[66,3126,3127],{"class":76},"> QMAKE_LINK            = i586-mingw32msvc-g++\n",[66,3129,3130],{"class":68,"line":653},[66,3131,3132],{"class":76},"> QMAKE_LINK_C          = i586-mingw32msvc-gcc\n",[66,3134,3135],{"class":68,"line":1278},[66,3136,3137],{"class":230},"77c77\n",[66,3139,3140],{"class":68,"line":1301},[66,3141,3142],{"class":437},"\u003C !isEmpty(QMAKE_SH) {\n",[66,3144,3145],{"class":68,"line":1320},[66,3146,3040],{"class":230},[66,3148,3149],{"class":68,"line":1328},[66,3150,3151],{"class":76},"> #!isEmpty(QMAKE_SH) {\n",[66,3153,3154],{"class":68,"line":1367},[66,3155,3156],{"class":230},"88,100c88,100\n",[66,3158,3159],{"class":68,"line":1398},[66,3160,3161],{"class":437},"\u003C } else {\n",[66,3163,3164],{"class":68,"line":1405},[66,3165,3166],{"class":437},"\u003C       QMAKE_COPY              = copy \u002Fy\n",[66,3168,3169],{"class":68,"line":1410},[66,3170,3171],{"class":437},"\u003C       QMAKE_COPY_DIR          = xcopy \u002Fs \u002Fq \u002Fy \u002Fi\n",[66,3173,3175],{"class":68,"line":3174},31,[66,3176,3177],{"class":437},"\u003C       QMAKE_MOVE              = move\n",[66,3179,3181],{"class":68,"line":3180},32,[66,3182,3183],{"class":437},"\u003C       QMAKE_DEL_FILE          = del\n",[66,3185,3187],{"class":68,"line":3186},33,[66,3188,3189],{"class":437},"\u003C       QMAKE_MKDIR             = mkdir\n",[66,3191,3193],{"class":68,"line":3192},34,[66,3194,3195],{"class":437},"\u003C       QMAKE_DEL_DIR           = rmdir\n",[66,3197,3199],{"class":68,"line":3198},35,[66,3200,3201],{"class":437},"\u003C     QMAKE_CHK_DIR_EXISTS      = if not exist\n",[66,3203,3205],{"class":68,"line":3204},36,[66,3206,3207],{"class":437},"\u003C }\n",[66,3209,3211],{"class":68,"line":3210},37,[66,3212,3213],{"class":437},"\u003C\n",[66,3215,3217],{"class":68,"line":3216},38,[66,3218,3219],{"class":437},"\u003C QMAKE_MOC             = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc.exe\n",[66,3221,3223],{"class":68,"line":3222},39,[66,3224,3225],{"class":437},"\u003C QMAKE_UIC             = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic.exe\n",[66,3227,3229],{"class":68,"line":3228},40,[66,3230,3231],{"class":437},"\u003C QMAKE_IDC             = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc.exe\n",[66,3233,3235],{"class":68,"line":3234},41,[66,3236,3040],{"class":230},[66,3238,3240],{"class":68,"line":3239},42,[66,3241,3242],{"class":76},"> #} else {\n",[66,3244,3246],{"class":68,"line":3245},43,[66,3247,3248],{"class":76},"> #     QMAKE_COPY              = copy \u002Fy\n",[66,3250,3252],{"class":68,"line":3251},44,[66,3253,3254],{"class":76},"> #     QMAKE_COPY_DIR          = xcopy \u002Fs \u002Fq \u002Fy \u002Fi\n",[66,3256,3258],{"class":68,"line":3257},45,[66,3259,3260],{"class":76},"> #     QMAKE_MOVE              = move\n",[66,3262,3264],{"class":68,"line":3263},46,[66,3265,3266],{"class":76},"> #     QMAKE_DEL_FILE          = del\n",[66,3268,3270],{"class":68,"line":3269},47,[66,3271,3272],{"class":76},"> #     QMAKE_MKDIR             = mkdir\n",[66,3274,3276],{"class":68,"line":3275},48,[66,3277,3278],{"class":76},"> #     QMAKE_DEL_DIR           = rmdir\n",[66,3280,3282],{"class":68,"line":3281},49,[66,3283,3284],{"class":76},"> #    QMAKE_CHK_DIR_EXISTS     = if not exist\n",[66,3286,3288],{"class":68,"line":3287},50,[66,3289,3290],{"class":76},"> #}\n",[66,3292,3294],{"class":68,"line":3293},51,[66,3295,3296],{"class":76},">\n",[66,3298,3300],{"class":68,"line":3299},52,[66,3301,3302],{"class":76},"> QMAKE_MOC             = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc-qt4\n",[66,3304,3306],{"class":68,"line":3305},53,[66,3307,3308],{"class":76},"> QMAKE_UIC             = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic-qt4\n",[66,3310,3312],{"class":68,"line":3311},54,[66,3313,3314],{"class":76},"> QMAKE_IDC             = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc-qt4\n",[17,3316,3317],{},"Une fois terminé on peut compiler et lancer l'application de la manière\nsuivante :",[56,3319,3321],{"className":58,"code":3320,"language":60,"meta":61,"style":61},"> qmake-qt4 -spec win32-x-g++\n> make\n> wine .\u002Frelease\u002Ftest.exe\n",[63,3322,3323,3328,3332],{"__ignoreMap":61},[66,3324,3325],{"class":68,"line":69},[66,3326,3327],{"class":230},"> qmake-qt4 -spec win32-x-g++\n",[66,3329,3330],{"class":68,"line":80},[66,3331,2330],{"class":230},[66,3333,3334],{"class":68,"line":89},[66,3335,3336],{"class":230},"> wine .\u002Frelease\u002Ftest.exe\n",[17,3338,3339],{},[1445,3340],{"alt":3341,"src":3342},"cross-compil4","\u002FProgrammation\u002Fcross-compilation-compiler-un-programme-pour-ms-windows-sous-gnu-linux\u002Fcross-compil4.png",[1432,3344,1540],{"id":1539},[17,3346,3347],{},"Et voilà, vous êtes maintenant capable de faire de la compilation\ncroisée pour des programmes aussi simples que complexes :). Quand vos\nprogrammes ont des dépendances, et si vous le pouvez, préférez la\nversion binaire. Sinon vous devrez compiler les librairies vous-même au\nformat Windows de la même manière avant de compiler votre programme.\nCela peut vous obliger à modifier les scriptes de build.",[3349,3350,3353,3358],"section",{"className":3351,"dataFootnotes":61},[3352],"footnotes",[1432,3354,3357],{"className":3355,"id":1613},[3356],"sr-only","Footnotes",[3359,3360,3361,3372,3381,3390,3399,3412,3421,3430],"ol",{},[165,3362,3364,3365],{"id":3363},"user-content-fn-1","En français cela donne compilation croisée ",[39,3366,3371],{"href":3367,"ariaLabel":3368,"className":3369,"dataFootnoteBackref":61},"#user-content-fnref-1","Back to reference 1",[3370],"data-footnote-backref","↩",[165,3373,3375,3376],{"id":3374},"user-content-fn-2","bien que ... ",[39,3377,3371],{"href":3378,"ariaLabel":3379,"className":3380,"dataFootnoteBackref":61},"#user-content-fnref-2","Back to reference 2",[3370],[165,3382,3384,3385],{"id":3383},"user-content-fn-3","là aussi avec les smartphones actuels, on peut en douter ",[39,3386,3371],{"href":3387,"ariaLabel":3388,"className":3389,"dataFootnoteBackref":61},"#user-content-fnref-3","Back to reference 3",[3370],[165,3391,3393,3394],{"id":3392},"user-content-fn-4","très lointain ",[39,3395,3371],{"href":3396,"ariaLabel":3397,"className":3398,"dataFootnoteBackref":61},"#user-content-fnref-4","Back to reference 4",[3370],[165,3400,3402,3403,3406,3407],{"id":3401},"user-content-fn-5","MinGW est un ",[32,3404,3405],{},"portage"," de gcc pour Window. Il nous permettra donc de générer un executable Windows à partir de notre Gnu\u002FLinux ",[39,3408,3371],{"href":3409,"ariaLabel":3410,"className":3411,"dataFootnoteBackref":61},"#user-content-fnref-5","Back to reference 5",[3370],[165,3413,3415,3416],{"id":3414},"user-content-fn-6","Un émulateur pour démarrer des programmes Windows sous Linux ",[39,3417,3371],{"href":3418,"ariaLabel":3419,"className":3420,"dataFootnoteBackref":61},"#user-content-fnref-6","Back to reference 6",[3370],[165,3422,3424,3425],{"id":3423},"user-content-fn-7","L'installation de wine sous une distribution 64-bit peut-être un peu plus compliqué que prévu, mais reste néanmoins faisable. Référez vous à la documentation de votre distribution. ",[39,3426,3371],{"href":3427,"ariaLabel":3428,"className":3429,"dataFootnoteBackref":61},"#user-content-fnref-7","Back to reference 7",[3370],[165,3431,3433,3434,3438,3439],{"id":3432},"user-content-fn-8","Vous pouvez aussi le télécharger ",[39,3435,3437],{"href":3436},"\u002FProgrammation\u002Fcross-compilation-compiler-un-programme-pour-ms-windows-sous-gnu-linux\u002Fqmake.conf.diff","ici",". ",[39,3440,3371],{"href":3441,"ariaLabel":3442,"className":3443,"dataFootnoteBackref":61},"#user-content-fnref-8","Back to reference 8",[3370],[1545,3445,3446],{},"html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .s_ZVi, html code.shiki .s_ZVi{--shiki-default:#E06C75;--shiki-default-font-style:italic}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}",{"title":61,"searchDepth":80,"depth":80,"links":3448},[3449,3451,3452,3453,3454,3455,3456],{"id":1604,"depth":89,"text":3450},"Qu'est que la cross-compilation1 ?",{"id":1666,"depth":89,"text":1667},{"id":1729,"depth":89,"text":1720},{"id":1874,"depth":89,"text":1723},{"id":2731,"depth":89,"text":2732},{"id":1539,"depth":80,"text":1540},{"id":1613,"depth":80,"text":3357},"2012-07-01",{"type":9,"value":3459},[3460,3467,3469,3471,3473,3493,3495],[12,3461,1605,3462,1615],{"id":1604},[1607,3463,3464],{},[39,3465,461],{"href":1611,"ariaDescribedBy":3466,"dataFootnoteRef":61,"id":1614},[1613],[17,3468,1618],{},[17,3470,1621],{},[17,3472,1624],{},[162,3474,3475,3477,3484,3491],{},[165,3476,1629],{},[165,3478,1632,3479,1640],{},[1607,3480,3481],{},[39,3482,476],{"href":1637,"ariaDescribedBy":3483,"dataFootnoteRef":61,"id":1639},[1613],[165,3485,1643,3486,1640],{},[1607,3487,3488],{},[39,3489,1651],{"href":1648,"ariaDescribedBy":3490,"dataFootnoteRef":61,"id":1650},[1613],[165,3492,1654],{},[17,3494,1657],{},[17,3496,1660,3497,44],{},[32,3498,1663],{},{},"\u002Fpost\u002Fcross-compilation-compiler-un-programme-pour-ms-windows-sous-gnu-linux",{"title":1599,"description":61},"cross-compilation-compiler-un-programme-pour-ms-windows-sous-gnu-linux","posts\u002FProgrammation\u002F2012-07-01-cross-compilation-compiler-un-programme-pour-ms-windows-sous-gnu-linux",[1592],"xyp3lTmc_CVoPo48zy-LSh68_42nO_FD4l7WdmhTvoA",{"id":3507,"title":3508,"author":7,"body":3509,"category":3556,"categorySlug":3756,"date":3757,"description":61,"excerpt":3758,"extension":1584,"location":1585,"meta":3782,"navigation":275,"path":3783,"published":275,"seo":3784,"slug":3785,"stem":3786,"tags":3787,"timeToRead":89,"__hash__":3790},"posts\u002Fposts\u002FKMDAlert\u002F2011-08-14-kmdalert-0.2.md","KMDAlert - Logiciel de surveillance de périphérique RAID - Version pour KDE 4.0",{"type":9,"value":3510,"toc":3748},[3511,3515,3523,3530,3541,3544,3547,3551,3576,3586,3593,3613,3618,3622,3628,3698,3701,3705,3713,3717,3738,3742,3745],[1432,3512,3514],{"id":3513},"présentation","Présentation",[17,3516,3517,3518,3522],{},"Possédant chez moi des disques durs en RAID logiciels sous Gnu\u002FLinux, en\n2007 (cela fait déjà 4 ans), ",[39,3519,3521],{"href":3520},"\u002Fpost\u002F2007-08-17-kmdalert-logiciel-de-surveillance-raid\u002F","j'avais écrit un petit logiciel"," dont le\nbut était de faire du monitoring RAID.",[17,3524,3525,3526,3529],{},"En cas de reconstruction du RAID ou de disque défectueux, le logiciel\naffiche une notification à l'utilisateur, et change le statut affiché\ndans la barre de notification (",[32,3527,3528],{},"systray","). L'icône change bien sur en\nfonction de l'état du RAID :",[162,3531,3532,3535,3538],{},[165,3533,3534],{},"dégradé (avec un point d'exclamation)",[165,3536,3537],{},"en cours de synchronisation (avec une barre de progression)",[165,3539,3540],{},"disque RAID dans un état normal",[17,3542,3543],{},"Ce logiciel ne tournait que sous KDE 3.X.",[17,3545,3546],{},"Voici donc une nouvelle version (qui a mis le temps de sortir) qui est\nun portage de l'application sous KDE 4.X. Elle utilise donc le nouveau\nsystème de notification de KDE (pour l'instant en passant uniquement par\nles notifications standard). Quelques améliorations y seront apportées\nplus tard.",[1432,3548,3550],{"id":3549},"requis","Requis",[17,3552,3553,3554,3557,3558,3561,3562,3565,3566,251,3569,3572,3573,3575],{},"Pour fonctionner ",[32,3555,3556],{},"KMDAlert"," nécessite que le dossier ",[63,3559,3560],{},"\u002Fsys"," soit monté\net que ",[63,3563,3564],{},"\u002Fsys\u002Fblock\u002F"," soit renseigné pour chaque volume RAID (exemple\n",[63,3567,3568],{},"\u002Fsys\u002Fblock\u002Fmd0",[63,3570,3571],{},"\u002Fsys\u002Fblock\u002Fmd1",", ...). ",[63,3574,3556],{}," observe ensuite les\nmodifications faites sur les fichiers pour informer l'utilisateur des\nmodifications faites sur le volume RAID ou sur les disques le composant.",[17,3577,3578,3579,3581,3582,3585],{},"De nos jours le dossier ",[63,3580,3560],{}," et ",[63,3583,3584],{},"\u002Fsys\u002Fblock"," devraient être toujours\nprésents.",[17,3587,3588,3589,3592],{},"L'application a été développée sur ",[32,3590,3591],{},"Gnu\u002FDebian Squeeze",", sur un KDE\n4.4.5 avec un noyau 2.6.32.",[17,3594,3595,3597,3598,3438,3601,3603,3604,3606,3607,3609,3610,3612],{},[32,3596,3556],{}," ne nécessite pas de ",[32,3599,3600],{},"Inotify",[32,3602,3556],{}," lit le contenu de\nplusieurs fichiers dans le dossier ",[63,3605,3560],{}," toutes les 6 secondes pour\nêtre informé de la modification de l'état du périphérique. Sur\nl'application d'origine, développé sous un noyau 2.6.18, ",[32,3608,3600],{}," n'est\npas averti des modifications faites sur le système de fichier ",[63,3611,3560],{},".\nLes dates de ces fichiers ne sont pas non plus modifiées. Si quelqu'un a\nune autre méthode à me proposer, je reste ouvert à toutes propositions.",[17,3614,3615,3617],{},[32,3616,3556],{}," est une application écrite en utilisant les librairies de\nKDE, mais devrait tout de même fonctionner sous Gnome. Les messages de\nnotification utilisent donc le système de notification de KDE (bien que\nje n'utilise pas toutes ses possibilités).",[1432,3619,3621],{"id":3620},"compilation-installation","Compilation \u002F Installation",[17,3623,3624,3625,3627],{},"La compilation et l'installation de ",[32,3626,3556],{}," se fait à l'aide du trio\nhabituel :",[56,3629,3631],{"className":58,"code":3630,"language":60,"meta":61,"style":61},"# Décompression de KMDAlert\ntar xjfv kmdalert-0.2-77c0d6b4d49f.tar.gz\ncd kmdalert-77c0d6b4d49f\n# Préparation de la compilation\nmkdir build\ncd build\n# Comilation\ncmake ..\u002Fmake\n# Installation\nmake install\n",[63,3632,3633,3638,3649,3656,3661,3667,3673,3678,3685,3690],{"__ignoreMap":61},[66,3634,3635],{"class":68,"line":69},[66,3636,3637],{"class":351},"# Décompression de KMDAlert\n",[66,3639,3640,3643,3646],{"class":68,"line":80},[66,3641,3642],{"class":72},"tar",[66,3644,3645],{"class":76}," xjfv",[66,3647,3648],{"class":76}," kmdalert-0.2-77c0d6b4d49f.tar.gz\n",[66,3650,3651,3653],{"class":68,"line":89},[66,3652,84],{"class":83},[66,3654,3655],{"class":76}," kmdalert-77c0d6b4d49f\n",[66,3657,3658],{"class":68,"line":279},[66,3659,3660],{"class":351},"# Préparation de la compilation\n",[66,3662,3663,3665],{"class":68,"line":307},[66,3664,73],{"class":72},[66,3666,719],{"class":76},[66,3668,3669,3671],{"class":68,"line":329},[66,3670,84],{"class":83},[66,3672,719],{"class":76},[66,3674,3675],{"class":68,"line":334},[66,3676,3677],{"class":351},"# Comilation\n",[66,3679,3680,3682],{"class":68,"line":340},[66,3681,730],{"class":72},[66,3683,3684],{"class":76}," ..\u002Fmake\n",[66,3686,3687],{"class":68,"line":355},[66,3688,3689],{"class":351},"# Installation\n",[66,3691,3692,3695],{"class":68,"line":372},[66,3693,3694],{"class":72},"make",[66,3696,3697],{"class":76}," install\n",[17,3699,3700],{},"La compilation nécessite les librairies de développement KDE et Qt3,\nainsi que le compilateur GCC.",[1432,3702,3704],{"id":3703},"licence","Licence",[17,3706,3707,3708],{},"La licence choisie est la ",[39,3709,3712],{"href":3710,"rel":3711},"http:\u002F\u002Fwww.gnu.org\u002Flicenses\u002Fgpl-2.0.txt",[43],"GNU GENERAL PUBLIC LICENSE",[1432,3714,3716],{"id":3715},"téléchargement","Téléchargement",[162,3718,3719,3727,3735],{},[165,3720,3721,3722,44],{},"Vous pouvez télécharger une archive déjà construite de l'application\nsur ",[39,3723,3726],{"href":3724,"rel":3725},"http:\u002F\u002Fkde-apps.org\u002Fcontent\u002Fshow.php\u002FKMDAlert?content=73373",[43],"KDE-Apps.org",[165,3728,3729,3730,44],{},"Le dépôt officiel pour télécharger les sources et participer :\n",[39,3731,3734],{"href":3732,"rel":3733},"https:\u002F\u002Fgogs.shadoware.org\u002Fphoenix\u002Fkmdalert?pk_campaign=shadoware",[43],"https:\u002F\u002Fgogs.shadoware.org\u002Fphoenix\u002Fkmdalert",[165,3736,3737],{},"Vous pouvez également télécharger la version attachée au billet.",[1432,3739,3741],{"id":3740},"système-de-suivi","Système de suivi",[17,3743,3744],{},"Il n'y a actuellement plus de système de suivi pour ce logiciel. En cas\nde problème, vous pouvez laisser un message dans les commentaires ou\nm'envoyer un mail.",[1545,3746,3747],{},"html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":61,"searchDepth":80,"depth":80,"links":3749},[3750,3751,3752,3753,3754,3755],{"id":3513,"depth":80,"text":3514},{"id":3549,"depth":80,"text":3550},{"id":3620,"depth":80,"text":3621},{"id":3703,"depth":80,"text":3704},{"id":3715,"depth":80,"text":3716},{"id":3740,"depth":80,"text":3741},"kmdalert","2011-08-14",{"type":9,"value":3759},[3760,3762,3766,3770,3778,3780],[1432,3761,3514],{"id":3513},[17,3763,3517,3764,3522],{},[39,3765,3521],{"href":3520},[17,3767,3525,3768,3529],{},[32,3769,3528],{},[162,3771,3772,3774,3776],{},[165,3773,3534],{},[165,3775,3537],{},[165,3777,3540],{},[17,3779,3543],{},[17,3781,3546],{},{},"\u002Fpost\u002Fkmdalert-0.2",{"title":3508,"description":61},"kmdalert-0.2","posts\u002FKMDAlert\u002F2011-08-14-kmdalert-0.2",[3788,1592,3756,3789],"kde","raid","4FaKIyQl43RcZ_dgavc_Yj95PpItKkc48C5B55Yud_8",{"id":3792,"title":3793,"author":7,"body":3794,"category":4067,"categorySlug":4068,"date":4069,"description":61,"excerpt":4070,"extension":1584,"location":1585,"meta":4276,"navigation":275,"path":4277,"published":275,"seo":4278,"slug":4279,"stem":4280,"tags":4281,"timeToRead":80,"__hash__":4282},"posts\u002Fposts\u002FQGenConfig\u002F2011-08-06-qgenconfig-generateur-de-classe.md","qGenConfig - Générateur de classe",{"type":9,"value":3795,"toc":4062},[3796,3798,3809,3815,3922,3925,4026,4029,4035,4041,4043,4049,4051,4059],[1432,3797,3514],{"id":3513},[17,3799,3800,3801,3804,3805,3808],{},"Ce logiciel permet de générer des objets ",[63,3802,3803],{},"Qt"," héritant de ",[63,3806,3807],{},"QConfig"," à\npartir d'un fichier écrit au format XML.",[17,3810,3811,3812,3814],{},"Lors de la sauvegarde de paramètres avec ",[63,3813,3803],{},", il faut généralement\nécrire des choses ainsi :",[56,3816,3818],{"className":214,"code":3817,"language":216,"meta":61,"style":61},"QSettings settings(\"MaBoite\", \"MonLogiciel\");\n\nsettings.beginGroup(\"Ma fenêtre\");\nsettings.setValue(\"Taille\", win->size());\nsettings.setValue(\"Pleine écran\", win->isFullScreen());\nsettings.endGroup();\n",[63,3819,3820,3840,3844,3861,3887,3911],{"__ignoreMap":61},[66,3821,3822,3825,3828,3830,3833,3835,3838],{"class":68,"line":69},[66,3823,3824],{"class":240},"QSettings",[66,3826,3827],{"class":72}," settings",[66,3829,231],{"class":230},[66,3831,3832],{"class":76},"\"MaBoite\"",[66,3834,251],{"class":230},[66,3836,3837],{"class":76},"\"MonLogiciel\"",[66,3839,1188],{"class":230},[66,3841,3842],{"class":68,"line":80},[66,3843,276],{"emptyLinePlaceholder":275},[66,3845,3846,3849,3851,3854,3856,3859],{"class":68,"line":89},[66,3847,3848],{"class":240},"settings",[66,3850,44],{"class":230},[66,3852,3853],{"class":72},"beginGroup",[66,3855,231],{"class":230},[66,3857,3858],{"class":76},"\"Ma fenêtre\"",[66,3860,1188],{"class":230},[66,3862,3863,3865,3867,3870,3872,3875,3877,3880,3882,3885],{"class":68,"line":279},[66,3864,3848],{"class":240},[66,3866,44],{"class":230},[66,3868,3869],{"class":72},"setValue",[66,3871,231],{"class":230},[66,3873,3874],{"class":76},"\"Taille\"",[66,3876,251],{"class":230},[66,3878,3879],{"class":240},"win",[66,3881,2829],{"class":230},[66,3883,3884],{"class":72},"size",[66,3886,604],{"class":230},[66,3888,3889,3891,3893,3895,3897,3900,3902,3904,3906,3909],{"class":68,"line":307},[66,3890,3848],{"class":240},[66,3892,44],{"class":230},[66,3894,3869],{"class":72},[66,3896,231],{"class":230},[66,3898,3899],{"class":76},"\"Pleine écran\"",[66,3901,251],{"class":230},[66,3903,3879],{"class":240},[66,3905,2829],{"class":230},[66,3907,3908],{"class":72},"isFullScreen",[66,3910,604],{"class":230},[66,3912,3913,3915,3917,3920],{"class":68,"line":329},[66,3914,3848],{"class":240},[66,3916,44],{"class":230},[66,3918,3919],{"class":72},"endGroup",[66,3921,543],{"class":230},[17,3923,3924],{},"Puis pour récupérer les mêmes paramètres, il faut écrire :",[56,3926,3928],{"className":214,"code":3927,"language":216,"meta":61,"style":61},"QSettings settings(\"MaBoite\", \"MonLogiciel\");\n\nsettings.beginGroup(\"Ma fenêtre\");\nQSize size = settings.value(\"Taille\").toSize();\nbool fullscreen = settings.value(\"Pleine écran\").toBool();\nsettings.endGroup();\n",[63,3929,3930,3946,3950,3964,3989,4016],{"__ignoreMap":61},[66,3931,3932,3934,3936,3938,3940,3942,3944],{"class":68,"line":69},[66,3933,3824],{"class":240},[66,3935,3827],{"class":72},[66,3937,231],{"class":230},[66,3939,3832],{"class":76},[66,3941,251],{"class":230},[66,3943,3837],{"class":76},[66,3945,1188],{"class":230},[66,3947,3948],{"class":68,"line":80},[66,3949,276],{"emptyLinePlaceholder":275},[66,3951,3952,3954,3956,3958,3960,3962],{"class":68,"line":89},[66,3953,3848],{"class":240},[66,3955,44],{"class":230},[66,3957,3853],{"class":72},[66,3959,231],{"class":230},[66,3961,3858],{"class":76},[66,3963,1188],{"class":230},[66,3965,3966,3969,3971,3973,3975,3978,3980,3982,3984,3987],{"class":68,"line":279},[66,3967,3968],{"class":230},"QSize size ",[66,3970,378],{"class":223},[66,3972,3827],{"class":240},[66,3974,44],{"class":230},[66,3976,3977],{"class":72},"value",[66,3979,231],{"class":230},[66,3981,3874],{"class":76},[66,3983,1640],{"class":230},[66,3985,3986],{"class":72},"toSize",[66,3988,543],{"class":230},[66,3990,3991,3994,3997,3999,4001,4003,4005,4007,4009,4011,4014],{"class":68,"line":307},[66,3992,3993],{"class":223},"bool",[66,3995,3996],{"class":230}," fullscreen ",[66,3998,378],{"class":223},[66,4000,3827],{"class":240},[66,4002,44],{"class":230},[66,4004,3977],{"class":72},[66,4006,231],{"class":230},[66,4008,3899],{"class":76},[66,4010,1640],{"class":230},[66,4012,4013],{"class":72},"toBool",[66,4015,543],{"class":230},[66,4017,4018,4020,4022,4024],{"class":68,"line":329},[66,4019,3848],{"class":240},[66,4021,44],{"class":230},[66,4023,3919],{"class":72},[66,4025,543],{"class":230},[17,4027,4028],{},"Si les valeurs doivent être récupérées dans toute l'application et qu'un\njour l'un des paramètres change de nom, de type, ou de groupe, il ne\nsera pas possible d'être sûr que tous les endroits de l'application sont\nbien modifiés lors de la compilation.",[17,4030,4031,4032,44],{},"C'est là qu'intervient ",[63,4033,4034],{},"qGenConfig",[17,4036,4037,4038,4040],{},"Le but est d'écrire un fichier XML représentant la configuration du\nlogiciel et possédant une certaine structure (des groupes, et des\nvaleurs). Le programme parcourt ensuite ce fichier et génère une classe\npermettant de lire et d'enregistrer la configuration à l'aide de\n",[63,4039,4034],{},". Le contenu des données est alors stocké dans une structure\nC, et permet l'accès facile aux données de configuration. Si une donnée\nchange de type, de nom, ou de groupe, le programme ne compilera plus.",[1432,4042,3704],{"id":3703},[17,4044,3707,4045,44],{},[39,4046,3712],{"href":4047,"rel":4048},"http:\u002F\u002Fwww.gnu.org\u002Fcopyleft\u002Fgpl.txt",[43],[1432,4050,3716],{"id":3715},[17,4052,4053,4054],{},"Il est possible de télécharger l'application sur le dépôt officiel à\nl'adresse : ",[39,4055,4058],{"href":4056,"rel":4057},"http:\u002F\u002Fhg.shadoware.org\u002FSoftware\u002Fqgenconfig?pk_campaign=shadoware",[43],"http:\u002F\u002Fhg.shadoware.org\u002FSoftware\u002Fqgenconfig",[1545,4060,4061],{},"html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}",{"title":61,"searchDepth":80,"depth":80,"links":4063},[4064,4065,4066],{"id":3513,"depth":80,"text":3514},{"id":3703,"depth":80,"text":3704},{"id":3715,"depth":80,"text":3716},"QGenConfig","qgenconfig","2011-08-06",{"type":9,"value":4071},[4072,4074,4080,4084,4176,4178,4272,4274],[1432,4073,3514],{"id":3513},[17,4075,3800,4076,3804,4078,3808],{},[63,4077,3803],{},[63,4079,3807],{},[17,4081,3811,4082,3814],{},[63,4083,3803],{},[56,4085,4086],{"className":214,"code":3817,"language":216,"meta":61,"style":61},[63,4087,4088,4104,4108,4122,4144,4166],{"__ignoreMap":61},[66,4089,4090,4092,4094,4096,4098,4100,4102],{"class":68,"line":69},[66,4091,3824],{"class":240},[66,4093,3827],{"class":72},[66,4095,231],{"class":230},[66,4097,3832],{"class":76},[66,4099,251],{"class":230},[66,4101,3837],{"class":76},[66,4103,1188],{"class":230},[66,4105,4106],{"class":68,"line":80},[66,4107,276],{"emptyLinePlaceholder":275},[66,4109,4110,4112,4114,4116,4118,4120],{"class":68,"line":89},[66,4111,3848],{"class":240},[66,4113,44],{"class":230},[66,4115,3853],{"class":72},[66,4117,231],{"class":230},[66,4119,3858],{"class":76},[66,4121,1188],{"class":230},[66,4123,4124,4126,4128,4130,4132,4134,4136,4138,4140,4142],{"class":68,"line":279},[66,4125,3848],{"class":240},[66,4127,44],{"class":230},[66,4129,3869],{"class":72},[66,4131,231],{"class":230},[66,4133,3874],{"class":76},[66,4135,251],{"class":230},[66,4137,3879],{"class":240},[66,4139,2829],{"class":230},[66,4141,3884],{"class":72},[66,4143,604],{"class":230},[66,4145,4146,4148,4150,4152,4154,4156,4158,4160,4162,4164],{"class":68,"line":307},[66,4147,3848],{"class":240},[66,4149,44],{"class":230},[66,4151,3869],{"class":72},[66,4153,231],{"class":230},[66,4155,3899],{"class":76},[66,4157,251],{"class":230},[66,4159,3879],{"class":240},[66,4161,2829],{"class":230},[66,4163,3908],{"class":72},[66,4165,604],{"class":230},[66,4167,4168,4170,4172,4174],{"class":68,"line":329},[66,4169,3848],{"class":240},[66,4171,44],{"class":230},[66,4173,3919],{"class":72},[66,4175,543],{"class":230},[17,4177,3924],{},[56,4179,4180],{"className":214,"code":3927,"language":216,"meta":61,"style":61},[63,4181,4182,4198,4202,4216,4238,4262],{"__ignoreMap":61},[66,4183,4184,4186,4188,4190,4192,4194,4196],{"class":68,"line":69},[66,4185,3824],{"class":240},[66,4187,3827],{"class":72},[66,4189,231],{"class":230},[66,4191,3832],{"class":76},[66,4193,251],{"class":230},[66,4195,3837],{"class":76},[66,4197,1188],{"class":230},[66,4199,4200],{"class":68,"line":80},[66,4201,276],{"emptyLinePlaceholder":275},[66,4203,4204,4206,4208,4210,4212,4214],{"class":68,"line":89},[66,4205,3848],{"class":240},[66,4207,44],{"class":230},[66,4209,3853],{"class":72},[66,4211,231],{"class":230},[66,4213,3858],{"class":76},[66,4215,1188],{"class":230},[66,4217,4218,4220,4222,4224,4226,4228,4230,4232,4234,4236],{"class":68,"line":279},[66,4219,3968],{"class":230},[66,4221,378],{"class":223},[66,4223,3827],{"class":240},[66,4225,44],{"class":230},[66,4227,3977],{"class":72},[66,4229,231],{"class":230},[66,4231,3874],{"class":76},[66,4233,1640],{"class":230},[66,4235,3986],{"class":72},[66,4237,543],{"class":230},[66,4239,4240,4242,4244,4246,4248,4250,4252,4254,4256,4258,4260],{"class":68,"line":307},[66,4241,3993],{"class":223},[66,4243,3996],{"class":230},[66,4245,378],{"class":223},[66,4247,3827],{"class":240},[66,4249,44],{"class":230},[66,4251,3977],{"class":72},[66,4253,231],{"class":230},[66,4255,3899],{"class":76},[66,4257,1640],{"class":230},[66,4259,4013],{"class":72},[66,4261,543],{"class":230},[66,4263,4264,4266,4268,4270],{"class":68,"line":329},[66,4265,3848],{"class":240},[66,4267,44],{"class":230},[66,4269,3919],{"class":72},[66,4271,543],{"class":230},[17,4273,4028],{},[1545,4275,4061],{},{},"\u002Fpost\u002Fqgenconfig-generateur-de-classe",{"title":3793,"description":61},"qgenconfig-generateur-de-classe","posts\u002FQGenConfig\u002F2011-08-06-qgenconfig-generateur-de-classe",[4068,1592],"zKVGw5y0H6WBfipekCU-jDYgCl9Lo12soIhuD9beiyM",{"id":4284,"title":4285,"author":7,"body":4286,"category":1560,"categorySlug":1561,"date":5550,"description":5551,"excerpt":5552,"extension":1584,"location":1585,"meta":5610,"navigation":275,"path":5611,"published":275,"seo":5612,"slug":5613,"stem":5614,"tags":5615,"timeToRead":329,"__hash__":5616},"posts\u002Fposts\u002FProgrammation\u002F2011-06-26-qt-cmake-et-qt.md","C++\u002FQt - CMake et Qt",{"type":9,"value":4287,"toc":5545},[4288,4319,4339,4347,4354,4372,4376,4388,4393,4406,4434,4438,4444,4715,4718,4753,4757,4769,4854,4861,4866,4879,4895,4901,4910,4917,4929,4933,4949,5152,5155,5170,5174,5181,5184,5193,5197,5203,5212,5216,5227,5236,5240,5243,5250,5254,5289,5293,5352,5356,5359,5362,5365,5411,5418,5422,5448,5452,5455,5490,5501,5504,5516,5542],[17,4289,4290,4291,4295,4296,4300,4301,4306,4307,4312,4313,4316,4317,44],{},"Suite à un ",[39,4292,4294],{"href":4293},"\u002Fpost\u002F2008-01-21-memo-qt\u002F","billet"," datant de 2008, je reviens vers vous pour ajouter\nquelques précisions sur la compilation de programme ",[39,4297,3803],{"href":4298,"rel":4299},"http:\u002F\u002Fqt.nokia.com\u002F",[43]," avec\n",[39,4302,4305],{"href":4303,"rel":4304},"http:\u002F\u002Fwww.cmake.org\u002F",[43],"CMake",". En effet, pour mon programme ",[39,4308,4311],{"href":4309,"rel":4310},"http:\u002F\u002Fxinx.shadoware.org?piwik_campaign=Shadoware&piwik_keyword=Billet",[43],"XINX",", j'ai modifié la chaîne\nde compilation actuelle utilisant ",[32,4314,4315],{},"QMake"," par une chaîne de compilation\n",[32,4318,4305],{},[17,4320,4321,4323,4324,4327,4328,3438,4333,4335,4336,4338],{},[32,4322,4305],{}," est un puissant générateur de ",[63,4325,4326],{},"Makefile",", il permet de remplacer\nles anciens (mais pas complètement révolus) ",[39,4329,4332],{"href":4330,"rel":4331},"http:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fautoconf\u002F",[43],"autotools",[32,4334,4305],{}," ne\nremplace donc pas le programme ",[63,4337,3694],{}," mais vient se placer en amont.",[17,4340,4341,4343,4344,44],{},[32,4342,4305],{}," permet de compiler un programme à différents endroits du dossier\ndes sources, ce qui permet de garder le répertoire des sources ",[32,4345,4346],{},"propre",[17,4348,4349,4350,4353],{},"Nous allons considérer dans la suite le dossier ",[63,4351,4352],{},"projet"," suivant :",[162,4355,4356],{},[165,4357,4358,4360],{},[63,4359,4352],{},[162,4361,4362,4367],{},[165,4363,4364],{},[63,4365,4366],{},"source",[165,4368,4369],{},[63,4370,4371],{},"build",[12,4373,4375],{"id":4374},"compilation","Compilation",[17,4377,4378,4379,4381,4382,4387],{},"Nous passerons sous silence la compilation d'un programme non ",[32,4380,3803],{}," qui\npeut être retrouvé dans la ",[39,4383,4386],{"href":4384,"rel":4385},"http:\u002F\u002Fwww.cmake.org\u002Fcmake\u002Fhelp\u002Fcmake_tutorial.html",[43],"documentation"," et nous nous limiterons aux\nexplications liées aux programmes écrits en ''Qt' (qui peuvent également\nêtre retrouvés dans d'autres tutoriels sur Internet).",[4389,4390,4392],"h4",{"id":4391},"package-à-utiliser","Package à utiliser",[17,4394,4395,4396,4399,4400,4402,4403,4405],{},"Pour utiliser ",[32,4397,4398],{},"Qt4"," avec ",[32,4401,4305],{},", il faut inclure le package ",[63,4404,4398],{}," :",[56,4407,4409],{"className":2040,"code":4408,"language":730,"meta":61,"style":61},"project(lenomdemonprojet)\ncmake_minimum_required(VERSION 2.8.0)\nfind_package(Qt4 REQUIRED)\n",[63,4410,4411,4418,4426],{"__ignoreMap":61},[66,4412,4413,4415],{"class":68,"line":69},[66,4414,2048],{"class":223},[66,4416,4417],{"class":230},"(lenomdemonprojet)\n",[66,4419,4420,4423],{"class":68,"line":80},[66,4421,4422],{"class":223},"cmake_minimum_required",[66,4424,4425],{"class":230},"(VERSION 2.8.0)\n",[66,4427,4428,4431],{"class":68,"line":89},[66,4429,4430],{"class":223},"find_package",[66,4432,4433],{"class":230},"(Qt4 REQUIRED)\n",[4389,4435,4437],{"id":4436},"définir-les-modules-qt-à-utiliser","Définir les modules Qt à utiliser",[17,4439,4440,4441,4443],{},"Il est ensuite possible d'activer ou de désactiver les différents\nmodules de ",[32,4442,3803],{}," à utiliser suivant le programme que vous écrivez :",[56,4445,4447],{"className":2040,"code":4446,"language":730,"meta":61,"style":61},"set(QT_DONT_USE_QTCORE TRUE)\nset(QT_DONT_USE_QTGUI TRUE)\nset(QT_USE_QT3SUPPORT TRUE)\nset(QT_USE_QTASSISTANT TRUE)\nset(QT_USE_QAXCONTAINER TRUE)\nset(QT_USE_QAXSERVER TRUE)\nset(QT_USE_QTDESIGNER TRUE)\nset(QT_USE_QTMOTIF TRUE)\nset(QT_USE_QTMAIN TRUE)\nset(QT_USE_QTNETWORK TRUE)\nset(QT_USE_QTNSPLUGIN TRUE)\nset(QT_USE_QTOPENGL TRUE)\nset(QT_USE_QTSQL TRUE)\nset(QT_USE_QTXML TRUE)\nset(QT_USE_QTXMLPATTERNS TRUE)\nset(QT_USE_QTWEBKIT TRUE)\nset(QT_USE_QTSVG TRUE)\nset(QT_USE_QTTEST TRUE)\nset(QT_USE_QTUITOOLS TRUE)\nset(QT_USE_QTDBUS TRUE)\nset(QT_USE_QTSCRIPT TRUE)\nset(QT_USE_QTASSISTANTCLIENT TRUE)\nset(QT_USE_QTHELP TRUE)\nset(QT_USE_PHONON TRUE)\n",[63,4448,4449,4462,4473,4484,4495,4506,4517,4528,4539,4550,4561,4572,4583,4594,4605,4616,4627,4638,4649,4660,4671,4682,4693,4704],{"__ignoreMap":61},[66,4450,4451,4454,4457,4460],{"class":68,"line":69},[66,4452,4453],{"class":223},"set",[66,4455,4456],{"class":230},"(QT_DONT_USE_QTCORE ",[66,4458,4459],{"class":223},"TRUE",[66,4461,1784],{"class":230},[66,4463,4464,4466,4469,4471],{"class":68,"line":80},[66,4465,4453],{"class":223},[66,4467,4468],{"class":230},"(QT_DONT_USE_QTGUI ",[66,4470,4459],{"class":223},[66,4472,1784],{"class":230},[66,4474,4475,4477,4480,4482],{"class":68,"line":89},[66,4476,4453],{"class":223},[66,4478,4479],{"class":230},"(QT_USE_QT3SUPPORT ",[66,4481,4459],{"class":223},[66,4483,1784],{"class":230},[66,4485,4486,4488,4491,4493],{"class":68,"line":279},[66,4487,4453],{"class":223},[66,4489,4490],{"class":230},"(QT_USE_QTASSISTANT ",[66,4492,4459],{"class":223},[66,4494,1784],{"class":230},[66,4496,4497,4499,4502,4504],{"class":68,"line":307},[66,4498,4453],{"class":223},[66,4500,4501],{"class":230},"(QT_USE_QAXCONTAINER ",[66,4503,4459],{"class":223},[66,4505,1784],{"class":230},[66,4507,4508,4510,4513,4515],{"class":68,"line":329},[66,4509,4453],{"class":223},[66,4511,4512],{"class":230},"(QT_USE_QAXSERVER ",[66,4514,4459],{"class":223},[66,4516,1784],{"class":230},[66,4518,4519,4521,4524,4526],{"class":68,"line":334},[66,4520,4453],{"class":223},[66,4522,4523],{"class":230},"(QT_USE_QTDESIGNER ",[66,4525,4459],{"class":223},[66,4527,1784],{"class":230},[66,4529,4530,4532,4535,4537],{"class":68,"line":340},[66,4531,4453],{"class":223},[66,4533,4534],{"class":230},"(QT_USE_QTMOTIF ",[66,4536,4459],{"class":223},[66,4538,1784],{"class":230},[66,4540,4541,4543,4546,4548],{"class":68,"line":355},[66,4542,4453],{"class":223},[66,4544,4545],{"class":230},"(QT_USE_QTMAIN ",[66,4547,4459],{"class":223},[66,4549,1784],{"class":230},[66,4551,4552,4554,4557,4559],{"class":68,"line":372},[66,4553,4453],{"class":223},[66,4555,4556],{"class":230},"(QT_USE_QTNETWORK ",[66,4558,4459],{"class":223},[66,4560,1784],{"class":230},[66,4562,4563,4565,4568,4570],{"class":68,"line":395},[66,4564,4453],{"class":223},[66,4566,4567],{"class":230},"(QT_USE_QTNSPLUGIN ",[66,4569,4459],{"class":223},[66,4571,1784],{"class":230},[66,4573,4574,4576,4579,4581],{"class":68,"line":400},[66,4575,4453],{"class":223},[66,4577,4578],{"class":230},"(QT_USE_QTOPENGL ",[66,4580,4459],{"class":223},[66,4582,1784],{"class":230},[66,4584,4585,4587,4590,4592],{"class":68,"line":416},[66,4586,4453],{"class":223},[66,4588,4589],{"class":230},"(QT_USE_QTSQL ",[66,4591,4459],{"class":223},[66,4593,1784],{"class":230},[66,4595,4596,4598,4601,4603],{"class":68,"line":421},[66,4597,4453],{"class":223},[66,4599,4600],{"class":230},"(QT_USE_QTXML ",[66,4602,4459],{"class":223},[66,4604,1784],{"class":230},[66,4606,4607,4609,4612,4614],{"class":68,"line":485},[66,4608,4453],{"class":223},[66,4610,4611],{"class":230},"(QT_USE_QTXMLPATTERNS ",[66,4613,4459],{"class":223},[66,4615,1784],{"class":230},[66,4617,4618,4620,4623,4625],{"class":68,"line":490},[66,4619,4453],{"class":223},[66,4621,4622],{"class":230},"(QT_USE_QTWEBKIT ",[66,4624,4459],{"class":223},[66,4626,1784],{"class":230},[66,4628,4629,4631,4634,4636],{"class":68,"line":520},[66,4630,4453],{"class":223},[66,4632,4633],{"class":230},"(QT_USE_QTSVG ",[66,4635,4459],{"class":223},[66,4637,1784],{"class":230},[66,4639,4640,4642,4645,4647],{"class":68,"line":546},[66,4641,4453],{"class":223},[66,4643,4644],{"class":230},"(QT_USE_QTTEST ",[66,4646,4459],{"class":223},[66,4648,1784],{"class":230},[66,4650,4651,4653,4656,4658],{"class":68,"line":558},[66,4652,4453],{"class":223},[66,4654,4655],{"class":230},"(QT_USE_QTUITOOLS ",[66,4657,4459],{"class":223},[66,4659,1784],{"class":230},[66,4661,4662,4664,4667,4669],{"class":68,"line":607},[66,4663,4453],{"class":223},[66,4665,4666],{"class":230},"(QT_USE_QTDBUS ",[66,4668,4459],{"class":223},[66,4670,1784],{"class":230},[66,4672,4673,4675,4678,4680],{"class":68,"line":645},[66,4674,4453],{"class":223},[66,4676,4677],{"class":230},"(QT_USE_QTSCRIPT ",[66,4679,4459],{"class":223},[66,4681,1784],{"class":230},[66,4683,4684,4686,4689,4691],{"class":68,"line":653},[66,4685,4453],{"class":223},[66,4687,4688],{"class":230},"(QT_USE_QTASSISTANTCLIENT ",[66,4690,4459],{"class":223},[66,4692,1784],{"class":230},[66,4694,4695,4697,4700,4702],{"class":68,"line":1278},[66,4696,4453],{"class":223},[66,4698,4699],{"class":230},"(QT_USE_QTHELP ",[66,4701,4459],{"class":223},[66,4703,1784],{"class":230},[66,4705,4706,4708,4711,4713],{"class":68,"line":1301},[66,4707,4453],{"class":223},[66,4709,4710],{"class":230},"(QT_USE_PHONON ",[66,4712,4459],{"class":223},[66,4714,1784],{"class":230},[17,4716,4717],{},"Par exemple pour faire un programme utilisant le module Xml,\nXmlPatterns, et Webkit il faut ajouter :",[56,4719,4721],{"className":2040,"code":4720,"language":730,"meta":61,"style":61},"set(QT_USE_QTXML TRUE)\nset(QT_USE_QTXMLPATTERNS TRUE)\nset(QT_USE_QTWEBKIT TRUE)\n",[63,4722,4723,4733,4743],{"__ignoreMap":61},[66,4724,4725,4727,4729,4731],{"class":68,"line":69},[66,4726,4453],{"class":223},[66,4728,4600],{"class":230},[66,4730,4459],{"class":223},[66,4732,1784],{"class":230},[66,4734,4735,4737,4739,4741],{"class":68,"line":80},[66,4736,4453],{"class":223},[66,4738,4611],{"class":230},[66,4740,4459],{"class":223},[66,4742,1784],{"class":230},[66,4744,4745,4747,4749,4751],{"class":68,"line":89},[66,4746,4453],{"class":223},[66,4748,4622],{"class":230},[66,4750,4459],{"class":223},[66,4752,1784],{"class":230},[4389,4754,4756],{"id":4755},"quelques-déclarations-supplémentaires","Quelques déclarations supplémentaires",[17,4758,4759,4760,4762,4763,4765,4766,44],{},"Après avoir compilé les différentes parties du programme avec le\ngénérateur de ",[63,4761,4326],{}," de ",[32,4764,3803],{}," (QMake), j'ai relevé les différentes\ndéfinitions à ajouter lors de la compilation. De plus une fois les\nmodules définis, il faut inclure également le module ",[32,4767,4768],{},"UseQt4",[56,4770,4772],{"className":2040,"code":4771,"language":730,"meta":61,"style":61},"add_definitions(-DUNICODE)\n# Les Q_ASSERT, Q_ASSERT_X, ... sont désactivés en mode Release\nif(CMAKE_BUILD_TYPE STREQUAL \"Release\")\n    add_definitions(-DQT_NO_DEBUG)\nendif()\n# Include utilisé par Qt (du style include (UseQt4))\ninclude(${QT_USE_FILE})\n# Ajoute les définitions propres à Qt (suivant les modules ajoutés)\nadd_definitions(${QT_DEFINITIONS})\n",[63,4773,4774,4782,4787,4805,4813,4821,4826,4838,4843],{"__ignoreMap":61},[66,4775,4776,4779],{"class":68,"line":69},[66,4777,4778],{"class":223},"add_definitions",[66,4780,4781],{"class":230},"(-DUNICODE)\n",[66,4783,4784],{"class":68,"line":80},[66,4785,4786],{"class":351},"# Les Q_ASSERT, Q_ASSERT_X, ... sont désactivés en mode Release\n",[66,4788,4789,4792,4794,4797,4800,4803],{"class":68,"line":89},[66,4790,4791],{"class":223},"if",[66,4793,231],{"class":230},[66,4795,4796],{"class":437},"CMAKE_BUILD_TYPE",[66,4798,4799],{"class":223}," STREQUAL",[66,4801,4802],{"class":76}," \"Release\"",[66,4804,1784],{"class":230},[66,4806,4807,4810],{"class":68,"line":279},[66,4808,4809],{"class":223},"    add_definitions",[66,4811,4812],{"class":230},"(-DQT_NO_DEBUG)\n",[66,4814,4815,4818],{"class":68,"line":307},[66,4816,4817],{"class":223},"endif",[66,4819,4820],{"class":230},"()\n",[66,4822,4823],{"class":68,"line":329},[66,4824,4825],{"class":351},"# Include utilisé par Qt (du style include (UseQt4))\n",[66,4827,4828,4831,4833,4836],{"class":68,"line":334},[66,4829,4830],{"class":223},"include",[66,4832,231],{"class":230},[66,4834,4835],{"class":223},"${QT_USE_FILE}",[66,4837,1784],{"class":230},[66,4839,4840],{"class":68,"line":340},[66,4841,4842],{"class":351},"# Ajoute les définitions propres à Qt (suivant les modules ajoutés)\n",[66,4844,4845,4847,4849,4852],{"class":68,"line":355},[66,4846,4778],{"class":223},[66,4848,231],{"class":230},[66,4850,4851],{"class":223},"${QT_DEFINITIONS}",[66,4853,1784],{"class":230},[4389,4855,4857,4858],{"id":4856},"macros-pour-générer-les-fichiers-moc","Macros pour générer les fichiers ",[63,4859,4860],{},"moc",[4862,4863,4865],"h5",{"id":4864},"macro-par-défaut","Macro par défaut",[17,4867,4868,4869,4871,4872,4874,44],{},"La facilité de programmation en ",[32,4870,3803],{}," est due à l'ajout par le framework\nde la notion de méta-objet. Cette notion se fait à l'aide d'un\ngénérateur propre à ce framework : ",[63,4873,4860],{},[1607,4875,4876],{},[39,4877,461],{"href":1611,"ariaDescribedBy":4878,"dataFootnoteRef":61,"id":1614},[1613],[17,4880,4881,4882,4885,4886,4889,4890,44],{},"Pour générer les méta-objets, il faut définir sur les objets descendants\nde ",[63,4883,4884],{},"QObject",", une macro ",[63,4887,4888],{},"Q_OBJECT",". Cette macro ajoute, côté interface,\nla déclaration de méthodes supplémentaires pour la gestion des\nméta-informations, et coté implémentation, ajoute l'implémentation de\nces méta-informations ainsi que la déclaration des signaux et de slots\nde l'objet",[1607,4891,4892],{},[39,4893,476],{"href":1637,"ariaDescribedBy":4894,"dataFootnoteRef":61,"id":1639},[1613],[17,4896,4897,4898,4900],{},"Pour générer les fichiers d'implémentation générés par le compilateur\n",[63,4899,4860],{},", il est possible d'utiliser la macro suivante pour une liste de\nfichier sources (extension .cpp, ou .cxx, ...) :",[56,4902,4904],{"className":2040,"code":4903,"language":730,"meta":61,"style":61},"qt4_wrap_cpp(outfiles inputfile ... OPTIONS ...)\n",[63,4905,4906],{"__ignoreMap":61},[66,4907,4908],{"class":68,"line":69},[66,4909,4903],{"class":230},[17,4911,4912,4913,4916],{},"Cette macro générera un fichier de type ",[63,4914,4915],{},"moc_nomfichier.cxx"," qu'il\nfaudra inclure dans le ficher CPP (car il n'est pas inclus\nautomatiquement dans la liste des fichiers à compiler.",[56,4918,4920],{"className":214,"code":4919,"language":216,"meta":61,"style":61},"#include \"moc_nomfichier.cxx\"\n",[63,4921,4922],{"__ignoreMap":61},[66,4923,4924,4926],{"class":68,"line":69},[66,4925,1887],{"class":223},[66,4927,4928],{"class":76}," \"moc_nomfichier.cxx\"\n",[4862,4930,4932],{"id":4931},"une-autre-macro","Une autre macro",[17,4934,4935,4936,4762,4939,4941,4942,4945,4946,4948],{},"Autre possibilité, faire comme avec les fichiers ",[63,4937,4938],{},".pro",[32,4940,4315],{}," et\ngénérer un fichier moc pour chaque fichier ",[63,4943,4944],{},".h"," possédant une macro\n",[63,4947,4888],{},". Pour cela j'ai écrit la petite macro suivante :",[56,4950,4952],{"className":2040,"code":4951,"language":730,"meta":61,"style":61},"macro(xinx_automoc outfiles)\nqt4_get_moc_flags(moc_flags)\nqt4_extract_options(moc_files moc_options ${ARGN})\nforeach (it ${moc_files})\n    get_filename_component(it ${it} ABSOLUTE)\n    if ( EXISTS ${it} )\n        file(READ ${it} _contents)\n        string(REGEX MATCHALL \"Q_OBJECT\" _match \"${_contents}\")\n        if(_match)\n            qt4_make_output_file(${it} moc_ cxx outfile)\n            qt4_create_moc_command(${it} ${outfile} \"${moc_flags}\" \"${moc_options}\")\n            macro_add_file_dependencies(${it} ${outfile})\n            set(${outfiles} ${${outfiles}} ${outfile})\n        endif(_match)\n    endif ( EXISTS ${it} )\nendforeach(it)endmacro(xinx_automoc)\n",[63,4953,4954,4962,4967,4977,4990,5006,5022,5035,5054,5062,5072,5090,5101,5124,5131,5144],{"__ignoreMap":61},[66,4955,4956,4959],{"class":68,"line":69},[66,4957,4958],{"class":223},"macro",[66,4960,4961],{"class":230},"(xinx_automoc outfiles)\n",[66,4963,4964],{"class":68,"line":80},[66,4965,4966],{"class":230},"qt4_get_moc_flags(moc_flags)\n",[66,4968,4969,4972,4975],{"class":68,"line":89},[66,4970,4971],{"class":230},"qt4_extract_options(moc_files moc_options ",[66,4973,4974],{"class":223},"${ARGN}",[66,4976,1784],{"class":230},[66,4978,4979,4982,4985,4988],{"class":68,"line":279},[66,4980,4981],{"class":223},"foreach",[66,4983,4984],{"class":230}," (it ",[66,4986,4987],{"class":223},"${moc_files}",[66,4989,1784],{"class":230},[66,4991,4992,4995,4998,5001,5004],{"class":68,"line":307},[66,4993,4994],{"class":223},"    get_filename_component",[66,4996,4997],{"class":230},"(it ",[66,4999,5000],{"class":223},"${it}",[66,5002,5003],{"class":223}," ABSOLUTE",[66,5005,1784],{"class":230},[66,5007,5008,5010,5013,5016,5019],{"class":68,"line":329},[66,5009,493],{"class":223},[66,5011,5012],{"class":230}," ( ",[66,5014,5015],{"class":223},"EXISTS",[66,5017,5018],{"class":223}," ${it}",[66,5020,5021],{"class":230}," )\n",[66,5023,5024,5027,5030,5032],{"class":68,"line":334},[66,5025,5026],{"class":223},"        file",[66,5028,5029],{"class":230},"(READ ",[66,5031,5000],{"class":223},[66,5033,5034],{"class":230}," _contents)\n",[66,5036,5037,5040,5043,5046,5049,5052],{"class":68,"line":340},[66,5038,5039],{"class":223},"        string",[66,5041,5042],{"class":230},"(REGEX MATCHALL ",[66,5044,5045],{"class":76},"\"Q_OBJECT\"",[66,5047,5048],{"class":230}," _match ",[66,5050,5051],{"class":76},"\"${_contents}\"",[66,5053,1784],{"class":230},[66,5055,5056,5059],{"class":68,"line":355},[66,5057,5058],{"class":223},"        if",[66,5060,5061],{"class":230},"(_match)\n",[66,5063,5064,5067,5069],{"class":68,"line":372},[66,5065,5066],{"class":230},"            qt4_make_output_file(",[66,5068,5000],{"class":223},[66,5070,5071],{"class":230}," moc_ cxx outfile)\n",[66,5073,5074,5077,5079,5082,5085,5088],{"class":68,"line":395},[66,5075,5076],{"class":230},"            qt4_create_moc_command(",[66,5078,5000],{"class":223},[66,5080,5081],{"class":223}," ${outfile}",[66,5083,5084],{"class":76}," \"${moc_flags}\"",[66,5086,5087],{"class":76}," \"${moc_options}\"",[66,5089,1784],{"class":230},[66,5091,5092,5095,5097,5099],{"class":68,"line":400},[66,5093,5094],{"class":230},"            macro_add_file_dependencies(",[66,5096,5000],{"class":223},[66,5098,5081],{"class":223},[66,5100,1784],{"class":230},[66,5102,5103,5106,5108,5111,5114,5116,5119,5122],{"class":68,"line":416},[66,5104,5105],{"class":223},"            set",[66,5107,231],{"class":230},[66,5109,5110],{"class":223},"${outfiles}",[66,5112,5113],{"class":230}," ${",[66,5115,5110],{"class":223},[66,5117,5118],{"class":230},"} ",[66,5120,5121],{"class":223},"${outfile}",[66,5123,1784],{"class":230},[66,5125,5126,5129],{"class":68,"line":421},[66,5127,5128],{"class":223},"        endif",[66,5130,5061],{"class":230},[66,5132,5133,5136,5138,5140,5142],{"class":68,"line":485},[66,5134,5135],{"class":223},"    endif",[66,5137,5012],{"class":230},[66,5139,5015],{"class":223},[66,5141,5018],{"class":223},[66,5143,5021],{"class":230},[66,5145,5146,5149],{"class":68,"line":490},[66,5147,5148],{"class":223},"endforeach",[66,5150,5151],{"class":230},"(it)endmacro(xinx_automoc)\n",[17,5153,5154],{},"Elle s'utilise ainsi :",[56,5156,5158],{"className":2040,"code":5157,"language":730,"meta":61,"style":61},"xinx_automoc(moc_headers ${headers})\n",[63,5159,5160],{"__ignoreMap":61},[66,5161,5162,5165,5168],{"class":68,"line":69},[66,5163,5164],{"class":230},"xinx_automoc(moc_headers ",[66,5166,5167],{"class":223},"${headers}",[66,5169,1784],{"class":230},[4389,5171,5173],{"id":5172},"macro-pour-générer-les-fichiers-en-tête-dinterface-graphique","Macro pour générer les fichiers en tête d'interface graphique",[17,5175,5176,5177,5180],{},"Les interfaces graphiques sont développées à l'aide de ",[32,5178,5179],{},"Qt-Designer",".\nCes fichiers sont au format XML.",[17,5182,5183],{},"La macro CMake suivante permet de transformer ces fichiers XML en\nfichier d'entête C.",[56,5185,5187],{"className":2040,"code":5186,"language":730,"meta":61,"style":61},"qt4_wrap_ui(outfiles inputfile ...)\n",[63,5188,5189],{"__ignoreMap":61},[66,5190,5191],{"class":68,"line":69},[66,5192,5186],{"class":230},[4389,5194,5196],{"id":5195},"macro-pour-compiler-les-fichiers-de-resources","Macro pour compiler les fichiers de resources",[17,5198,5199,5200,5202],{},"La macro CMake suivante permet de compiler le fichier de ressource\n(extension *.qrc) en fichier ",[63,5201,216],{}," qui sera ensuite compilé avec le\nreste du programme :",[56,5204,5206],{"className":2040,"code":5205,"language":730,"meta":61,"style":61},"qt4_add_resources(outfiles inputfile ... OPTIONS ...)\n",[63,5207,5208],{"__ignoreMap":61},[66,5209,5210],{"class":68,"line":69},[66,5211,5205],{"class":230},[4389,5213,5215],{"id":5214},"macro-pour-compiler-les-fichiers-de-traduction","Macro pour compiler les fichiers de traduction",[17,5217,5218,5219,5222,5223,5226],{},"La macro CMake suivante est utilisée pour compiler un fichier de\ntraduction ",[63,5220,5221],{},"ts"," en fichier de traduction compilé ",[63,5224,5225],{},"qm",". Ce dernier est\nensuite à inclure dans le programme (soit par un fichier de ressource,\nsoit dans un dossier à coté).",[56,5228,5230],{"className":2040,"code":5229,"language":730,"meta":61,"style":61},"qt4_add_translation(qm_files ts_files ...)\n",[63,5231,5232],{"__ignoreMap":61},[66,5233,5234],{"class":68,"line":69},[66,5235,5229],{"class":230},[4389,5237,5239],{"id":5238},"compilation-dun-plugin","Compilation d'un plugin",[17,5241,5242],{},"En plus des options décrites ci-dessus, pour compiler un plugin, il faut\najouter quelques définitions supplémentaires.",[17,5244,5245,5246,5249],{},"Il faut bien faire attention à ce que le plugin soit compilé en mode\n",[63,5247,5248],{},"Release"," si le programme l'est aussi (Ce qui n'est pas forcément\npratique pour faire du debug).",[4862,5251,5253],{"id":5252},"plugin-dynamique","Plugin dynamique",[56,5255,5257],{"className":2040,"code":5256,"language":730,"meta":61,"style":61},"add_definitions(-DQT_PLUGIN)\nadd_definitions(-DQT_SHARED)\nadd_library(webplugin SHARED ${webplugin_SRCS} ${webplugin_MOC_SRCS})\n",[63,5258,5259,5266,5273],{"__ignoreMap":61},[66,5260,5261,5263],{"class":68,"line":69},[66,5262,4778],{"class":223},[66,5264,5265],{"class":230},"(-DQT_PLUGIN)\n",[66,5267,5268,5270],{"class":68,"line":80},[66,5269,4778],{"class":223},[66,5271,5272],{"class":230},"(-DQT_SHARED)\n",[66,5274,5275,5278,5281,5284,5287],{"class":68,"line":89},[66,5276,5277],{"class":223},"add_library",[66,5279,5280],{"class":230},"(webplugin SHARED ",[66,5282,5283],{"class":223},"${webplugin_SRCS}",[66,5285,5286],{"class":223}," ${webplugin_MOC_SRCS}",[66,5288,1784],{"class":230},[4862,5290,5292],{"id":5291},"plugin-static","Plugin Static",[56,5294,5296],{"className":2040,"code":5295,"language":730,"meta":61,"style":61},"add_definitions(-DQT_PLUGIN)\nadd_definitions(-DQT_STATICPLUGIN)\nif(CMAKE_SIZEOF_VOID_P MATCHES 8)\n    add_definitions(-fPIC)\nendif()\nadd_library(webplugin STATIC ${webplugin_SRCS} ${webplugin_MOC_SRCS})\n",[63,5297,5298,5304,5311,5326,5333,5339],{"__ignoreMap":61},[66,5299,5300,5302],{"class":68,"line":69},[66,5301,4778],{"class":223},[66,5303,5265],{"class":230},[66,5305,5306,5308],{"class":68,"line":80},[66,5307,4778],{"class":223},[66,5309,5310],{"class":230},"(-DQT_STATICPLUGIN)\n",[66,5312,5313,5315,5317,5320,5323],{"class":68,"line":89},[66,5314,4791],{"class":223},[66,5316,231],{"class":230},[66,5318,5319],{"class":437},"CMAKE_SIZEOF_VOID_P",[66,5321,5322],{"class":223}," MATCHES",[66,5324,5325],{"class":230}," 8)\n",[66,5327,5328,5330],{"class":68,"line":279},[66,5329,4809],{"class":223},[66,5331,5332],{"class":230},"(-fPIC)\n",[66,5334,5335,5337],{"class":68,"line":307},[66,5336,4817],{"class":223},[66,5338,4820],{"class":230},[66,5340,5341,5343,5346,5348,5350],{"class":68,"line":329},[66,5342,5277],{"class":223},[66,5344,5345],{"class":230},"(webplugin STATIC ",[66,5347,5283],{"class":223},[66,5349,5286],{"class":223},[66,5351,1784],{"class":230},[4389,5353,5355],{"id":5354},"ajout-dun-fichier-rc-pour-windows","Ajout d'un fichier RC pour windows",[17,5357,5358],{},"Les fichiers RC Windows contiennent des informations, comme par exemple,\nla version et le nom du programme.",[17,5360,5361],{},"Ces informations peuvent être utilisées par les programmes\nd'installation sous Windows ou aussi par Windows lui-même.",[17,5363,5364],{},"Afin de pouvoir ajouter un fichier RC file au programme, on peut ajouter\nceci :",[56,5366,5368],{"className":2040,"code":5367,"language":730,"meta":61,"style":61},"if(MINGW)\n        set(CMAKE_RC_COMPILER_INIT windres)\n        enable_language(RC)\n        set(CMAKE_RC_COMPILE_OBJECT \"\u003CCMAKE_RC_COMPILER> \u003CFLAGS> \u003CDEFINES> -O coff -o \u003COBJECT> \u003CSOURCE>\")\nendif(MINGW)\n",[63,5369,5370,5377,5385,5393,5405],{"__ignoreMap":61},[66,5371,5372,5374],{"class":68,"line":69},[66,5373,4791],{"class":223},[66,5375,5376],{"class":230},"(MINGW)\n",[66,5378,5379,5382],{"class":68,"line":80},[66,5380,5381],{"class":223},"        set",[66,5383,5384],{"class":230},"(CMAKE_RC_COMPILER_INIT windres)\n",[66,5386,5387,5390],{"class":68,"line":89},[66,5388,5389],{"class":223},"        enable_language",[66,5391,5392],{"class":230},"(RC)\n",[66,5394,5395,5397,5400,5403],{"class":68,"line":279},[66,5396,5381],{"class":223},[66,5398,5399],{"class":230},"(CMAKE_RC_COMPILE_OBJECT ",[66,5401,5402],{"class":76},"\"\u003CCMAKE_RC_COMPILER> \u003CFLAGS> \u003CDEFINES> -O coff -o \u003COBJECT> \u003CSOURCE>\"",[66,5404,1784],{"class":230},[66,5406,5407,5409],{"class":68,"line":307},[66,5408,4817],{"class":223},[66,5410,5376],{"class":230},[17,5412,5413,5414,5417],{},"Ensuite le fichier RC se compile comme tout autre fichier (",[63,5415,5416],{},"C++",", ...)",[4389,5419,5421],{"id":5420},"compilation-dune-librairie-static","Compilation d'une librairie static",[56,5423,5425],{"className":2040,"code":5424,"language":730,"meta":61,"style":61},"add_definitions(-DQT_SHARED)\nadd_library(xinxplugins STATIC ${xinxplugins_SRCS} ${xinxplugins_MOC_SRCS})\n",[63,5426,5427,5433],{"__ignoreMap":61},[66,5428,5429,5431],{"class":68,"line":69},[66,5430,4778],{"class":223},[66,5432,5272],{"class":230},[66,5434,5435,5437,5440,5443,5446],{"class":68,"line":80},[66,5436,5277],{"class":223},[66,5438,5439],{"class":230},"(xinxplugins STATIC ",[66,5441,5442],{"class":223},"${xinxplugins_SRCS}",[66,5444,5445],{"class":223}," ${xinxplugins_MOC_SRCS}",[66,5447,1784],{"class":230},[12,5449,5451],{"id":5450},"utiliser-le-programme-cmake","Utiliser le programme CMake",[17,5453,5454],{},"Une fois le programme configuré, il est possible de compiler ce dernier\nà l'aide des commandes suivantes :",[56,5456,5458],{"className":58,"code":5457,"language":60,"meta":61,"style":61},"mkdir build\ncd build\ncmake ..\u002Fsources\nmake\nmake install\n",[63,5459,5460,5466,5472,5479,5484],{"__ignoreMap":61},[66,5461,5462,5464],{"class":68,"line":69},[66,5463,73],{"class":72},[66,5465,719],{"class":76},[66,5467,5468,5470],{"class":68,"line":80},[66,5469,84],{"class":83},[66,5471,719],{"class":76},[66,5473,5474,5476],{"class":68,"line":89},[66,5475,730],{"class":72},[66,5477,5478],{"class":76}," ..\u002Fsources\n",[66,5480,5481],{"class":68,"line":279},[66,5482,5483],{"class":72},"make\n",[66,5485,5486,5488],{"class":68,"line":307},[66,5487,3694],{"class":72},[66,5489,3697],{"class":76},[17,5491,5492,5493,5497,5498,44],{},"Sous Windows, il est possible de compiler en utilisant ",[39,5494,1691],{"href":5495,"rel":5496},"http:\u002F\u002Fwww.mingw.org\u002F",[43]," pour\ncompiler ou d'utiliser le compilateur de ",[63,5499,5500],{},"Visual Studio",[17,5502,5503],{},"Il est également possible de définir un emplacement pour l'installation\ndifférent du dossier par défaut :",[56,5505,5507],{"className":58,"code":5506,"language":60,"meta":61,"style":61},"cmake -DCMAKE_INSTALL_PREFIX=\u002Fhome\u002Flogin\u002Fusr\u002F\n",[63,5508,5509],{"__ignoreMap":61},[66,5510,5511,5513],{"class":68,"line":69},[66,5512,730],{"class":72},[66,5514,5515],{"class":114}," -DCMAKE_INSTALL_PREFIX=\u002Fhome\u002Flogin\u002Fusr\u002F\n",[3349,5517,5519,5522],{"className":5518,"dataFootnotes":61},[3352],[1432,5520,3357],{"className":5521,"id":1613},[3356],[3359,5523,5524,5533],{},[165,5525,5526,5527,5529,5530],{"id":3363},"C'est ce qui fait tout l'avantage de ",[32,5528,3803],{}," mais est aussi son inconvénient car il ajoute une couche supplémentaire. C'est ensuite une question de goût. ",[39,5531,3371],{"href":3367,"ariaLabel":3368,"className":5532,"dataFootnoteBackref":61},[3370],[165,5534,5535,5536,5538,5539],{"id":3374},"facilitant la gestion des évènements dans ",[32,5537,3803],{}," ",[39,5540,3371],{"href":3378,"ariaLabel":3379,"className":5541,"dataFootnoteBackref":61},[3370],[1545,5543,5544],{},"html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}",{"title":61,"searchDepth":80,"depth":80,"links":5546},[5547,5548,5549],{"id":4374,"depth":89,"text":4375},{"id":5450,"depth":89,"text":5451},{"id":1613,"depth":80,"text":3357},"2011-06-26","Suite à un billet datant de 2008, je reviens vers vous pour ajouter\nquelques précisions sur la compilation de programme Qt avec\nCMake. En effet, pour mon programme XINX, j'ai modifié la chaîne\nde compilation actuelle utilisant QMake par une chaîne de compilation\nCMake.",{"type":9,"value":5553},[5554,5571,5584,5590,5594],[17,5555,4290,5556,4295,5558,4300,5561,4306,5564,4312,5567,4316,5569,44],{},[39,5557,4294],{"href":4293},[39,5559,3803],{"href":4298,"rel":5560},[43],[39,5562,4305],{"href":4303,"rel":5563},[43],[39,5565,4311],{"href":4309,"rel":5566},[43],[32,5568,4315],{},[32,5570,4305],{},[17,5572,5573,4323,5575,4327,5577,3438,5580,4335,5582,4338],{},[32,5574,4305],{},[63,5576,4326],{},[39,5578,4332],{"href":4330,"rel":5579},[43],[32,5581,4305],{},[63,5583,3694],{},[17,5585,5586,4343,5588,44],{},[32,5587,4305],{},[32,5589,4346],{},[17,5591,4349,5592,4353],{},[63,5593,4352],{},[162,5595,5596],{},[165,5597,5598,5600],{},[63,5599,4352],{},[162,5601,5602,5606],{},[165,5603,5604],{},[63,5605,4366],{},[165,5607,5608],{},[63,5609,4371],{},{},"\u002Fpost\u002Fqt-cmake-et-qt",{"title":4285,"description":5551},"qt-cmake-et-qt","posts\u002FProgrammation\u002F2011-06-26-qt-cmake-et-qt",[1592],"z241vjvDaj7TX5NjylClHpgb9g7dVly4_9NxleMnRPU",{"id":5618,"title":5619,"author":7,"body":5620,"category":4311,"categorySlug":5899,"date":5900,"description":5624,"excerpt":5901,"extension":1584,"location":1585,"meta":5924,"navigation":275,"path":5925,"published":275,"seo":5926,"slug":5927,"stem":5928,"tags":5929,"timeToRead":329,"__hash__":5932},"posts\u002Fposts\u002FXINX\u002F2011-05-03-xinx-0.10.1.md","XINX v0.10.1",{"type":9,"value":5621,"toc":5892},[5622,5625,5633,5650,5657,5661,5683,5687,5691,5697,5702,5713,5716,5719,5723,5726,5729,5746,5751,5754,5757,5761,5767,5770,5776,5779,5783,5789,5792,5795,5798,5806,5809,5813,5817,5826,5829,5833,5839,5842,5846,5852,5855,5859,5865,5868,5872,5875,5879,5882,5886,5889],[17,5623,5624],{},"Bonjour à tous,",[17,5626,5627,5628,5632],{},"Je suis heureux de vous annoncer la nouvelle version de ",[39,5629,4311],{"href":5630,"rel":5631},"http:\u002F\u002Fxinx.shadoware.org?piwik_campaign=20110504_0.10.1_blog",[43],". Cette\nversion apporte, en plus de la ré-écriture complète de la gestion du\ncontenu et de la complétion, son petit lot de nouveautés et de\ncorrections.",[17,5634,5635,5636,5639,5640,5643,5644,5649],{},"La version ",[32,5637,5638],{},"0.10.1"," est beaucoup plus stable que sa grande soeur ",[32,5641,5642],{},"0.9",".\nUn soin particulier a été apporté à la recherche des sources d'anomalie\npossible, ainsi que des fuites mémoires. Ces opérations ont été faites\ngrâce à des outils tels que ",[39,5645,5648],{"href":5646,"rel":5647},"http:\u002F\u002Fvalgrind.org\u002F",[43],"valgrind",", mais aussi grâce aux\nbéta-testeurs (Merci à eux).",[17,5651,5652,5653,5656],{},"De plus l'utilisation des pointeurs intelligents de ",[39,5654,3803],{"href":4298,"rel":5655},[43]," ont permis de\npasser plus de temps, sur la gestion des structures et moins de temps\nsur la gestion de la mémoire, sur des parties du code assez critiques\n(comme ContentView et CodeCompletion). Ils ont également permis un\npartage plus facile des structures entre les différents threads avec\nmoins de contrôle de synchronisation.",[12,5658,5660],{"id":5659},"liens","Liens",[162,5662,5663,5669,5676],{},[165,5664,5665],{},[39,5666,5668],{"href":5630,"rel":5667},[43],"Site Internet de XINX",[165,5670,5671],{},[39,5672,5675],{"href":5673,"rel":5674},"http:\u002F\u002Fxinx.shadoware.org\u002Fwiki\u002FDownload?piwik_campaign=20110504_0.10.1_blog",[43],"Téléchargement de XINX",[165,5677,5678],{},[39,5679,5682],{"href":5680,"rel":5681},"http:\u002F\u002Fxinx.shadoware.org\u002Fnewticket?piwik_campaign=20110504_0.10.1_blog",[43],"Faire une demande d'évolution ou reporter un bug",[12,5684,5686],{"id":5685},"gestion-projet-et-gestion-des-sessions","Gestion Projet et Gestion des sessions",[4389,5688,5690],{"id":5689},"multi-projet","Multi-projet",[17,5692,5693],{},[1445,5694],{"alt":5695,"src":5696},"Project","\u002FXINX\u002Fxinx-0.10.1\u002FprojectDirectory10.png",[17,5698,5699,5701],{},[1534,5700,4311],{}," est maintenant capable d'ouvrir plusieurs\nprojets en même temps. Cela permet donc plusieurs choses :",[162,5703,5704,5707,5710],{},[165,5705,5706],{},"Rechercher un fichier pouvant se trouver dans plusieurs projets\ndifférents (par exemple un projet trunk et un projet branche).",[165,5708,5709],{},"Comparer des fichiers venant de plusieurs projets différents.",[165,5711,5712],{},"Ne pas basculer d'un projet à l'autre en continu, lorsque l'on\ntravaille sur plusieurs projets en même temps.",[17,5714,5715],{},"A cause de cette gestion de plusieurs projets en même temps, toute la\npartie de gestion de projet de XINX a été ré-écrite (entre autre la\npartie concernant la session, que l'on verra ensuite).",[17,5717,5718],{},"De plus à l'ouverture du projet, l'application recherche l'ensemble des\nfichiers présents sur le disque afin de permettre une recherche beaucoup\nplus rapide. Cela a néanmoins quelques répercussions : il n'est pas\npossible de supprimer un dossier du projet sans fermer XINX.",[4389,5720,5722],{"id":5721},"inclusion-exclusion-de-chemin","Inclusion \u002F Exclusion de chemin",[17,5724,5725],{},"Afin d'avoir une vue propre, XINX affiche déjà uniquement les fichiers\nqu'il est capable de gérer. Il est également possible de lui définir une\nliste de chemin qu'il doit ignorer.",[17,5727,5728],{},"Exemple :",[162,5730,5731,5736,5741],{},[165,5732,5733],{},[63,5734,5735],{},"WEB-INF\u002Flib",[165,5737,5738],{},[63,5739,5740],{},"dico",[165,5742,5743],{},[63,5744,5745],{},"configuration",[17,5747,5748],{},[1445,5749],{"alt":5695,"src":5750},"\u002FXINX\u002Fxinx-0.10.1\u002FprojectpropertyIncludeExclude10.png",[17,5752,5753],{},"Il est possible d'utiliser des expressions régulières pour définir ces\nchemins.",[17,5755,5756],{},"A l'inverse il est possible d'inclure un dossier externe au projet\ndirectement dans la vue de celui-ci. L'équivalent d'un lien symbolique\nmais propre au projet sous XINX. Il est alors possible d'inclure dans le\ndossier projet, un répertoire temporaire contenant les données utilisées\npar les feuilles de styles, ou inclure un dossier contenant des fichiers\nde logs, ...",[4389,5758,5760],{"id":5759},"sessions","Sessions",[17,5762,5763],{},[1445,5764],{"alt":5765,"src":5766},"Welcom","\u002FXINX\u002Fxinx-0.10.1\u002FwelcomDialog10.png",[17,5768,5769],{},"Suite à la gestion du multi-projet, il a fallu ré-écrire\nle système de gestion des sessions. Il est maintenant plus proche des\nsystèmes de session des autres applications.",[17,5771,5772,5773,5775],{},"Alors que sur la version ",[32,5774,5642],{}," et précédente, la session était\ndirectement associée à un projet (et donc ouverte en même temps),\nmaintenant la session est séparée de la notion de projet.",[17,5777,5778],{},"Une session peut alors désormais contenir une liste de projet ouvert,\nune liste de fichier ouvert (associé ou non à un projet), des signets.\nPlusieurs sessions différentes peuvent pointer vers un même projet mais\nproposer une vue (un ensemble de fichier ouvert) différente. Une session\npar défaut est créée pour l'utilisation courante de l'application.",[12,5780,5782],{"id":5781},"modification-du-système-de-complétion","Modification du système de complétion",[17,5784,5785],{},[1445,5786],{"alt":5787,"src":5788},"Code","\u002FXINX\u002Fxinx-0.10.1\u002FCompletion10.png",[17,5790,5791],{},"Le système de vue contenue et de code complétion a\ncomplètement été ré-écrit. La lecture des différents imports des\ndifférents fichiers est faite en mémoire (et non plus dans une base de\ndonnée SQL) et en parallèle (s'il y a plusieurs processeurs sur la\nmachine). La lecture des fichiers est ainsi plus rapide. Le système a\ncomplètement été ré-écrit pour que la complétion du code soit rapide et\nstable en même temps.",[17,5793,5794],{},"La complétion du code affiche désormais les différentes lignes dans des\ncatégories suivant leur emplacement (par exemple le fichier où se trouve\nchaque template), les snipets dans une catégorie différente...",[17,5796,5797],{},"XINX est maintenant capable également de compléter",[162,5799,5800,5803],{},[165,5801,5802],{},"les paramètres des templates du type call-template",[165,5804,5805],{},"les imports (proposition des différents fichiers, et des alias si le\nplugin Generix est activé)",[17,5807,5808],{},"et plein d'autres choses :)",[12,5810,5812],{"id":5811},"et-plein-dautres-nouveautés","Et plein d'autres nouveautés",[4389,5814,5816],{"id":5815},"utilisation-de-la-librairie-svn-directement","Utilisation de la librairie SVN directement",[17,5818,5819,5820,5825],{},"Un nouveau plugin pour SubVersion a été écrit. Ce plugin utilise\ndirectement les librairies de SubVersion au lieu d'utiliser l'exécutable\nsvn. Ce plugin est plus performant que le wrapper et ne nécessite pas\nl'installation d'un client SubVersion (tel que ",[39,5821,5824],{"href":5822,"rel":5823},"http:\u002F\u002Fwww.collab.net\u002Fdownloads\u002Fsubversion\u002F",[43],"CollabNet SubVersion","\nsous Windows ou le client svn sous linux.",[17,5827,5828],{},"L'ancien plugin est toujours disponible et utilisable.",[4389,5830,5832],{"id":5831},"créer-des-tickets-depuis-xinx","Créer des tickets depuis XINX",[17,5834,5835],{},[1445,5836],{"alt":5837,"src":5838},"Create","\u002FXINX\u002Fxinx-0.10.1\u002FTicketCreation10.png",[17,5840,5841],{},"Une boite de dialogue permet maintenant de créer automatiquement un\ncompte et un ticket sur le site Internet de XINX. Vous pouvez ainsi\ncréer facilement des demandes d'évolution, des demandes de correction,\n...De plus lors de la sortie d'une nouvelle version, XINX vous informera\nautomatiquement qu'une nouvelle version est disponible.",[4389,5843,5845],{"id":5844},"dock-des-logs-et-des-erreurs","Dock des logs et des erreurs",[17,5847,5848],{},[1445,5849],{"alt":5850,"src":5851},"Error","\u002FXINX\u002Fxinx-0.10.1\u002FErrorLog10.png",[17,5853,5854],{},"Le dock d'affichage des erreurs a été amélioré pour ne plus perturber\nl'utilisateur en s'ouvrant de façon intempestive. Il est maintenant\npossible de définir que le dock doit rester fermé, un compteur affiche\nalors le nombre d'erreur .",[4389,5856,5858],{"id":5857},"modification-de-la-recherche","Modification de la recherche",[17,5860,5861],{},[1445,5862],{"alt":5863,"src":5864},"Search","\u002FXINX\u002Fxinx-0.10.1\u002FSearchDock10.png",[17,5866,5867],{},"Suite à la gestion du multi-projet, XINX peut maintenant rechercher dans\nplusieurs projets en même temps. Il est aussi possible d'arrêter la\nrecherche en plein milieu.",[4389,5869,5871],{"id":5870},"validation-dun-fichier-xml","Validation d'un fichier XML",[17,5873,5874],{},"XINX peut également valider un fichier XML à partir d'un schéma. Il ne\npeut malheureusement pas encore valider de fichier XSL (les parseurs XSL\ntrouvés n'arrivent pas à lire les schémas des fichiers XSLT).",[4389,5876,5878],{"id":5877},"correction-de-bugs","Correction de bugs",[17,5880,5881],{},"Beaucoup de corrections de bug ont été faites ce qui rend cette version\ntrès stable.",[12,5883,5885],{"id":5884},"et-pour-la-suite","Et pour la suite ?",[17,5887,5888],{},"Dans la même série, j'ai l'intention de sortir une version avec de\nnouveaux modèles, de la documentation, ....",[17,5890,5891],{},"Pour la version suivante, le moteur JavaScript sera amélioré pour ne\nplus donner d'erreur, voir proposer de la complétion plus performante.",{"title":61,"searchDepth":80,"depth":80,"links":5893},[5894,5895,5896,5897,5898],{"id":5659,"depth":89,"text":5660},{"id":5685,"depth":89,"text":5686},{"id":5781,"depth":89,"text":5782},{"id":5811,"depth":89,"text":5812},{"id":5884,"depth":89,"text":5885},"xinx","2011-05-03",{"type":9,"value":5902},[5903,5905,5910,5919],[17,5904,5624],{},[17,5906,5627,5907,5632],{},[39,5908,4311],{"href":5630,"rel":5909},[43],[17,5911,5635,5912,5639,5914,5643,5916,5649],{},[32,5913,5638],{},[32,5915,5642],{},[39,5917,5648],{"href":5646,"rel":5918},[43],[17,5920,5652,5921,5656],{},[39,5922,3803],{"href":4298,"rel":5923},[43],{},"\u002Fpost\u002Fxinx-0.10.1",{"title":5619,"description":5624},"xinx-0.10.1","posts\u002FXINX\u002F2011-05-03-xinx-0.10.1",[5899,5930,1592,5931],"generix-group","xml","wLQ73NHdvyayFYtxw7KT53sos1O0VxBKcuvImmDWUEQ",{"id":5934,"title":5935,"author":7,"body":5936,"category":1560,"categorySlug":1561,"date":9000,"description":61,"excerpt":9001,"extension":1584,"location":1585,"meta":9074,"navigation":275,"path":9075,"published":275,"seo":9076,"slug":9077,"stem":9078,"tags":9079,"timeToRead":558,"__hash__":9081},"posts\u002Fposts\u002FProgrammation\u002F2011-01-25-qt-performance-de-l-utilisation-de-qsharedpointer.md","C++\u002FQt - Performance de l'utilisation de QSharedPointer",{"type":9,"value":5937,"toc":8993},[5938,5940,5949,5969,5978,6039,6043,6047,6051,6064,6075,6081,6085,6106,6131,6229,6236,6246,6251,6295,6301,6325,6336,6350,6380,6399,6454,6467,6473,6482,6547,6557,6563,6609,6631,6637,6775,6791,6799,6816,6819,6968,6991,6998,7071,7075,7078,7081,7364,7367,7644,7647,7653,7656,7659,7782,7804,7808,7819,7836,7849,7853,7862,7870,8016,8031,8049,8143,8146,8149,8179,8183,8189,8203,8206,8210,8217,8220,8234,8237,8256,8259,8273,8277,8281,8290,8293,8303,8427,8496,8500,8503,8525,8529,8535,8599,8603,8610,8616,8657,8660,8717,8721,8724,8828,8834,8837,8840,8844,8851,8868,8990],[12,5939,3514],{"id":3513},[17,5941,5942,5944,5945,5948],{},[32,5943,3803],{}," est un framework orienté objet écrit en C++ et permettant de faire\ndes interfaces graphiques. Ce framework est utilisé par le projet ",[32,5946,5947],{},"KDE","\ndepuis ses débuts pour en faire un environnement de bureau très complet.",[17,5950,5951,5953,5954,5957,5962,5963,5965,5966,5968],{},[32,5952,3803],{}," fournit un ensemble de pointeur ",[32,5955,5956],{},"intelligent",[1607,5958,5959],{},[39,5960,461],{"href":1611,"ariaDescribedBy":5961,"dataFootnoteRef":61,"id":1614},[1613]," permettant\nde gérer plus facilement la mémoire. Le but est alors de ne plus avoir à\nsupprimer des objets. La suppression se fera soit par un pointeur\n",[32,5964,5956],{}," soit par le système de hiérarchie d'objet existant en ",[32,5967,3803],{},"\n(l'objet père qui supprime l'ensemble des objets fils qui lui sont\nrattachés).",[17,5970,5971,5973,5974,5977],{},[32,5972,3803],{}," propose l'ensemble des pointeurs ",[32,5975,5976],{},"intelligents"," suivants:",[162,5979,5980,6003,6017,6025],{},[165,5981,5982,5987,5988,5993,5994,5997,5998,44],{},[39,5983,5986],{"href":5984,"rel":5985},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqshareddatapointer.html",[43],"QSharedDataPointer"," \u002F ",[39,5989,5992],{"href":5990,"rel":5991},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqshareddata.html",[43],"QSharedData"," : ces deux classes\nutilisées ensemble permettent d'écrire un objet avec partage\nimplicite. Cela signifie que l'objet fonctionnera comme la classe\n",[32,5995,5996],{},"QString",". Tant que l'objet est copié, passé en paramètre, ....\nl'objet n'est pas dupliqué (tous les objets pointes vers le même\nespace mémoire). Au moment où l'objet est modifié, l'objet est\ndupliqué. C'est ce qu'on appelle le COW",[1607,5999,6000],{},[39,6001,476],{"href":1637,"ariaDescribedBy":6002,"dataFootnoteRef":61,"id":1639},[1613],[165,6004,6005,5987,6010,6013,6014,6016],{},[39,6006,6009],{"href":6007,"rel":6008},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqexplicitlyshareddatapointer.html",[43],"QExplictlySharedDataPointer",[39,6011,5992],{"href":5990,"rel":6012},[43]," :\nQExplicitlySharedDataPointer est une variante de QSharedDataPointer.\nCe pointeur ",[32,6015,5956],{},", comme son nom l'indique, est détaché\nuniquement lorsque la méthode detach() est appelée explicitement.\nCette classe permet de faire des objets qui fonctionnent comme des\npointeurs mais qui sont utilisés sans la notion de pointeur (le *).\nLa suppression des données partagées se fait donc quand tous les\nobjets ne sont plus utilisés.",[165,6018,6019,6024],{},[39,6020,6023],{"href":6021,"rel":6022},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqscopedpointer.html",[43],"QScopedPointer"," : Ce pointeur est le plus simple. Il permet de\ndéclarer un pointeur sur le tas et s'occupe de la destruction de\nl'objet, lorsque le programme sort de la portée du bloc. Cela permet\nde ne plus se soucier de la libération du pointeur dans les cas\nd'erreur (exception, retour avant la fin de la fonction car le\nfichier n'a pu être ouvert, ...).",[165,6026,6027,6032,6033,6038],{},[39,6028,6031],{"href":6029,"rel":6030},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqsharedpointer.html",[43],"QSharedPointer"," : Le pointeur dont on parlera dans la suite de ce\nbillet. Il permet de partager non plus des données (comme le fait\nQSharedData) mais de partager un pointeur",[1607,6034,6035],{},[39,6036,1651],{"href":1648,"ariaDescribedBy":6037,"dataFootnoteRef":61,"id":1650},[1613],". Nous allons voir\ndans la suite du billet, comment simplement utiliser ce pointeur, et\nles performances de ce pointeur par rapport à un pointeur standard.",[12,6040,6042],{"id":6041},"sommaire","Sommaire",[12,6044,6046],{"id":6045},"utilisation-de-qsharedpointer","Utilisation de QSharedPointer",[4389,6048,6050],{"id":6049},"a-quoi-sert-il","A quoi sert-il ?",[17,6052,6053,6054,6056,6057,6059,6060,6063],{},"L'objet ",[63,6055,6031],{}," fait partie des pointeurs ",[32,6058,5976],{},". Ces\npointeurs permettent de gérer automatiquement la libération de la\nmémoire (plus besoin de faire ",[63,6061,6062],{},"delete ptr;"," quand le pointeur n'est plus\nutilisé) tout en restant utilisable comme un pointeur normal.",[17,6065,6066,6068,6069,6071,6072,6074],{},[63,6067,6031],{}," fonctionne par comptage de référence. Après la\ndéclaration, à chaque affectation, on augmente le compteur de référence,\nlorsqu'on quitte la portée du bloc, on décrémente le compteur de\nréférence. ",[63,6070,6031],{}," détruit donc automatiquement le pointeur\nquand il n'existe plus aucune référence vers ce pointeur.\n",[63,6073,6031],{}," vient donc comme une encapsulation de notre pointeur.",[17,6076,6077],{},[1445,6078],{"alt":6079,"src":6080},"QSharedPointer vers la même adresse","\u002FProgrammation\u002Fqt-performance-de-l-utilisation-de-qsharedpointer\u002FQSharedPointer1.png",[4389,6082,6084],{"id":6083},"comment-lutiliser","Comment l'utiliser ?",[17,6086,6087,6088,6091,6092,6095,6096,6099,6100,6102,6103,6105],{},"La déclaration d'un pointeur en C, se fait en écrivant ",[63,6089,6090],{},"MyObject*",". La\nsyntaxe en utilisant un QSharedPointer se fait en écrivant\n",[63,6093,6094],{},"QSharedPointer\u003CMyObject>",". Par la suite dans le programme,\nl'utilisation du pointeur ",[63,6097,6098],{},"QSharedObject"," se fera de la même manière\nqu'un pointeur C. (Avec l'opérateur ",[63,6101,2829],{}," pour appeler un membre, une\nméthode, ...) . Appelons dans la suite pointeur C, les pointeurs\nstandards et ",[63,6104,6031],{},", le pointeur intelligent.",[17,6107,6108,6109,6111,6112,6115,6116,6118,6119,6121,6122,6125,6126,44],{},"Afin d'éviter d'avoir un pointeur normal pouvant être supprimé à tout\nmoment dans l'application, lors de l'utilisation de ",[63,6110,6031],{},", il\nne faut utiliser le pointeur C résultant du ",[63,6113,6114],{},"new"," que pour la création\ndu ",[63,6117,6031],{},". On peut donc directement créer le ",[63,6120,6031],{},"\nen utilisant le constructeur ",[63,6123,6124],{},"QSharedPointer ( T * ptr )"," qui prend en\nparamètre le pointeur C. C'est entre ces parenthèses que nous allons\ncréer le pointeur C",[1607,6127,6128],{},[39,6129,1682],{"href":1679,"ariaDescribedBy":6130,"dataFootnoteRef":61,"id":1681},[1613],[56,6132,6134],{"className":214,"code":6133,"language":216,"meta":61,"style":61},"{\n    \u002F\u002F Création du pointeur intelligent à partir d'un pointeur normal.\n    QSharedPointer\u003CMyObject> ptr(new MyObject());\n\n    \u002F\u002F Utilisation du pointeur intelligent comme un pointeur normal.\n    if (ptr)\n    {\n        ptr->setMembre(maValeur);\n    }\n\n    \u002F\u002F Appel d'une méthode utilisant ce pointeur\n    maMethode(ptr);\n}\n",[63,6135,6136,6140,6145,6170,6174,6179,6186,6191,6204,6208,6212,6217,6225],{"__ignoreMap":61},[66,6137,6138],{"class":68,"line":69},[66,6139,1924],{"class":230},[66,6141,6142],{"class":68,"line":80},[66,6143,6144],{"class":351},"    \u002F\u002F Création du pointeur intelligent à partir d'un pointeur normal.\n",[66,6146,6147,6150,6152,6155,6158,6161,6163,6165,6168],{"class":68,"line":89},[66,6148,6149],{"class":230},"    QSharedPointer",[66,6151,532],{"class":223},[66,6153,6154],{"class":230},"MyObject",[66,6156,6157],{"class":223},">",[66,6159,6160],{"class":72}," ptr",[66,6162,231],{"class":230},[66,6164,6114],{"class":223},[66,6166,6167],{"class":72}," MyObject",[66,6169,604],{"class":230},[66,6171,6172],{"class":68,"line":279},[66,6173,276],{"emptyLinePlaceholder":275},[66,6175,6176],{"class":68,"line":307},[66,6177,6178],{"class":351},"    \u002F\u002F Utilisation du pointeur intelligent comme un pointeur normal.\n",[66,6180,6181,6183],{"class":68,"line":329},[66,6182,493],{"class":223},[66,6184,6185],{"class":230}," (ptr)\n",[66,6187,6188],{"class":68,"line":334},[66,6189,6190],{"class":230},"    {\n",[66,6192,6193,6196,6198,6201],{"class":68,"line":340},[66,6194,6195],{"class":240},"        ptr",[66,6197,2829],{"class":230},[66,6199,6200],{"class":72},"setMembre",[66,6202,6203],{"class":230},"(maValeur);\n",[66,6205,6206],{"class":68,"line":355},[66,6207,656],{"class":230},[66,6209,6210],{"class":68,"line":372},[66,6211,276],{"emptyLinePlaceholder":275},[66,6213,6214],{"class":68,"line":395},[66,6215,6216],{"class":351},"    \u002F\u002F Appel d'une méthode utilisant ce pointeur\n",[66,6218,6219,6222],{"class":68,"line":400},[66,6220,6221],{"class":72},"    maMethode",[66,6223,6224],{"class":230},"(ptr);\n",[66,6226,6227],{"class":68,"line":416},[66,6228,1413],{"class":230},[17,6230,6231,6232,6235],{},"Lorsque l'on quitte le bloc, si le comptage de référence tombe à 0, on\nsupprime le pointeur. A l'intérieur de ",[63,6233,6234],{},"maMethode()"," le nombre de\nréférence sera passé à 2. Si la méthode utilise le pointeur mais ne\nl'assigne nul part, le nombre de référence devrait être retombé à 1 et\ndonc ici sera décrémenté à 0.",[17,6237,6238,6239,6241,6242,6245],{},"Si par contre, ",[63,6240,6234],{}," fait des opérations d'assignation de ",[63,6243,6244],{},"ptr","\net conserve une copie, le comptage ne tombera pas à 0 tant que l'objet\nrestera utilisé (assigné) ailleurs.",[17,6247,6248,6249,4405],{},"Regardons un exemple de ",[63,6250,6234],{},[56,6252,6254],{"className":214,"code":6253,"language":216,"meta":61,"style":61},"void maMethode(QSharedPointer\u003CMyObject> ptr)\n{\n    ptr->setMembre2(maValeur);\n",[63,6255,6256,6279,6283],{"__ignoreMap":61},[66,6257,6258,6261,6264,6266,6268,6270,6272,6275,6277],{"class":68,"line":69},[66,6259,6260],{"class":223},"void",[66,6262,6263],{"class":72}," maMethode",[66,6265,231],{"class":230},[66,6267,6031],{"class":240},[66,6269,532],{"class":230},[66,6271,6154],{"class":240},[66,6273,6274],{"class":230},"> ",[66,6276,6244],{"class":247},[66,6278,1784],{"class":230},[66,6280,6281],{"class":68,"line":80},[66,6282,1924],{"class":230},[66,6284,6285,6288,6290,6293],{"class":68,"line":89},[66,6286,6287],{"class":240},"    ptr",[66,6289,2829],{"class":230},[66,6291,6292],{"class":72},"setMembre2",[66,6294,6203],{"class":230},[17,6296,6297,6298,6300],{},"Au début du bloc, ici le comptage de référence est à 2 et sera\ndécrémenté à la sortie de la méthode. On peut modifier les membres de\n",[63,6299,6244],{},", et dans ce cas pas de changement du comptage de référence.",[56,6302,6304],{"className":214,"code":6303,"language":216,"meta":61,"style":61},"    this->monPtr = ptr;\n}\n",[63,6305,6306,6321],{"__ignoreMap":61},[66,6307,6308,6311,6313,6316,6318],{"class":68,"line":69},[66,6309,6310],{"class":240},"    this",[66,6312,2829],{"class":230},[66,6314,6315],{"class":437},"monPtr",[66,6317,2883],{"class":223},[66,6319,6320],{"class":230}," ptr;\n",[66,6322,6323],{"class":68,"line":80},[66,6324,1413],{"class":230},[17,6326,6327,6328,6331,6332,6335],{},"Au contraire, on peut également l'assigner à un autre objet. Dans ce cas\nle comptage de référence de cet objet passera à 3. A la sortie de la\nméthode il sera décrémenté et passera alors à 2. L'objet ne sera pas\nsupprimé tant qu'on ne fera pas un ",[63,6329,6330],{},"this->monPtr.clear()"," ou que ",[63,6333,6334],{},"this","\nne sera pas détruit.",[17,6337,6338,6339,6341,6342,6345,6346,6349],{},"Si on veut garder une référence d'un pointeur mais qu'on ne souhaite pas\nque celle-ci incrémente le nombre de référence du ",[63,6340,6031],{},", il\nest possible de créer un pointeur ",[32,6343,6344],{},"faible",". Ce pointeur passe par\nl'objet ",[63,6347,6348],{},"QWeakPointer",". Pour obtenir ce type de pointeur, il suffit de\nfaire :",[56,6351,6353],{"className":214,"code":6352,"language":216,"meta":61,"style":61},"QWeakPointer\u003CMyObject> ptrW = ptr->toWeakRef ();\n",[63,6354,6355],{"__ignoreMap":61},[66,6356,6357,6359,6361,6363,6365,6368,6370,6372,6374,6377],{"class":68,"line":69},[66,6358,6348],{"class":230},[66,6360,532],{"class":223},[66,6362,6154],{"class":230},[66,6364,6157],{"class":223},[66,6366,6367],{"class":230}," ptrW ",[66,6369,378],{"class":223},[66,6371,6160],{"class":240},[66,6373,2829],{"class":230},[66,6375,6376],{"class":72},"toWeakRef",[66,6378,6379],{"class":230}," ();\n",[17,6381,6382,6385,6386,6388,6389,6392,6393,6395,6396,44],{},[63,6383,6384],{},"ptrW"," n'incrémente donc pas le comptage de référence, cela signifie\ndonc que le pointeur peut être détruit même si un objet ",[63,6387,6348],{},"\nexiste. Il sera alors possible de faire un ",[63,6390,6391],{},"ptrW.isNull()"," pour savoir\nsi le pointeur est toujours valide. Si l'utilisateur a également besoin\nd'avoir accès à un membre de l'objet, il pourra le transformer en\n",[63,6394,6031],{}," avant de l'utiliser sauf si le pointeur est ",[63,6397,6398],{},"null",[56,6400,6402],{"className":214,"code":6401,"language":216,"meta":61,"style":61},"QSharedPointer\u003CMyObject> ptr2 = ptrW->toStrongRef ();\nif (ptr)\n{\n    ptr->maMethodePtr();\n}\n",[63,6403,6404,6429,6435,6439,6450],{"__ignoreMap":61},[66,6405,6406,6408,6410,6412,6414,6417,6419,6422,6424,6427],{"class":68,"line":69},[66,6407,6031],{"class":230},[66,6409,532],{"class":223},[66,6411,6154],{"class":230},[66,6413,6157],{"class":223},[66,6415,6416],{"class":230}," ptr2 ",[66,6418,378],{"class":223},[66,6420,6421],{"class":240}," ptrW",[66,6423,2829],{"class":230},[66,6425,6426],{"class":72},"toStrongRef",[66,6428,6379],{"class":230},[66,6430,6431,6433],{"class":68,"line":80},[66,6432,4791],{"class":223},[66,6434,6185],{"class":230},[66,6436,6437],{"class":68,"line":89},[66,6438,1924],{"class":230},[66,6440,6441,6443,6445,6448],{"class":68,"line":279},[66,6442,6287],{"class":240},[66,6444,2829],{"class":230},[66,6446,6447],{"class":72},"maMethodePtr",[66,6449,543],{"class":230},[66,6451,6452],{"class":68,"line":307},[66,6453,1413],{"class":230},[17,6455,6456,6457,6460,6461,6463,6464,6466],{},"Il faut tester que ",[63,6458,6459],{},"ptr2"," est encore valide, car tant que la\ntransformation du pointeur ",[32,6462,6344],{}," vers le ",[63,6465,6031],{}," n'a pas\nencore été fait, il est possible que le nombre de référence vers l'objet\nsoit tombé à 0 et qu'il ait été supprimé.",[4389,6468,6470,6471],{"id":6469},"comment-utiliser-this","Comment utiliser ",[63,6472,6334],{},[17,6474,6475,6476,6478,6479,6481],{},"Un des points peu pratique de l'utilisation de ",[63,6477,6031],{}," est que\nle comptage de référence ne fonctionne pas si plusieurs ",[63,6480,6031],{},"\npointent vers le même objet mais ont tous été créés à partir du pointeur\nC. Prenons par exemple, le cas suivant :",[56,6483,6485],{"className":214,"code":6484,"language":216,"meta":61,"style":61},"MyObject * ptr = new MyObject();\n\nQSharedPointer\u003CMyObject> ptr1 = QSharedPointer(ptr);\nQSharedPointer\u003CMyObject> ptr2 = QSharedPointer(ptr);\n",[63,6486,6487,6505,6509,6529],{"__ignoreMap":61},[66,6488,6489,6492,6494,6497,6499,6501,6503],{"class":68,"line":69},[66,6490,6491],{"class":230},"MyObject ",[66,6493,593],{"class":223},[66,6495,6496],{"class":230}," ptr ",[66,6498,378],{"class":223},[66,6500,2811],{"class":223},[66,6502,6167],{"class":72},[66,6504,543],{"class":230},[66,6506,6507],{"class":68,"line":80},[66,6508,276],{"emptyLinePlaceholder":275},[66,6510,6511,6513,6515,6517,6519,6522,6524,6527],{"class":68,"line":89},[66,6512,6031],{"class":230},[66,6514,532],{"class":223},[66,6516,6154],{"class":230},[66,6518,6157],{"class":223},[66,6520,6521],{"class":230}," ptr1 ",[66,6523,378],{"class":223},[66,6525,6526],{"class":72}," QSharedPointer",[66,6528,6224],{"class":230},[66,6530,6531,6533,6535,6537,6539,6541,6543,6545],{"class":68,"line":279},[66,6532,6031],{"class":230},[66,6534,532],{"class":223},[66,6536,6154],{"class":230},[66,6538,6157],{"class":223},[66,6540,6416],{"class":230},[66,6542,378],{"class":223},[66,6544,6526],{"class":72},[66,6546,6224],{"class":230},[17,6548,6549,6550,6553,6554,6556],{},"Le problème d'écrire ces lignes ainsi, et que pour ",[63,6551,6552],{},"ptr1"," comme pour\n",[63,6555,6459],{},", l'objet n'est référencé qu'une fois. Ainsi le premier qui\ntombera à 0 détruira l'objet, alors que l'autre pourrait encore\nl'utiliser. Il faut donc écrire les choses comme suite :",[17,6558,6559],{},[1445,6560],{"alt":6561,"src":6562},"Deux QSharedPointer créé vers la même adresse","\u002FProgrammation\u002Fqt-performance-de-l-utilisation-de-qsharedpointer\u002FQSharedPointer2.png",[56,6564,6566],{"className":214,"code":6565,"language":216,"meta":61,"style":61},"QSharedPointer\u003CMyObject> ptr1 = QSharedPointer(new MyObject());\nQSharedPointer\u003CMyObject> ptr2 = ptr1;\n",[63,6567,6568,6592],{"__ignoreMap":61},[66,6569,6570,6572,6574,6576,6578,6580,6582,6584,6586,6588,6590],{"class":68,"line":69},[66,6571,6031],{"class":230},[66,6573,532],{"class":223},[66,6575,6154],{"class":230},[66,6577,6157],{"class":223},[66,6579,6521],{"class":230},[66,6581,378],{"class":223},[66,6583,6526],{"class":72},[66,6585,231],{"class":230},[66,6587,6114],{"class":223},[66,6589,6167],{"class":72},[66,6591,604],{"class":230},[66,6593,6594,6596,6598,6600,6602,6604,6606],{"class":68,"line":80},[66,6595,6031],{"class":230},[66,6597,532],{"class":223},[66,6599,6154],{"class":230},[66,6601,6157],{"class":223},[66,6603,6416],{"class":230},[66,6605,378],{"class":223},[66,6607,6608],{"class":230}," ptr1;\n",[17,6610,6611,6612,3581,6614,6616,6617,6619,6620,6622,6623,6625,6626,6628,6629,44],{},"Ainsi ",[63,6613,6552],{},[63,6615,6459],{}," ont bien chacun connaissance de l'existence de\nl'autre. Cela contraint donc à remplacer toutes les déclarations du type\n",[63,6618,6090],{}," par ",[63,6621,6094],{},". Ceci est donc à faire dans\nles paramètres des méthodes, dans les membres, dans la déclaration des\nvariables locales, ... . On ne peut donc plus utiliser le pointeur C\n",[63,6624,6090],{}," directement, mais seulement au travers de ",[63,6627,6031],{},"\nou de ",[63,6630,6348],{},[17,6632,6633,6634,6636],{},"Cela commence à poser problème lors de l'utilisation de ",[63,6635,6334],{}," dans un\nobjet. Imaginons une méthode d'un objet mettant à jour des membres fils\navec en paramètre le père. Nous aurions alors tendance à écrire ceci :",[56,6638,6640],{"className":214,"code":6639,"language":216,"meta":61,"style":61},"void Object2::setParent(QSharedPointer\u003CMyObject> parent)\n{\n    ...\n}\n\n....\n\nvoid MyObject::setMember(Object2 * obj)\n{\n    _membre = obj;\n    if (obj)\n    {\n        obj->setParent(QSharedPointer\u003CMyObject>(this));\n    }\n}\n",[63,6641,6642,6669,6673,6678,6682,6686,6691,6695,6718,6722,6732,6739,6743,6767,6771],{"__ignoreMap":61},[66,6643,6644,6646,6649,6651,6654,6656,6658,6660,6662,6664,6667],{"class":68,"line":69},[66,6645,6260],{"class":223},[66,6647,6648],{"class":240}," Object2",[66,6650,1001],{"class":230},[66,6652,6653],{"class":72},"setParent",[66,6655,231],{"class":230},[66,6657,6031],{"class":240},[66,6659,532],{"class":230},[66,6661,6154],{"class":240},[66,6663,6274],{"class":230},[66,6665,6666],{"class":247},"parent",[66,6668,1784],{"class":230},[66,6670,6671],{"class":68,"line":80},[66,6672,1924],{"class":230},[66,6674,6675],{"class":68,"line":89},[66,6676,6677],{"class":230},"    ...\n",[66,6679,6680],{"class":68,"line":279},[66,6681,1413],{"class":230},[66,6683,6684],{"class":68,"line":307},[66,6685,276],{"emptyLinePlaceholder":275},[66,6687,6688],{"class":68,"line":329},[66,6689,6690],{"class":230},"....\n",[66,6692,6693],{"class":68,"line":334},[66,6694,276],{"emptyLinePlaceholder":275},[66,6696,6697,6699,6701,6703,6706,6708,6711,6713,6716],{"class":68,"line":340},[66,6698,6260],{"class":223},[66,6700,6167],{"class":240},[66,6702,1001],{"class":230},[66,6704,6705],{"class":72},"setMember",[66,6707,231],{"class":230},[66,6709,6710],{"class":240},"Object2",[66,6712,620],{"class":223},[66,6714,6715],{"class":247}," obj",[66,6717,1784],{"class":230},[66,6719,6720],{"class":68,"line":355},[66,6721,1924],{"class":230},[66,6723,6724,6727,6729],{"class":68,"line":372},[66,6725,6726],{"class":230},"    _membre ",[66,6728,378],{"class":223},[66,6730,6731],{"class":230}," obj;\n",[66,6733,6734,6736],{"class":68,"line":395},[66,6735,493],{"class":223},[66,6737,6738],{"class":230}," (obj)\n",[66,6740,6741],{"class":68,"line":400},[66,6742,6190],{"class":230},[66,6744,6745,6748,6750,6752,6754,6756,6758,6760,6763,6765],{"class":68,"line":416},[66,6746,6747],{"class":240},"        obj",[66,6749,2829],{"class":230},[66,6751,6653],{"class":72},[66,6753,231],{"class":230},[66,6755,6031],{"class":72},[66,6757,532],{"class":230},[66,6759,6154],{"class":240},[66,6761,6762],{"class":230},">(",[66,6764,6334],{"class":240},[66,6766,304],{"class":230},[66,6768,6769],{"class":68,"line":421},[66,6770,656],{"class":230},[66,6772,6773],{"class":68,"line":485},[66,6774,1413],{"class":230},[17,6776,6777,6778,6780,6781,3438,6786,6788,6789,44],{},"Ceci ne marchera pas car on créerait un nouvel objet ",[63,6779,6031],{},"\ncommençant son comptage de référence à 1, alors que nous en avons déjà\nau moins un autre pointant vers notre instance",[1607,6782,6783],{},[39,6784,1699],{"href":1696,"ariaDescribedBy":6785,"dataFootnoteRef":61,"id":1698},[1613],[63,6787,6154],{},"\npourrait alors être détruit alors qu'il est encore utilisé par\n",[63,6790,6710],{},[17,6792,6793,6794,6796,6798],{},"Pour éviter cela, il faut alors passer par un pointeur ",[32,6795,5956],{},[63,6797,6334],{},". Pour cela nous allons utiliser deux choses :",[162,6800,6801,6813],{},[165,6802,6803,6804,6807,6808,6810,6812],{},"Un membre nommé ",[63,6805,6806],{},"_this"," de type pointeur ",[32,6809,5956],{},[63,6811,6348],{},", contenant une référence à l'objet lui même. (Nous\nn'utilisons pas un QSharedPointer, pour éviter une référence\ncirculaire, voir le paragraphe suivant).",[165,6814,6815],{},"Une méthode statique utilisée pour la création (nous n'allons plus\nutiliser le constructeur, car à ce moment, il n'existe pas encore de\nQSharedPointer pointant vers notre objet).",[17,6817,6818],{},"Voici un exemple de comment écrire le constructeur maison :",[56,6820,6822],{"className":214,"code":6821,"language":216,"meta":61,"style":61},"class MyObject\n{\npublic:\n    static QSharedPointer\u003CMyObject> create(QString parametre)\n    {\n        QSharedPointer\u003CMyObject> ptr(new MyObject(parametre);\n        ptr->_this = ptr.toWeakRef();\n        return ptr;\n    }\nprivate:\n    MyObject(QString parametre)\n    {\n        ...\n    }\n\n    QWeakPointer\u003CMyObject> _this;\n};\n",[63,6823,6824,6832,6836,6841,6866,6870,6892,6910,6916,6920,6925,6933,6937,6942,6946,6950,6964],{"__ignoreMap":61},[66,6825,6826,6829],{"class":68,"line":69},[66,6827,6828],{"class":223},"class",[66,6830,6831],{"class":240}," MyObject\n",[66,6833,6834],{"class":68,"line":80},[66,6835,1924],{"class":230},[66,6837,6838],{"class":68,"line":89},[66,6839,6840],{"class":223},"public:\n",[66,6842,6843,6846,6848,6850,6852,6854,6857,6859,6861,6864],{"class":68,"line":279},[66,6844,6845],{"class":223},"    static",[66,6847,6526],{"class":240},[66,6849,532],{"class":230},[66,6851,6154],{"class":240},[66,6853,6274],{"class":230},[66,6855,6856],{"class":72},"create",[66,6858,231],{"class":230},[66,6860,5996],{"class":240},[66,6862,6863],{"class":247}," parametre",[66,6865,1784],{"class":230},[66,6867,6868],{"class":68,"line":307},[66,6869,6190],{"class":230},[66,6871,6872,6875,6877,6879,6881,6883,6885,6887,6889],{"class":68,"line":329},[66,6873,6874],{"class":230},"        QSharedPointer",[66,6876,532],{"class":223},[66,6878,6154],{"class":230},[66,6880,6157],{"class":223},[66,6882,6160],{"class":72},[66,6884,231],{"class":230},[66,6886,6114],{"class":223},[66,6888,6167],{"class":72},[66,6890,6891],{"class":230},"(parametre);\n",[66,6893,6894,6896,6898,6900,6902,6904,6906,6908],{"class":68,"line":334},[66,6895,6195],{"class":240},[66,6897,2829],{"class":230},[66,6899,6806],{"class":437},[66,6901,2883],{"class":223},[66,6903,6160],{"class":240},[66,6905,44],{"class":230},[66,6907,6376],{"class":72},[66,6909,543],{"class":230},[66,6911,6912,6914],{"class":68,"line":340},[66,6913,523],{"class":223},[66,6915,6320],{"class":230},[66,6917,6918],{"class":68,"line":355},[66,6919,656],{"class":230},[66,6921,6922],{"class":68,"line":372},[66,6923,6924],{"class":230},"private:\n",[66,6926,6927,6930],{"class":68,"line":395},[66,6928,6929],{"class":72},"    MyObject",[66,6931,6932],{"class":230},"(QString parametre)\n",[66,6934,6935],{"class":68,"line":400},[66,6936,6190],{"class":230},[66,6938,6939],{"class":68,"line":416},[66,6940,6941],{"class":230},"        ...\n",[66,6943,6944],{"class":68,"line":421},[66,6945,656],{"class":230},[66,6947,6948],{"class":68,"line":485},[66,6949,276],{"emptyLinePlaceholder":275},[66,6951,6952,6955,6957,6959,6961],{"class":68,"line":490},[66,6953,6954],{"class":230},"    QWeakPointer",[66,6956,532],{"class":223},[66,6958,6154],{"class":230},[66,6960,6157],{"class":223},[66,6962,6963],{"class":230}," _this;\n",[66,6965,6966],{"class":68,"line":520},[66,6967,906],{"class":230},[17,6969,6970,6971,6973,6974,6976,6977,6979,6980,6982,6983,6985,6986,6988,6989,44],{},"Le constructeur devient alors privé (ou protégé si on a besoin de la\nnotion d'héritage) afin d'obliger l'utilisateur de la classe à utiliser\nnotre méthode de création. Dans notre nouvelle méthode de création\n",[63,6972,6856],{},", qui est une méthode statique, nous allons créer le pointeur et\ninitialiser le ",[63,6975,6348],{}," de notre objet avec le pointeur\n",[32,6978,5956],{}," que nous venons de créer. Nous retournons un\n",[63,6981,6031],{},". La méthode ",[63,6984,6856],{}," devient alors notre nouveau\nconstructeur, mais créant des instances d'objets de type\n",[63,6987,6094],{}," et non plus des instances d'objet\n",[63,6990,6090],{},[17,6992,6993,6994,6997],{},"Notre méthode ",[63,6995,6996],{},"setMember()"," peut alors être ré-écrite :",[56,6999,7001],{"className":214,"code":7000,"language":216,"meta":61,"style":61},"void MyObject::setMember(Object2 * obj)\n{\n    _membre = obj;\n    if (obj)\n    {\n        obj->setParent(_this.toStrongRef());\n    }\n}\n",[63,7002,7003,7023,7027,7035,7041,7045,7063,7067],{"__ignoreMap":61},[66,7004,7005,7007,7009,7011,7013,7015,7017,7019,7021],{"class":68,"line":69},[66,7006,6260],{"class":223},[66,7008,6167],{"class":240},[66,7010,1001],{"class":230},[66,7012,6705],{"class":72},[66,7014,231],{"class":230},[66,7016,6710],{"class":240},[66,7018,620],{"class":223},[66,7020,6715],{"class":247},[66,7022,1784],{"class":230},[66,7024,7025],{"class":68,"line":80},[66,7026,1924],{"class":230},[66,7028,7029,7031,7033],{"class":68,"line":89},[66,7030,6726],{"class":230},[66,7032,378],{"class":223},[66,7034,6731],{"class":230},[66,7036,7037,7039],{"class":68,"line":279},[66,7038,493],{"class":223},[66,7040,6738],{"class":230},[66,7042,7043],{"class":68,"line":307},[66,7044,6190],{"class":230},[66,7046,7047,7049,7051,7053,7055,7057,7059,7061],{"class":68,"line":329},[66,7048,6747],{"class":240},[66,7050,2829],{"class":230},[66,7052,6653],{"class":72},[66,7054,231],{"class":230},[66,7056,6806],{"class":240},[66,7058,44],{"class":230},[66,7060,6426],{"class":72},[66,7062,604],{"class":230},[66,7064,7065],{"class":68,"line":334},[66,7066,656],{"class":230},[66,7068,7069],{"class":68,"line":340},[66,7070,1413],{"class":230},[4389,7072,7074],{"id":7073},"comment-éviter-les-références-circulaires","Comment éviter les références circulaires",[17,7076,7077],{},"Le principe d'une référence circulaire est qu'un objet A référence\nl'objet B et l'objet B référence l'objet A.",[17,7079,7080],{},"Voici par exemple, un cas de référence circulaire :",[56,7082,7084],{"className":214,"code":7083,"language":216,"meta":61,"style":61},"class A\n{\npublic:\n    static create()\n    {\n        QSharedPointer\u003CA> ptr(new A());\n        return ptr;\n    }\n    ~A()\n    {\n    }\nprivate:\n    A()\n    {\n        b = B::create();\n        b->setA(_this);\n    }\n    QSharedPointer\u003CB> b;\n    QWeakPointer\u003CA> _this;\n};\n\nclass B\n{\npublic:\n    static QSharedPointer\u003CB> create()\n    {\n        QSharedPointer\u003CB> ptr(new B());\n        return ptr;\n    }\n    void setA(QSharedPointer\u003CA> b);\n    QSharedPointer\u003CA> getA();\nprivate:\n    QSharedPointer\u003CA>  a;\n};\n",[63,7085,7086,7093,7097,7101,7110,7114,7135,7141,7145,7152,7156,7160,7164,7171,7175,7189,7202,7206,7220,7232,7236,7240,7247,7251,7255,7271,7275,7296,7302,7306,7328,7343,7347,7360],{"__ignoreMap":61},[66,7087,7088,7090],{"class":68,"line":69},[66,7089,6828],{"class":223},[66,7091,7092],{"class":240}," A\n",[66,7094,7095],{"class":68,"line":80},[66,7096,1924],{"class":230},[66,7098,7099],{"class":68,"line":89},[66,7100,6840],{"class":223},[66,7102,7103,7105,7108],{"class":68,"line":279},[66,7104,6845],{"class":223},[66,7106,7107],{"class":72}," create",[66,7109,4820],{"class":230},[66,7111,7112],{"class":68,"line":307},[66,7113,6190],{"class":230},[66,7115,7116,7118,7120,7123,7125,7127,7129,7131,7133],{"class":68,"line":329},[66,7117,6874],{"class":230},[66,7119,532],{"class":223},[66,7121,7122],{"class":230},"A",[66,7124,6157],{"class":223},[66,7126,6160],{"class":72},[66,7128,231],{"class":230},[66,7130,6114],{"class":223},[66,7132,1865],{"class":72},[66,7134,604],{"class":230},[66,7136,7137,7139],{"class":68,"line":334},[66,7138,523],{"class":223},[66,7140,6320],{"class":230},[66,7142,7143],{"class":68,"line":340},[66,7144,656],{"class":230},[66,7146,7147,7150],{"class":68,"line":355},[66,7148,7149],{"class":72},"    ~A",[66,7151,4820],{"class":230},[66,7153,7154],{"class":68,"line":372},[66,7155,6190],{"class":230},[66,7157,7158],{"class":68,"line":395},[66,7159,656],{"class":230},[66,7161,7162],{"class":68,"line":400},[66,7163,6924],{"class":223},[66,7165,7166,7169],{"class":68,"line":416},[66,7167,7168],{"class":72},"    A",[66,7170,4820],{"class":230},[66,7172,7173],{"class":68,"line":421},[66,7174,6190],{"class":230},[66,7176,7177,7180,7182,7185,7187],{"class":68,"line":485},[66,7178,7179],{"class":230},"        b ",[66,7181,378],{"class":223},[66,7183,7184],{"class":230}," B::",[66,7186,6856],{"class":72},[66,7188,543],{"class":230},[66,7190,7191,7194,7196,7199],{"class":68,"line":490},[66,7192,7193],{"class":240},"        b",[66,7195,2829],{"class":230},[66,7197,7198],{"class":72},"setA",[66,7200,7201],{"class":230},"(_this);\n",[66,7203,7204],{"class":68,"line":520},[66,7205,656],{"class":230},[66,7207,7208,7210,7212,7215,7217],{"class":68,"line":546},[66,7209,6149],{"class":230},[66,7211,532],{"class":223},[66,7213,7214],{"class":230},"B",[66,7216,6157],{"class":223},[66,7218,7219],{"class":230}," b;\n",[66,7221,7222,7224,7226,7228,7230],{"class":68,"line":558},[66,7223,6954],{"class":230},[66,7225,532],{"class":223},[66,7227,7122],{"class":230},[66,7229,6157],{"class":223},[66,7231,6963],{"class":230},[66,7233,7234],{"class":68,"line":607},[66,7235,906],{"class":230},[66,7237,7238],{"class":68,"line":645},[66,7239,276],{"emptyLinePlaceholder":275},[66,7241,7242,7244],{"class":68,"line":653},[66,7243,6828],{"class":223},[66,7245,7246],{"class":240}," B\n",[66,7248,7249],{"class":68,"line":1278},[66,7250,1924],{"class":230},[66,7252,7253],{"class":68,"line":1301},[66,7254,6840],{"class":223},[66,7256,7257,7259,7261,7263,7265,7267,7269],{"class":68,"line":1320},[66,7258,6845],{"class":223},[66,7260,6526],{"class":240},[66,7262,532],{"class":230},[66,7264,7214],{"class":240},[66,7266,6274],{"class":230},[66,7268,6856],{"class":72},[66,7270,4820],{"class":230},[66,7272,7273],{"class":68,"line":1328},[66,7274,6190],{"class":230},[66,7276,7277,7279,7281,7283,7285,7287,7289,7291,7294],{"class":68,"line":1367},[66,7278,6874],{"class":230},[66,7280,532],{"class":223},[66,7282,7214],{"class":230},[66,7284,6157],{"class":223},[66,7286,6160],{"class":72},[66,7288,231],{"class":230},[66,7290,6114],{"class":223},[66,7292,7293],{"class":72}," B",[66,7295,604],{"class":230},[66,7297,7298,7300],{"class":68,"line":1398},[66,7299,523],{"class":223},[66,7301,6320],{"class":230},[66,7303,7304],{"class":68,"line":1405},[66,7305,656],{"class":230},[66,7307,7308,7311,7314,7316,7318,7320,7322,7324,7326],{"class":68,"line":1410},[66,7309,7310],{"class":223},"    void",[66,7312,7313],{"class":72}," setA",[66,7315,231],{"class":230},[66,7317,6031],{"class":240},[66,7319,532],{"class":230},[66,7321,7122],{"class":240},[66,7323,6274],{"class":230},[66,7325,1008],{"class":247},[66,7327,1188],{"class":230},[66,7329,7330,7332,7334,7336,7338,7341],{"class":68,"line":3174},[66,7331,6149],{"class":240},[66,7333,532],{"class":230},[66,7335,7122],{"class":240},[66,7337,6274],{"class":230},[66,7339,7340],{"class":72},"getA",[66,7342,543],{"class":230},[66,7344,7345],{"class":68,"line":3180},[66,7346,6924],{"class":223},[66,7348,7349,7351,7353,7355,7357],{"class":68,"line":3186},[66,7350,6149],{"class":230},[66,7352,532],{"class":223},[66,7354,7122],{"class":230},[66,7356,6157],{"class":223},[66,7358,7359],{"class":230},"  a;\n",[66,7361,7362],{"class":68,"line":3192},[66,7363,906],{"class":230},[17,7365,7366],{},"Cela peut-être aussi le cas, si par exemple une instance d'objet C\nréférence des instances d'objets fils C, qui possèdent eux-même un\npointeur vers l'objet C père.",[56,7368,7370],{"className":214,"code":7369,"language":216,"meta":61,"style":61},"class C\n{\npublic:\n    static QSharedPointer\u003CC> create()\n    {\n        QSharedPointer\u003CC> ptr(new C());\n        _this = ptr.toWeakPtr();\n        return ptr;\n    }\n\n    ~C()\n    {\n    }\n\n    void addChild(QSharedPointer\u003CC> c)\n    {\n        _childs.append(c);\n        c->setParent(_this);\n    }\n\n    void setParent(QSharedPointer\u003CC> c);\n    QSharedPointer\u003CC> getParent();\nprivate:\n    C()\n    {\n    }\n\n    QWeakPointer\u003CC> _this;\n    QSharedPointer\u003CC> _parent;\n    QList\u003C QSharedPointer\u003CC> > _childs;\n};\n",[63,7371,7372,7379,7383,7387,7404,7408,7428,7444,7450,7454,7458,7465,7469,7473,7477,7499,7503,7516,7527,7531,7535,7556,7571,7575,7582,7586,7590,7594,7606,7619,7640],{"__ignoreMap":61},[66,7373,7374,7376],{"class":68,"line":69},[66,7375,6828],{"class":223},[66,7377,7378],{"class":240}," C\n",[66,7380,7381],{"class":68,"line":80},[66,7382,1924],{"class":230},[66,7384,7385],{"class":68,"line":89},[66,7386,6840],{"class":223},[66,7388,7389,7391,7393,7395,7398,7400,7402],{"class":68,"line":279},[66,7390,6845],{"class":223},[66,7392,6526],{"class":240},[66,7394,532],{"class":230},[66,7396,7397],{"class":240},"C",[66,7399,6274],{"class":230},[66,7401,6856],{"class":72},[66,7403,4820],{"class":230},[66,7405,7406],{"class":68,"line":307},[66,7407,6190],{"class":230},[66,7409,7410,7412,7414,7416,7418,7420,7422,7424,7426],{"class":68,"line":329},[66,7411,6874],{"class":230},[66,7413,532],{"class":223},[66,7415,7397],{"class":230},[66,7417,6157],{"class":223},[66,7419,6160],{"class":72},[66,7421,231],{"class":230},[66,7423,6114],{"class":223},[66,7425,2103],{"class":72},[66,7427,604],{"class":230},[66,7429,7430,7433,7435,7437,7439,7442],{"class":68,"line":334},[66,7431,7432],{"class":230},"        _this ",[66,7434,378],{"class":223},[66,7436,6160],{"class":240},[66,7438,44],{"class":230},[66,7440,7441],{"class":72},"toWeakPtr",[66,7443,543],{"class":230},[66,7445,7446,7448],{"class":68,"line":340},[66,7447,523],{"class":223},[66,7449,6320],{"class":230},[66,7451,7452],{"class":68,"line":355},[66,7453,656],{"class":230},[66,7455,7456],{"class":68,"line":372},[66,7457,276],{"emptyLinePlaceholder":275},[66,7459,7460,7463],{"class":68,"line":395},[66,7461,7462],{"class":72},"    ~C",[66,7464,4820],{"class":230},[66,7466,7467],{"class":68,"line":400},[66,7468,6190],{"class":230},[66,7470,7471],{"class":68,"line":416},[66,7472,656],{"class":230},[66,7474,7475],{"class":68,"line":421},[66,7476,276],{"emptyLinePlaceholder":275},[66,7478,7479,7481,7484,7486,7488,7490,7492,7494,7497],{"class":68,"line":485},[66,7480,7310],{"class":223},[66,7482,7483],{"class":72}," addChild",[66,7485,231],{"class":230},[66,7487,6031],{"class":240},[66,7489,532],{"class":230},[66,7491,7397],{"class":240},[66,7493,6274],{"class":230},[66,7495,7496],{"class":247},"c",[66,7498,1784],{"class":230},[66,7500,7501],{"class":68,"line":490},[66,7502,6190],{"class":230},[66,7504,7505,7508,7510,7513],{"class":68,"line":520},[66,7506,7507],{"class":240},"        _childs",[66,7509,44],{"class":230},[66,7511,7512],{"class":72},"append",[66,7514,7515],{"class":230},"(c);\n",[66,7517,7518,7521,7523,7525],{"class":68,"line":546},[66,7519,7520],{"class":240},"        c",[66,7522,2829],{"class":230},[66,7524,6653],{"class":72},[66,7526,7201],{"class":230},[66,7528,7529],{"class":68,"line":558},[66,7530,656],{"class":230},[66,7532,7533],{"class":68,"line":607},[66,7534,276],{"emptyLinePlaceholder":275},[66,7536,7537,7539,7542,7544,7546,7548,7550,7552,7554],{"class":68,"line":645},[66,7538,7310],{"class":223},[66,7540,7541],{"class":72}," setParent",[66,7543,231],{"class":230},[66,7545,6031],{"class":240},[66,7547,532],{"class":230},[66,7549,7397],{"class":240},[66,7551,6274],{"class":230},[66,7553,7496],{"class":247},[66,7555,1188],{"class":230},[66,7557,7558,7560,7562,7564,7566,7569],{"class":68,"line":653},[66,7559,6149],{"class":240},[66,7561,532],{"class":230},[66,7563,7397],{"class":240},[66,7565,6274],{"class":230},[66,7567,7568],{"class":72},"getParent",[66,7570,543],{"class":230},[66,7572,7573],{"class":68,"line":1278},[66,7574,6924],{"class":223},[66,7576,7577,7580],{"class":68,"line":1301},[66,7578,7579],{"class":72},"    C",[66,7581,4820],{"class":230},[66,7583,7584],{"class":68,"line":1320},[66,7585,6190],{"class":230},[66,7587,7588],{"class":68,"line":1328},[66,7589,656],{"class":230},[66,7591,7592],{"class":68,"line":1367},[66,7593,276],{"emptyLinePlaceholder":275},[66,7595,7596,7598,7600,7602,7604],{"class":68,"line":1398},[66,7597,6954],{"class":230},[66,7599,532],{"class":223},[66,7601,7397],{"class":230},[66,7603,6157],{"class":223},[66,7605,6963],{"class":230},[66,7607,7608,7610,7612,7614,7616],{"class":68,"line":1405},[66,7609,6149],{"class":230},[66,7611,532],{"class":223},[66,7613,7397],{"class":230},[66,7615,6157],{"class":223},[66,7617,7618],{"class":230}," _parent;\n",[66,7620,7621,7624,7626,7628,7630,7632,7634,7637],{"class":68,"line":1410},[66,7622,7623],{"class":230},"    QList",[66,7625,532],{"class":223},[66,7627,6526],{"class":230},[66,7629,532],{"class":223},[66,7631,7397],{"class":230},[66,7633,6157],{"class":223},[66,7635,7636],{"class":223}," >",[66,7638,7639],{"class":230}," _childs;\n",[66,7641,7642],{"class":68,"line":3174},[66,7643,906],{"class":230},[17,7645,7646],{},"Dans ces cas là, on a :- L'objet A possède la référence vers l'objet B-\nL'objet B possède une référence vers l'objet A.- Même principe avec\nl'objet C",[17,7648,7649],{},[1445,7650],{"alt":7651,"src":7652},"Reference circulaire de QSharedPointer","\u002FProgrammation\u002Fqt-performance-de-l-utilisation-de-qsharedpointer\u002FQSharedPointer3.png",[17,7654,7655],{},"Dans ce cas, il restera alors toujours une référence vers A, et une vers\nB, même si plus aucune variable ne référence ces objets. Cette référence\ncirculaire fait que l'objet ne sera jamais détruit même si on n'a plus\nbesoin de l'objet.",[17,7657,7658],{},"Si on décide que l'objet A sera l'objet maitre (donc que sa destruction\nengendrera la destruction de l'objet B), on peut alors écrire les choses\nainsi pour l'objet B :",[56,7660,7662],{"className":214,"code":7661,"language":216,"meta":61,"style":61},"class B\n{\npublic:\n    static QSharedPointer\u003CB> create()\n    {\n        QSharedPointer\u003CB> ptr(new B());\n        return ptr;\n    }\n    void setA(QWeakPointer\u003CA> b);\n    QWeakPointer\u003CA> getA();\nprivate:\n    QWeakPointer\u003CA>  a;\n};\n",[63,7663,7664,7670,7674,7678,7694,7698,7718,7724,7728,7748,7762,7766,7778],{"__ignoreMap":61},[66,7665,7666,7668],{"class":68,"line":69},[66,7667,6828],{"class":223},[66,7669,7246],{"class":240},[66,7671,7672],{"class":68,"line":80},[66,7673,1924],{"class":230},[66,7675,7676],{"class":68,"line":89},[66,7677,6840],{"class":223},[66,7679,7680,7682,7684,7686,7688,7690,7692],{"class":68,"line":279},[66,7681,6845],{"class":223},[66,7683,6526],{"class":240},[66,7685,532],{"class":230},[66,7687,7214],{"class":240},[66,7689,6274],{"class":230},[66,7691,6856],{"class":72},[66,7693,4820],{"class":230},[66,7695,7696],{"class":68,"line":307},[66,7697,6190],{"class":230},[66,7699,7700,7702,7704,7706,7708,7710,7712,7714,7716],{"class":68,"line":329},[66,7701,6874],{"class":230},[66,7703,532],{"class":223},[66,7705,7214],{"class":230},[66,7707,6157],{"class":223},[66,7709,6160],{"class":72},[66,7711,231],{"class":230},[66,7713,6114],{"class":223},[66,7715,7293],{"class":72},[66,7717,604],{"class":230},[66,7719,7720,7722],{"class":68,"line":334},[66,7721,523],{"class":223},[66,7723,6320],{"class":230},[66,7725,7726],{"class":68,"line":340},[66,7727,656],{"class":230},[66,7729,7730,7732,7734,7736,7738,7740,7742,7744,7746],{"class":68,"line":355},[66,7731,7310],{"class":223},[66,7733,7313],{"class":72},[66,7735,231],{"class":230},[66,7737,6348],{"class":240},[66,7739,532],{"class":230},[66,7741,7122],{"class":240},[66,7743,6274],{"class":230},[66,7745,1008],{"class":247},[66,7747,1188],{"class":230},[66,7749,7750,7752,7754,7756,7758,7760],{"class":68,"line":372},[66,7751,6954],{"class":240},[66,7753,532],{"class":230},[66,7755,7122],{"class":240},[66,7757,6274],{"class":230},[66,7759,7340],{"class":72},[66,7761,543],{"class":230},[66,7763,7764],{"class":68,"line":395},[66,7765,6924],{"class":223},[66,7767,7768,7770,7772,7774,7776],{"class":68,"line":400},[66,7769,6954],{"class":230},[66,7771,532],{"class":223},[66,7773,7122],{"class":230},[66,7775,6157],{"class":223},[66,7777,7359],{"class":230},[66,7779,7780],{"class":68,"line":416},[66,7781,906],{"class":230},[17,7783,7784,7785,7787,7788,5538,7790,7792,7793,7798,7799,44],{},"Dans ce cas, avec l'utilisation d'un ",[63,7786,6348],{},", lorsque qu'il\nn'existera plus de référence vers l'objet A, le pointeur ",[32,7789,6344],{},[63,7791,39],{},"\nsera mis à jour comme ne contenant plus de référence",[1607,7794,7795],{},[39,7796,1711],{"href":1708,"ariaDescribedBy":7797,"dataFootnoteRef":61,"id":1710},[1613],".\nL'instance de l'objet A sera réellement détruite. Il n'y aura alors plus\naucune référence vers l'objet B qui sera alors également\ndétruit",[1607,7800,7801],{},[39,7802,1747],{"href":1744,"ariaDescribedBy":7803,"dataFootnoteRef":61,"id":1746},[1613],[4389,7805,7807],{"id":7806},"utilisation-dans-les-applications-multi-thread","Utilisation dans les applications multi-thread",[17,7809,7810,7811,7813,7814,3581,7816,7818],{},"L'utilisation de ",[63,7812,6031],{}," simplifie l'écriture des applications\nmulti-thread (les objets ",[63,7815,6031],{},[63,7817,6348],{}," sont\nthread-safe).",[17,7820,7821,7822,7827,7828,44],{},"Dans ces applications il n'y a alors plus besoin de se soucier si\nl'objet est en cours d'utilisation ailleurs dans l'application avant de\nle supprimer",[1607,7823,7824],{},[39,7825,3017],{"href":3014,"ariaDescribedBy":7826,"dataFootnoteRef":61,"id":3016},[1613],". Lorsqu'un pointeur ne devient plus utilisé dans\nun thread donné, il ne sera détruit que s'il n'y a pas d'autres\nréférences dans d'autres threads de l'application",[1607,7829,7830],{},[39,7831,7835],{"href":7832,"ariaDescribedBy":7833,"dataFootnoteRef":61,"id":7834},"#user-content-fn-9",[1613],"user-content-fnref-9","9",[17,7837,7838,7839,7841,7842,44],{},"Avec l'utilisation de ",[63,7840,6348],{},", un thread pourra tester\nl'existence du pointeur avant d'effectuer une opération et pourra aviser\nle cas échéant sans faire planter toute l'application",[1607,7843,7844],{},[39,7845,511],{"href":7846,"ariaDescribedBy":7847,"dataFootnoteRef":61,"id":7848},"#user-content-fn-10",[1613],"user-content-fnref-10",[4389,7850,7852],{"id":7851},"utilisation-dun-pool","Utilisation d'un pool",[17,7854,7855,7856,7861],{},"Si la création et la destruction d'un objet est coûteux, il est\nenvisageable de diminuer le coût de destruction et de création d'un\nthread en utilisant un Pool d'objet. Dans ce cas l'objet ",[39,7857,7860],{"href":7858,"rel":7859},"http:\u002F\u002Fdoc.qt.nokia.com\u002F4.6\u002Fqqueue.html",[43],"QQueue","\npourra être utilisé pour représenter notre Pool.",[17,7863,7864,7865,7867,7868,44],{},"Lors de la demande de création, en utilisant notre méthode ",[63,7866,6856],{},"\nci-dessus, on prend alors une valeur du pool (si disponible) et on la\nretourne sous forme d'un ",[63,7869,6031],{},[56,7871,7873],{"className":214,"code":7872,"language":216,"meta":61,"style":61},"QSharedPointer\u003CMyObject> MyObject::create()\n{\n    MyObject * c_ptr;\n    if (_queue.size())\n    {\n    c_ptr = _queue.dequeue();\n    }\n    else\n    {\n    c_ptr = new MyObject();\n    }\n    QSharedPointer\u003CMyObject> ptr(c_ptr, ReturnToPool);\n    ptr->_this = ptr.toWeakRef();\n    return ptr;\n}\n",[63,7874,7875,7893,7897,7907,7923,7927,7944,7948,7953,7957,7969,7973,7988,8006,8012],{"__ignoreMap":61},[66,7876,7877,7879,7881,7883,7885,7887,7889,7891],{"class":68,"line":69},[66,7878,6031],{"class":240},[66,7880,532],{"class":230},[66,7882,6154],{"class":240},[66,7884,6274],{"class":230},[66,7886,6154],{"class":240},[66,7888,1001],{"class":230},[66,7890,6856],{"class":72},[66,7892,4820],{"class":230},[66,7894,7895],{"class":68,"line":80},[66,7896,1924],{"class":230},[66,7898,7899,7902,7904],{"class":68,"line":89},[66,7900,7901],{"class":230},"    MyObject ",[66,7903,593],{"class":223},[66,7905,7906],{"class":230}," c_ptr;\n",[66,7908,7909,7911,7913,7916,7918,7920],{"class":68,"line":279},[66,7910,493],{"class":223},[66,7912,574],{"class":230},[66,7914,7915],{"class":240},"_queue",[66,7917,44],{"class":230},[66,7919,3884],{"class":72},[66,7921,7922],{"class":230},"())\n",[66,7924,7925],{"class":68,"line":307},[66,7926,6190],{"class":230},[66,7928,7929,7932,7934,7937,7939,7942],{"class":68,"line":329},[66,7930,7931],{"class":230},"    c_ptr ",[66,7933,378],{"class":223},[66,7935,7936],{"class":240}," _queue",[66,7938,44],{"class":230},[66,7940,7941],{"class":72},"dequeue",[66,7943,543],{"class":230},[66,7945,7946],{"class":68,"line":334},[66,7947,656],{"class":230},[66,7949,7950],{"class":68,"line":340},[66,7951,7952],{"class":223},"    else\n",[66,7954,7955],{"class":68,"line":355},[66,7956,6190],{"class":230},[66,7958,7959,7961,7963,7965,7967],{"class":68,"line":372},[66,7960,7931],{"class":230},[66,7962,378],{"class":223},[66,7964,2811],{"class":223},[66,7966,6167],{"class":72},[66,7968,543],{"class":230},[66,7970,7971],{"class":68,"line":395},[66,7972,656],{"class":230},[66,7974,7975,7977,7979,7981,7983,7985],{"class":68,"line":400},[66,7976,6149],{"class":230},[66,7978,532],{"class":223},[66,7980,6154],{"class":230},[66,7982,6157],{"class":223},[66,7984,6160],{"class":72},[66,7986,7987],{"class":230},"(c_ptr, ReturnToPool);\n",[66,7989,7990,7992,7994,7996,7998,8000,8002,8004],{"class":68,"line":416},[66,7991,6287],{"class":240},[66,7993,2829],{"class":230},[66,7995,6806],{"class":437},[66,7997,2883],{"class":223},[66,7999,6160],{"class":240},[66,8001,44],{"class":230},[66,8003,6376],{"class":72},[66,8005,543],{"class":230},[66,8007,8008,8010],{"class":68,"line":421},[66,8009,1946],{"class":223},[66,8011,6320],{"class":230},[66,8013,8014],{"class":68,"line":485},[66,8015,1413],{"class":230},[17,8017,8018,8019,8027,8028,8030],{},"Dans l'exemple ci-dessus",[1607,8020,8021],{},[39,8022,8026],{"href":8023,"ariaDescribedBy":8024,"dataFootnoteRef":61,"id":8025},"#user-content-fn-11",[1613],"user-content-fnref-11","11",", on demande à la queue, qui doit\nêtre une variable globale ou statique, un élément, et si ce n'est pas\npossible, on crée un nouvel objet de type ",[63,8029,6154],{}," (dont on suppose la\ncréation coûteuse).",[17,8032,8033,8034,8036,8037,8040,8041,8044,8045,8048],{},"Lors de la création du ",[63,8035,6031],{}," on utilise alors le constructeur\n",[63,8038,8039],{},"QSharedPointer ( T * ptr, Deleter deleter )"," sur lequel on définit une\nméthode ",[63,8042,8043],{},"Deleter"," nommée ",[63,8046,8047],{},"ReturnToPool"," dont le but est de remettre les\nobjets en pool.",[56,8050,8052],{"className":214,"code":8051,"language":216,"meta":61,"style":61},"static void ReturnToPool(MyObject *obj)\n{\n    if (_queue.size() \u003C MAX_SIZE_QUEUE)\n    {\n        _queue.enqueue(obj);\n    }\n    else\n    {\n        delete obj;\n    }\n}\n",[63,8053,8054,8076,8080,8099,8103,8116,8120,8124,8128,8135,8139],{"__ignoreMap":61},[66,8055,8056,8059,8062,8065,8067,8069,8071,8074],{"class":68,"line":69},[66,8057,8058],{"class":223},"static",[66,8060,8061],{"class":223}," void",[66,8063,8064],{"class":72}," ReturnToPool",[66,8066,231],{"class":230},[66,8068,6154],{"class":240},[66,8070,620],{"class":223},[66,8072,8073],{"class":247},"obj",[66,8075,1784],{"class":230},[66,8077,8078],{"class":68,"line":80},[66,8079,1924],{"class":230},[66,8081,8082,8084,8086,8088,8090,8092,8094,8096],{"class":68,"line":89},[66,8083,493],{"class":223},[66,8085,574],{"class":230},[66,8087,7915],{"class":240},[66,8089,44],{"class":230},[66,8091,3884],{"class":72},[66,8093,590],{"class":230},[66,8095,532],{"class":223},[66,8097,8098],{"class":230}," MAX_SIZE_QUEUE)\n",[66,8100,8101],{"class":68,"line":279},[66,8102,6190],{"class":230},[66,8104,8105,8108,8110,8113],{"class":68,"line":307},[66,8106,8107],{"class":240},"        _queue",[66,8109,44],{"class":230},[66,8111,8112],{"class":72},"enqueue",[66,8114,8115],{"class":230},"(obj);\n",[66,8117,8118],{"class":68,"line":329},[66,8119,656],{"class":230},[66,8121,8122],{"class":68,"line":334},[66,8123,7952],{"class":223},[66,8125,8126],{"class":68,"line":340},[66,8127,6190],{"class":230},[66,8129,8130,8133],{"class":68,"line":355},[66,8131,8132],{"class":223},"        delete",[66,8134,6731],{"class":230},[66,8136,8137],{"class":68,"line":372},[66,8138,656],{"class":230},[66,8140,8141],{"class":68,"line":395},[66,8142,1413],{"class":230},[17,8144,8145],{},"Dans ce cas de retour au pool, si le pool est rempli, on détruit l'objet\n(pour éviter de consommer trop de mémoire), sinon on l'ajoute au pool.\nDans ce cas, le pool est agrandi au fur et à mesure des besoins, jusqu'à\nune taille limite.",[17,8147,8148],{},"Bien sûr il faut que la performance de l'utilisation d'un pool soit plus\nintéressante que celle de la création de l'objet et de son\ninitialisation.",[17,8150,8151],{},[1534,8152,8153,8157,8158,8160,8161,8163,8164,8166,8167,8169,8170,8172,8173,8175,8176],{},[8154,8155,8156],"ins",{},"Attention"," : Ce point ne fonctionne, par contre, pas si\nl'objet (",[63,8159,6154],{},") est un descendant de ",[63,8162,4884],{},". En effet ",[63,8165,4884],{},"\ngarde une référence du ",[63,8168,6031],{}," en mémoire et lors de la\nréutilisation du ",[63,8171,4884],{}," une erreur indique que l'objet n'a pas été\ndétruit et est déjà utilisé par un ",[63,8174,6031],{},". On n'a pas le\nproblème avec ",[63,8177,8178],{},"std::tr1::shared_ptr",[12,8180,8182],{"id":8181},"benchmark","Benchmark",[17,8184,8185,8186,8188],{},"Le but du benchmark est de se faire une idée sur les performances d'une\napplication utilisant des ",[63,8187,6031],{}," à la place des pointeurs\nnormaux. Attention, ce bench ne prend pas en compte le besoin potentiel\nde Mutex, de comptage de référence manuel, ... dans les applications\nmulti-thread qui pourrait être nécessaire pour ne pas supprimer le\npointeur si besoin.",[17,8190,8191,8192,8194,8195,44],{},"Dans ce test nous allons tester également (en comparaison), le pointeur\n",[32,8193,5956],{}," du C++0x",[1607,8196,8197],{},[39,8198,8202],{"href":8199,"ariaDescribedBy":8200,"dataFootnoteRef":61,"id":8201},"#user-content-fn-12",[1613],"user-content-fnref-12","12",[17,8204,8205],{},"Nous allons donc tester les opérations courantes de création,\ndestruction, modification, affectation.",[4389,8207,8209],{"id":8208},"code-source","Code source",[17,8211,8212,8213,8216],{},"Le code source est disponible, attaché au billet. Dans la suite du\nbillet, seuls les morceaux intéressants du benchmark seront décris. Le\nbenchmark utilise QTest. Nous avons créé un objet bidon ",[63,8214,8215],{},"ObjetTest"," qui\ndans le constructeur allouera un pointeur et remplira une liste, et le\ndestructeur supprime ce pointeur (et forcément la liste).",[17,8218,8219],{},"Pour que chaque test soit indépendant, le jeu de test sera initialisé\navant le début de chaque QBENCHMARK et détruit à la fin du bloc. Nous\naurons quatre méthodes :",[162,8221,8222,8225,8228,8231],{},[165,8223,8224],{},"Allocation",[165,8226,8227],{},"Modification",[165,8229,8230],{},"Affectation",[165,8232,8233],{},"Nettoyage",[17,8235,8236],{},"Pour chaque test nous allons faire le test avec",[162,8238,8239,8242,8249],{},[165,8240,8241],{},"un pointeur C standard",[165,8243,8244,8245,4762,8247],{},"le pointeur ",[63,8246,6031],{},[32,8248,3803],{},[165,8250,8244,8251,4762,8253],{},[63,8252,8178],{},[32,8254,8255],{},"C++0x",[17,8257,8258],{},"Pour le test d'allocation et le test de nettoyage, nous allons également\nutiliser l'optimisation possible, vu ci-dessus, d'un Pool d'objet. Nous\nallons faire le test avec :",[162,8260,8261,8267],{},[165,8262,8244,8263,4762,8265],{},[63,8264,6031],{},[32,8266,3803],{},[165,8268,8244,8269,4762,8271],{},[63,8270,8178],{},[32,8272,8255],{},[4389,8274,8276],{"id":8275},"le-jeu-de-test","Le jeu de test",[4862,8278,8280],{"id":8279},"test-de-lallocation","Test de l'allocation",[17,8282,8283,8284,8286,8287,8289],{},"La création du pointeur en utilisant ",[63,8285,6031],{}," instancie le\npointeur ainsi que le ",[63,8288,6031],{},". Le temps d'exécution est donc\npotentiellement deux fois plus long (voir le benchmark à la fin de ce\nbillet).",[17,8291,8292],{},"Pour la création du pool, nous allons utiliser une méthode qui créera le\npointeur s'il n'est pas dans le pool, et sinon prendra le pointeur du\npool. Dans notre cas de test, il y aura toujours une valeur dans le\npool, que l'on aura rempli au préalable.",[17,8294,8295,8296,3581,8299,8302],{},"La méthode ",[63,8297,8298],{},"createFromPool()",[63,8300,8301],{},"createFromBoostPool()"," est\nsensiblement identique :",[56,8304,8306],{"className":214,"code":8305,"language":216,"meta":61,"style":61},"QSharedPointer\u003CObjetTest> createFromPool()\n{\n    ObjetTest * c_ptr;\n    if (_queue.size())\n    {\n        c_ptr = _queue.dequeue();\n    }\n    else\n    {\n        c_ptr = new ObjetTest();\n    }\n\n    QSharedPointer\u003CObjetTest> ptr(c_ptr, returnToPool);\n    return ptr;\n}\n",[63,8307,8308,8323,8327,8336,8350,8354,8369,8373,8377,8381,8394,8398,8402,8417,8423],{"__ignoreMap":61},[66,8309,8310,8312,8314,8316,8318,8321],{"class":68,"line":69},[66,8311,6031],{"class":240},[66,8313,532],{"class":230},[66,8315,8215],{"class":240},[66,8317,6274],{"class":230},[66,8319,8320],{"class":72},"createFromPool",[66,8322,4820],{"class":230},[66,8324,8325],{"class":68,"line":80},[66,8326,1924],{"class":230},[66,8328,8329,8332,8334],{"class":68,"line":89},[66,8330,8331],{"class":230},"    ObjetTest ",[66,8333,593],{"class":223},[66,8335,7906],{"class":230},[66,8337,8338,8340,8342,8344,8346,8348],{"class":68,"line":279},[66,8339,493],{"class":223},[66,8341,574],{"class":230},[66,8343,7915],{"class":240},[66,8345,44],{"class":230},[66,8347,3884],{"class":72},[66,8349,7922],{"class":230},[66,8351,8352],{"class":68,"line":307},[66,8353,6190],{"class":230},[66,8355,8356,8359,8361,8363,8365,8367],{"class":68,"line":329},[66,8357,8358],{"class":230},"        c_ptr ",[66,8360,378],{"class":223},[66,8362,7936],{"class":240},[66,8364,44],{"class":230},[66,8366,7941],{"class":72},[66,8368,543],{"class":230},[66,8370,8371],{"class":68,"line":334},[66,8372,656],{"class":230},[66,8374,8375],{"class":68,"line":340},[66,8376,7952],{"class":223},[66,8378,8379],{"class":68,"line":355},[66,8380,6190],{"class":230},[66,8382,8383,8385,8387,8389,8392],{"class":68,"line":372},[66,8384,8358],{"class":230},[66,8386,378],{"class":223},[66,8388,2811],{"class":223},[66,8390,8391],{"class":72}," ObjetTest",[66,8393,543],{"class":230},[66,8395,8396],{"class":68,"line":395},[66,8397,656],{"class":230},[66,8399,8400],{"class":68,"line":400},[66,8401,276],{"emptyLinePlaceholder":275},[66,8403,8404,8406,8408,8410,8412,8414],{"class":68,"line":416},[66,8405,6149],{"class":230},[66,8407,532],{"class":223},[66,8409,8215],{"class":230},[66,8411,6157],{"class":223},[66,8413,6160],{"class":72},[66,8415,8416],{"class":230},"(c_ptr, returnToPool);\n",[66,8418,8419,8421],{"class":68,"line":421},[66,8420,1946],{"class":223},[66,8422,6320],{"class":230},[66,8424,8425],{"class":68,"line":485},[66,8426,1413],{"class":230},[8428,8429,8430,8442],"table",{},[8431,8432,8433],"thead",{},[8434,8435,8436,8440],"tr",{},[8437,8438,8439],"th",{},"Méthode",[8437,8441,5787],{},[8443,8444,8445,8456,8466,8476,8486],"tbody",{},[8434,8446,8447,8451],{},[8448,8449,8450],"td",{},"C Pointer",[8448,8452,8453],{},[63,8454,8455],{},"ObjetTest* ptr = new ObjetTest();",[8434,8457,8458,8461],{},[8448,8459,8460],{},"Qt Smart Pointer",[8448,8462,8463],{},[63,8464,8465],{},"QSharedPointer\u003CObjetTest> ptr(new ObjetTest());",[8434,8467,8468,8471],{},[8448,8469,8470],{},"Qt Smart Pointer as Pool",[8448,8472,8473],{},[63,8474,8475],{},"QSharedPointer\u003CObjetTest> ptr = createFromPool ();",[8434,8477,8478,8481],{},[8448,8479,8480],{},"C++0x Smart Pointer",[8448,8482,8483],{},[63,8484,8485],{},"std::tr1::shared_ptr\u003CObjetTest> ptr(new ObjetTest());",[8434,8487,8488,8491],{},[8448,8489,8490],{},"C++0x Smart Pointer as Pool",[8448,8492,8493],{},[63,8494,8495],{},"std::tr1::shared_ptr\u003CObjetTest> ptr = createFromBoostPool ();",[4862,8497,8499],{"id":8498},"test-de-modification-dune-donnée","Test de Modification d'une donnée",[17,8501,8502],{},"Pour la modification d'une donnée, on génère un nombre aléatoire que\nl'on va stocker (toujours le même pour chaque test, cela n'a pas\nd'importance). La génération du nombre aléatoire se fait en dehors du\nbloc, pour éviter de polluer le test avec le calcul d'un nombre\naléatoire. Ici il n'y a pas création d'affectation du pointeur, juste\nune affectation d'une valeur dans le contenu du pointeur. La syntaxe\npour le C, et pour le pointeur intelligent est identique.",[8428,8504,8505,8513],{},[8431,8506,8507],{},[8434,8508,8509,8511],{},[8437,8510,8439],{},[8437,8512,5787],{},[8443,8514,8515],{},[8434,8516,8517,8520],{},[8448,8518,8519],{},"C Pointer \u002F Qt Smart Pointer \u002F C++0x Smart Pointer",[8448,8521,8522],{},[63,8523,8524],{},"obj->value = random_number;",[4862,8526,8528],{"id":8527},"test-daffectation","Test d'affectation",[17,8530,8531,8532,8534],{},"Pour l'affectation nous allons créer une nouvelle variable qui pointera\nsur le même pointeur, et sur lequel on fera une modification. La\ncréation d'un pointeur peut arriver par exemple lors du passage du\npointeur à une fonction, ou lors de la déclaration d'une variable devant\ncontenir la même valeur. Cette déclaration supplémentaire a peu d'impact\npour un pointeur C mais pour un pointeur ",[32,8533,5956],{}," oblige la\ncréation d'un objet, et l'incrément d'un nombre d'instance (qu'on\ndécrémente ici dans la même boucle).",[8428,8536,8537,8545],{},[8431,8538,8539],{},[8434,8540,8541,8543],{},[8437,8542,8439],{},[8437,8544,5787],{},[8443,8546,8547,8556,8565,8574,8582,8591],{},[8434,8548,8549,8551],{},[8448,8550,8450],{},[8448,8552,8553],{},[63,8554,8555],{},"ObjetTest * obj2 = obj;",[8434,8557,8558,8560],{},[8448,8559],{},[8448,8561,8562],{},[63,8563,8564],{},"obj2->value = random_number;",[8434,8566,8567,8569],{},[8448,8568,8460],{},[8448,8570,8571],{},[63,8572,8573],{},"QSharedPointer\u003CObjetTest> obj2 = obj;",[8434,8575,8576,8578],{},[8448,8577],{},[8448,8579,8580],{},[63,8581,8564],{},[8434,8583,8584,8586],{},[8448,8585,8480],{},[8448,8587,8588],{},[63,8589,8590],{},"std::tr1::shared_ptr\u003CObjetTest> obj2 = obj;",[8434,8592,8593,8595],{},[8448,8594],{},[8448,8596,8597],{},[63,8598,8564],{},[4862,8600,8602],{"id":8601},"test-de-destruction","Test de destruction",[17,8604,8605,8606,8609],{},"Pour ce test, nous allons initialiser une liste de pointeur, et pour le\nbenchmark, nous allons supprimer un à un chaque élément de la liste.La\ndestruction du pointeur en C se fait par un ",[63,8607,8608],{},"delete",". Pour le pointeur\n''intelligent', il n'y a pas de destruction explicite. Nous allons juste\nsupprimer le pointeur de la liste, le pointeur sera alors\nautomatiquement détruit car il n'y aura plus de référence vers ce\npointeur.",[17,8611,8612,8613,4405],{},"Pour le cas de test utilisant la notion du Pool, on aura créé le\npointeur avec le delete ",[63,8614,8615],{},"returnToPool()",[56,8617,8619],{"className":214,"code":8618,"language":216,"meta":61,"style":61},"void returnToPool(ObjetTest *obj)\n{\n    _queue.enqueue(obj);\n}\n",[63,8620,8621,8638,8642,8653],{"__ignoreMap":61},[66,8622,8623,8625,8628,8630,8632,8634,8636],{"class":68,"line":69},[66,8624,6260],{"class":223},[66,8626,8627],{"class":72}," returnToPool",[66,8629,231],{"class":230},[66,8631,8215],{"class":240},[66,8633,620],{"class":223},[66,8635,8073],{"class":247},[66,8637,1784],{"class":230},[66,8639,8640],{"class":68,"line":80},[66,8641,1924],{"class":230},[66,8643,8644,8647,8649,8651],{"class":68,"line":89},[66,8645,8646],{"class":240},"    _queue",[66,8648,44],{"class":230},[66,8650,8112],{"class":72},[66,8652,8115],{"class":230},[66,8654,8655],{"class":68,"line":279},[66,8656,1413],{"class":230},[17,8658,8659],{},"Cette méthode ne fait pas de réelle destruction, mais juste un ajout de\nl'objet au pool.",[8428,8661,8662,8670],{},[8431,8663,8664],{},[8434,8665,8666,8668],{},[8437,8667,8439],{},[8437,8669,5787],{},[8443,8671,8672,8681,8690,8699,8705,8711],{},[8434,8673,8674,8676],{},[8448,8675,8450],{},[8448,8677,8678],{},[63,8679,8680],{},"delete c_ptr_list.at(0);",[8434,8682,8683,8685],{},[8448,8684],{},[8448,8686,8687],{},[63,8688,8689],{},"c_ptr_list.removeFirst ();",[8434,8691,8692,8694],{},[8448,8693,8460],{},[8448,8695,8696],{},[63,8697,8698],{},"smart_ptr_list.removeFirst ();",[8434,8700,8701,8703],{},[8448,8702,8470],{},[8448,8704],{},[8434,8706,8707,8709],{},[8448,8708,8480],{},[8448,8710],{},[8434,8712,8713,8715],{},[8448,8714,8490],{},[8448,8716],{},[4862,8718,8720],{"id":8719},"résultat-du-test","Résultat du test",[17,8722,8723],{},"Le test a été fait en utilisant la version 4.6.3 de Qt. Test effectué\npour 5 000 000 itérations.",[8428,8725,8726,8747],{},[8431,8727,8728],{},[8434,8729,8730,8732,8735,8738,8741,8744],{},[8437,8731],{},[8437,8733,8734],{},"Pointeur C",[8437,8736,8737],{},"Pointeur Qt",[8437,8739,8740],{},"Pointeur C++0x",[8437,8742,8743],{},"Pool en utilisant QSharedPointer",[8437,8745,8746],{},"Pool en utilisant std::tr1::shared_ptr",[8443,8748,8749,8770,8788,8806],{},[8434,8750,8751,8755,8758,8761,8764,8767],{},[8448,8752,8753],{},[63,8754,8224],{},[8448,8756,8757],{},"0.0004275 msec",[8448,8759,8760],{},"0.0007692 msec",[8448,8762,8763],{},"0.0006604 msec",[8448,8765,8766],{},"0.0002590 msec",[8448,8768,8769],{},"0.0002286 msec",[8434,8771,8772,8776,8779,8782,8784,8786],{},[8448,8773,8774],{},[63,8775,8227],{},[8448,8777,8778],{},"0.000010 msec",[8448,8780,8781],{},"0.000012 msec",[8448,8783,8781],{},[8448,8785],{},[8448,8787],{},[8434,8789,8790,8794,8796,8799,8802,8804],{},[8448,8791,8792],{},[63,8793,8230],{},[8448,8795,8778],{},[8448,8797,8798],{},"0.0000386 msec",[8448,8800,8801],{},"0.0000230 msec",[8448,8803],{},[8448,8805],{},[8434,8807,8808,8813,8816,8819,8822,8825],{},[8448,8809,8810],{},[63,8811,8812],{},"Destruction",[8448,8814,8815],{},"0.000190 msec",[8448,8817,8818],{},"0.0003161 msec",[8448,8820,8821],{},"0.0003359 msec",[8448,8823,8824],{},"0.0004003 msec",[8448,8826,8827],{},"0.0003601 msec",[17,8829,8830,8831,8833],{},"Conclusion que l'on peut en tirer, le pointeur C est ce qu'il y a de\nplus rapide à partir du moment où on fait de l'allocation de\nl'affectation ou de la destruction. Par contre il n'apporte pas la\nsouplesse qu'apporte les pointeurs ",[32,8832,5976],{}," entre autre pour les\napplications multi-threadé.",[17,8835,8836],{},"On remarque que le pointeur C++0x est plus rapide pour la création, mais\napparemment plus lent en destruction. Il est également possible avec le\npool de gagner en performance (surtout en création). Par contre le coût\nde destruction de l'objet n'est pas encore assez fort pour y gagner en\nutilisant le pool.",[17,8838,8839],{},"Ensuite il est important de se faire son propre jugement selon ses\nbesoins. Si besoin le source est attaché, vous pouvez faire vos propres\ntests.",[4862,8841,8843],{"id":8842},"source-du-test","Source du test",[17,8845,8846,8847,44],{},"Vous pouvez trouver les sources du test au ",[39,8848,8850],{"href":8849},"\u002FProgrammation\u002Fqt-performance-de-l-utilisation-de-qsharedpointer\u002Fsmart_benchmark.7z","lien suivant",[17,8852,8853,8858,8859,8864,8865,44],{},[39,8854,8857],{"href":8855,"rel":8856},"http:\u002F\u002Fwww.boost.org\u002Fdoc\u002Flibs\u002F1_45_0\u002Flibs\u002Fsmart_ptr\u002Fshared_ptr.htm",[43],"boost::shared_ptr"," du projet ",[39,8860,8863],{"href":8861,"rel":8862},"http:\u002F\u002Fwww.boost.org\u002F",[43],"Boost",". Boost est une librairie qui\najoute beaucoup de facilité pour les programmes en C++, comme par\nexemple les smart-pointer dont certains seront inclus dans C++0x, ou de\nla boucle ",[63,8866,8867],{},"std::for_each",[3349,8869,8871,8874],{"className":8870,"dataFootnotes":61},[3352],[1432,8872,3357],{"className":8873,"id":1613},[3356],[3359,8875,8876,8882,8888,8896,8912,8918,8928,8934,8943,8952,8966,8975],{},[165,8877,8878,8879],{"id":3363},"en anglais : smart-pointer ",[39,8880,3371],{"href":3367,"ariaLabel":3368,"className":8881,"dataFootnoteBackref":61},[3370],[165,8883,8884,8885],{"id":3374},"COW = Copy On Write ",[39,8886,3371],{"href":3378,"ariaLabel":3379,"className":8887,"dataFootnoteBackref":61},[3370],[165,8889,8890,8891,5538,8893],{"id":3383},"Ce pointeur est l'équivalent du pointeur ",[32,8892,5956],{},[39,8894,3371],{"href":3387,"ariaLabel":3388,"className":8895,"dataFootnoteBackref":61},[3370],[165,8897,8898,8899,8902,8903,8905,8906,8908,8909],{"id":3392},"Si à un moment donné il faut utiliser le pointeur C pour une\nraison quelconque, on peut utiliser ",[63,8900,8901],{},"ptr.data()"," mais il faut s'assurer\nque le pointeur ne sera pas détruit en déclarant un ",[63,8904,6031],{},"\ndans le même bloc utilisant le pointeur C. Le ",[63,8907,6031],{}," ne devra\nêtre détruit qu'après utilisation du pointeur C. Ceci peut être fait\ndans certain cas pour des raisons de performance. ",[39,8910,3371],{"href":3396,"ariaLabel":3397,"className":8911,"dataFootnoteBackref":61},[3370],[165,8913,8914,8915],{"id":3401},"Sinon nous ne serions plus là pour lancer la méthode ",[39,8916,3371],{"href":3409,"ariaLabel":3410,"className":8917,"dataFootnoteBackref":61},[3370],[165,8919,8920,8921,8924,8925],{"id":3414},"Le ",[63,8922,8923],{},"QWeakPointeur"," ne gardant pas d'instance d'objet, car il\nn'incrémente pas le compteur de référence ",[39,8926,3371],{"href":3418,"ariaLabel":3419,"className":8927,"dataFootnoteBackref":61},[3370],[165,8929,8930,8931],{"id":3423},"s'il n'existe pas de référence vers l'objet B ailleurs dans\nl'application ",[39,8932,3371],{"href":3427,"ariaLabel":3428,"className":8933,"dataFootnoteBackref":61},[3370],[165,8935,8936,8937,8939,8940],{"id":3432},"Attention quand même, ",[63,8938,6031],{}," protège le pointeur\nmais pas le contenu ",[39,8941,3371],{"href":3441,"ariaLabel":3442,"className":8942,"dataFootnoteBackref":61},[3370],[165,8944,8946,8947],{"id":8945},"user-content-fn-9","d'autres threads pouvant inclure le thread principal ",[39,8948,3371],{"href":8949,"ariaLabel":8950,"className":8951,"dataFootnoteBackref":61},"#user-content-fnref-9","Back to reference 9",[3370],[165,8953,8955,8956,8958,8959,5538,8961],{"id":8954},"user-content-fn-10","Si l'objet est supprimé, ",[63,8957,6348],{},", sera alors remis à\n",[63,8960,6398],{},[39,8962,3371],{"href":8963,"ariaLabel":8964,"className":8965,"dataFootnoteBackref":61},"#user-content-fnref-10","Back to reference 10",[3370],[165,8967,8969,8970],{"id":8968},"user-content-fn-11","Dans le code en question, il faudrait ajouter la notion de\nmutex autour de la gestion de la queue, en cas de création parallèle. ",[39,8971,3371],{"href":8972,"ariaLabel":8973,"className":8974,"dataFootnoteBackref":61},"#user-content-fnref-11","Back to reference 11",[3370],[165,8976,8978,8979,5538,8981,8984,8985],{"id":8977},"user-content-fn-12","Le pointeur ",[32,8980,5956],{},[63,8982,8983],{},"shared_ptr"," de C++0x à pour origine\nle pointeur Boost ",[39,8986,3371],{"href":8987,"ariaLabel":8988,"className":8989,"dataFootnoteBackref":61},"#user-content-fnref-12","Back to reference 12",[3370],[1545,8991,8992],{},"html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s_ZVi, html code.shiki .s_ZVi{--shiki-default:#E06C75;--shiki-default-font-style:italic}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}",{"title":61,"searchDepth":80,"depth":80,"links":8994},[8995,8996,8997,8998,8999],{"id":3513,"depth":89,"text":3514},{"id":6041,"depth":89,"text":6042},{"id":6045,"depth":89,"text":6046},{"id":8181,"depth":89,"text":8182},{"id":1613,"depth":80,"text":3357},"2011-01-25",{"type":9,"value":9002},[9003,9005,9011,9026,9032],[12,9004,3514],{"id":3513},[17,9006,9007,5944,9009,5948],{},[32,9008,3803],{},[32,9010,5947],{},[17,9012,9013,5953,9015,9017,5962,9022,5965,9024,5968],{},[32,9014,3803],{},[32,9016,5956],{},[1607,9018,9019],{},[39,9020,461],{"href":1611,"ariaDescribedBy":9021,"dataFootnoteRef":61,"id":1614},[1613],[32,9023,5956],{},[32,9025,3803],{},[17,9027,9028,5973,9030,5977],{},[32,9029,3803],{},[32,9031,5976],{},[162,9033,9034,9049,9059,9064],{},[165,9035,9036,5987,9039,5993,9042,5997,9044,44],{},[39,9037,5986],{"href":5984,"rel":9038},[43],[39,9040,5992],{"href":5990,"rel":9041},[43],[32,9043,5996],{},[1607,9045,9046],{},[39,9047,476],{"href":1637,"ariaDescribedBy":9048,"dataFootnoteRef":61,"id":1639},[1613],[165,9050,9051,5987,9054,6013,9057,6016],{},[39,9052,6009],{"href":6007,"rel":9053},[43],[39,9055,5992],{"href":5990,"rel":9056},[43],[32,9058,5956],{},[165,9060,9061,6024],{},[39,9062,6023],{"href":6021,"rel":9063},[43],[165,9065,9066,6032,9069,6038],{},[39,9067,6031],{"href":6029,"rel":9068},[43],[1607,9070,9071],{},[39,9072,1651],{"href":1648,"ariaDescribedBy":9073,"dataFootnoteRef":61,"id":1650},[1613],{},"\u002Fpost\u002Fqt-performance-de-l-utilisation-de-qsharedpointer",{"title":5935,"description":61},"qt-performance-de-l-utilisation-de-qsharedpointer","posts\u002FProgrammation\u002F2011-01-25-qt-performance-de-l-utilisation-de-qsharedpointer",[3788,9080,1592],"performance","XqeYjPQRtPf9XXPuxti7oBEPUUnQd2DT_XGvWB1Y7Ws",{"id":9083,"title":9084,"author":7,"body":9085,"category":1560,"categorySlug":1561,"date":10295,"description":61,"excerpt":10296,"extension":1584,"location":1585,"meta":10308,"navigation":275,"path":10309,"published":275,"seo":10310,"slug":10311,"stem":10312,"tags":10313,"timeToRead":307,"__hash__":10314},"posts\u002Fposts\u002FProgrammation\u002F2010-12-22-qt-concatenation-de-chaine-de-caracteres.md","C++\u002FQt - Concaténation de chaînes de caractères",{"type":9,"value":9086,"toc":10288},[9087,9089,9092,9095,9098,9101,9105,9111,9167,9177,9180,9184,9191,9203,9209,9271,9281,9290,9352,9354,9363,9365,9373,10242,10244,10247,10269,10272,10275,10279,10285],[12,9088,3514],{"id":3513},[17,9090,9091],{},"Qt est un framework orienté objet écrit en C++ et permettant de faire\ndes interfaces graphiques à l’aide de ces widgets. Ce framework est\nutilisé par le projet KDE depuis ses débuts pour en faire un\nenvironnement très complet.",[17,9093,9094],{},"Qt permet donc de faire des interfaces graphiques mais aussi d’accéder à\ndes bases de données SQL, de faire de la communication réseau, une\ngestion simplifiée des threads, la lecture de fichier XML. Qt intègre\naussi le moteur HTML Webkit.",[17,9096,9097],{},"Qt ajoute une couche supplémentaire au C++ permettant de faire de\nl’introspection de classe un peu plus poussée (comme l’appel d’une\nméthode dont on ne connaît le nom qu’à l’exécution). Qt permet également\nla gestion d’évènement par l’intermédiaire d’un système puissant de\nSIGNALS et de SLOTS.",[17,9099,9100],{},"Dans la suite de cet article nous allons nous concentrer sur une très\npetite partie de Qt mais qui est utilisée dans beaucoup d’applications\nécrites en Qt : les chaînes de caractères, et plus précisément, la\nconcaténation de chaînes de caractères.",[1432,9102,9104],{"id":9103},"concaténation-de-chaînes-de-caractères","Concaténation de chaînes de caractères",[17,9106,9107,9108,9110],{},"Comme dans d’autres langages, la concaténation de chaînes de caractères\nse fait à l'aide de l'opérateur ",[63,9109,450],{},". Prenons un exemple simple :",[56,9112,9114],{"className":214,"code":9113,"language":216,"meta":61,"style":61},"#include \u003CQString>\n\nQString abc = \"abc\", def = \"def\";\nQString result;\nresult = abc + def;\n",[63,9115,9116,9123,9127,9147,9152],{"__ignoreMap":61},[66,9117,9118,9120],{"class":68,"line":69},[66,9119,1887],{"class":223},[66,9121,9122],{"class":76}," \u003CQString>\n",[66,9124,9125],{"class":68,"line":80},[66,9126,276],{"emptyLinePlaceholder":275},[66,9128,9129,9132,9134,9137,9140,9142,9145],{"class":68,"line":89},[66,9130,9131],{"class":230},"QString abc ",[66,9133,378],{"class":223},[66,9135,9136],{"class":76}," \"abc\"",[66,9138,9139],{"class":230},", def ",[66,9141,378],{"class":223},[66,9143,9144],{"class":76}," \"def\"",[66,9146,1952],{"class":230},[66,9148,9149],{"class":68,"line":279},[66,9150,9151],{"class":230},"QString result;\n",[66,9153,9154,9157,9159,9162,9164],{"class":68,"line":307},[66,9155,9156],{"class":230},"result ",[66,9158,378],{"class":223},[66,9160,9161],{"class":230}," abc ",[66,9163,450],{"class":223},[66,9165,9166],{"class":230}," def;\n",[17,9168,9169,9170,9172,9173,9176],{},"L'utilisation de l'opérateur ",[63,9171,450],{}," facilite l'écriture de la concaténation\ndes chaînes de caractères (tout comme l'opérateur ",[63,9174,9175],{},"=="," permet de\nfacilement comparer des chaînes de caractères de type QString).",[17,9178,9179],{},"Malheureusement cette écriture rend le code peu performant pour diverses\nraisons (que l’on peut retrouver dans la documentation de l’objet\nQString).",[12,9181,9183],{"id":9182},"concaténation-rapide-de-chaînes-de-caractères","Concaténation rapide de chaînes de caractères",[17,9185,9186,9187,9190],{},"A partir de Qt 4.6, Nokia, a ajouté un ",[63,9188,9189],{},"template"," nommé QStringBuilder\n(cet objet fait beaucoup penser à l'objet StringBuilder de JAVA\npermettant d'accélérer les concaténations de chaînes de caractères).",[17,9192,9193,9194,9197,9198,6619,9200,9202],{},"Ce template ne s’utilise pas directement mais au travers de l'opérateur\n",[63,9195,9196],{},"%",". En remplaçant donc l'opérateur ",[63,9199,450],{},[63,9201,9196],{}," on gagne en performance\n(dixit la doc de Qt).",[17,9204,9205,9206,4405],{},"Pour pouvoir utiliser l'opérateur, il suffit d'inclure le fichier\n",[63,9207,9208],{},"QStringBuilder",[56,9210,9212],{"className":214,"code":9211,"language":216,"meta":61,"style":61},"#include \u003CQStringBuilder>\n\nQString abc = \"abc\", def = \"def\", ghi = \"ghi\";\nQString result;\nresult = abc % def % ghi;\n",[63,9213,9214,9221,9225,9249,9253],{"__ignoreMap":61},[66,9215,9216,9218],{"class":68,"line":69},[66,9217,1887],{"class":223},[66,9219,9220],{"class":76}," \u003CQStringBuilder>\n",[66,9222,9223],{"class":68,"line":80},[66,9224,276],{"emptyLinePlaceholder":275},[66,9226,9227,9229,9231,9233,9235,9237,9239,9242,9244,9247],{"class":68,"line":89},[66,9228,9131],{"class":230},[66,9230,378],{"class":223},[66,9232,9136],{"class":76},[66,9234,9139],{"class":230},[66,9236,378],{"class":223},[66,9238,9144],{"class":76},[66,9240,9241],{"class":230},", ghi ",[66,9243,378],{"class":223},[66,9245,9246],{"class":76}," \"ghi\"",[66,9248,1952],{"class":230},[66,9250,9251],{"class":68,"line":279},[66,9252,9151],{"class":230},[66,9254,9255,9257,9259,9261,9263,9266,9268],{"class":68,"line":307},[66,9256,9156],{"class":230},[66,9258,378],{"class":223},[66,9260,9161],{"class":230},[66,9262,9196],{"class":223},[66,9264,9265],{"class":230}," def ",[66,9267,9196],{"class":223},[66,9269,9270],{"class":230}," ghi;\n",[17,9272,9273,9274,9277,9278,44],{},"Une autre possibilité est de définir (par exemple dans votre fichier\n.pro ou dans un include général de votre application) les définitions\n",[63,9275,9276],{},"QT_USE_FAST_CONCATENATION",", et ",[63,9279,9280],{},"QT_USE_FAST_OPERATOR_PLUS",[17,9282,9283,9284,9286,9287,9289],{},"Ces définitions permettent de remplacer l'opérateur ",[63,9285,450],{}," par l'opérateur\n",[63,9288,9196],{}," dans toute l'application. Par contre cette opération peut demander\nquelques modifications de votre code.",[56,9291,9293],{"className":214,"code":9292,"language":216,"meta":61,"style":61},"#define QT_USE_FAST_CONCATENATION\n#define QT_USE_FAST_OPERATOR_PLUS\n#include \u003CQString>\n\nQString abc = \"abc\", def = \"def\";\nQString result;\nresult = abc + def;\n",[63,9294,9295,9303,9310,9316,9320,9336,9340],{"__ignoreMap":61},[66,9296,9297,9300],{"class":68,"line":69},[66,9298,9299],{"class":223},"#define",[66,9301,9302],{"class":72}," QT_USE_FAST_CONCATENATION\n",[66,9304,9305,9307],{"class":68,"line":80},[66,9306,9299],{"class":223},[66,9308,9309],{"class":72}," QT_USE_FAST_OPERATOR_PLUS\n",[66,9311,9312,9314],{"class":68,"line":89},[66,9313,1887],{"class":223},[66,9315,9122],{"class":76},[66,9317,9318],{"class":68,"line":279},[66,9319,276],{"emptyLinePlaceholder":275},[66,9321,9322,9324,9326,9328,9330,9332,9334],{"class":68,"line":307},[66,9323,9131],{"class":230},[66,9325,378],{"class":223},[66,9327,9136],{"class":76},[66,9329,9139],{"class":230},[66,9331,378],{"class":223},[66,9333,9144],{"class":76},[66,9335,1952],{"class":230},[66,9337,9338],{"class":68,"line":329},[66,9339,9151],{"class":230},[66,9341,9342,9344,9346,9348,9350],{"class":68,"line":334},[66,9343,9156],{"class":230},[66,9345,378],{"class":223},[66,9347,9161],{"class":230},[66,9349,450],{"class":223},[66,9351,9166],{"class":230},[12,9353,8182],{"id":8181},[17,9355,9356,9357,9359,9360,9362],{},"Nous allons donc dans la suite du document vérifier que l'opérateur ",[63,9358,9196],{},"\nest plus rapide que l'opérateur ",[63,9361,450],{},". Pour cela nous allons utiliser le\nmodule de benchmark de Qt.",[4389,9364,8209],{"id":8208},[17,9366,9367,9368,9370,9371,44],{},"Voici le petit programme permettant de tester la performance de la\nconcaténation. Notre exemple simple va constituer à la concaténation de\n26 chaînes de caractères créées au début. L'appel se fera une première\nfois en utilisant l'opérateur ",[63,9369,450],{}," et une seconde fois en utilisant\nl'opérateur ",[63,9372,9196],{},[56,9374,9376],{"className":214,"code":9375,"language":216,"meta":61,"style":61},"#include \u003CQtCore\u002FQString>\n#include \u003CQtTest\u002FQtTest>\n#include \u003CQStringBuilder>\n\nclass TestPerf : public QObject\n{\n    Q_OBJECT\npublic:\n    TestPerf();\nprivate Q_SLOTS:\n    void concat();\n    void concat_data();\n};\n\nTestPerf::TestPerf()\n{\n} \n\nvoid TestPerf::concat()\n{\n    QFETCH(bool, useStringBuilder);\n    QString result;\n    QString a(\"a\"), b(\"b\"), c(\"c\"), d(\"d\"), e(\"e\"), f(\"f\"), g(\"g\"),\n    h(\"h\"), i(\"i\"), j(\"j\"), k(\"k\"), l(\"l\"), m(\"m\"), n(\"n\"), o(\"o\"),\n    p(\"p\"), q(\"q\"), r(\"r\"), s(\"s\"), t(\"t\"), u(\"u\"), v(\"v\"), w(\"w\"),\n    x(\"x\"), y(\"y\"), z(\"z\"); \n\n    if (useStringBuilder)\n    {\n        QBENCHMARK {\n            \u002F\u002F Concaténation en utilisant QStringBuilder\n            \u002F\u002F Dans ce cas la concaténation devrait être plus rapide\n            result = a % b % c % d % e % f % g % h % i % j % k % l %\n            m % n % o % p % q % r % s % t % u % v % w % x % y % z;\n        }\n    }\n    else\n    {\n        QBENCHMARK\n        {\n            \u002F\u002F Concaténation en n'utilisant pas QStringBuilder. On\n            \u002F\u002F utilise alors la concaténation normal de chaînes de\n            \u002F\u002F caractères en utilisant QString\n            result = a + b + c + d + e + f + g + h + i + j + k + l +\n            m + n + o + p + q + r + s + t + u + v + w + x + y + z;\n        }\n    }\n}\n\nvoid TestPerf::concat_data()\n{\n    QTest::addColumn\u003Cbool>(\"useStringBuilder\");\n    QTest::newRow(\"Don't use QStringBuilder\") \u003C\u003C false;\n    QTest::newRow(\"Use QStringBuilder\") \u003C\u003C true;\n}\n\nQTEST_APPLESS_MAIN(TestPerf);\n\n#include \"tst_testperf.moc\"\n",[63,9377,9378,9385,9392,9398,9402,9418,9422,9427,9431,9438,9443,9452,9461,9465,9469,9480,9484,9489,9493,9506,9510,9522,9527,9599,9681,9763,9796,9800,9807,9811,9816,9821,9826,9894,9964,9969,9973,9977,9981,9986,9991,9996,10001,10006,10061,10117,10121,10125,10129,10133,10146,10150,10169,10190,10210,10215,10220,10229,10234],{"__ignoreMap":61},[66,9379,9380,9382],{"class":68,"line":69},[66,9381,1887],{"class":223},[66,9383,9384],{"class":76}," \u003CQtCore\u002FQString>\n",[66,9386,9387,9389],{"class":68,"line":80},[66,9388,1887],{"class":223},[66,9390,9391],{"class":76}," \u003CQtTest\u002FQtTest>\n",[66,9393,9394,9396],{"class":68,"line":89},[66,9395,1887],{"class":223},[66,9397,9220],{"class":76},[66,9399,9400],{"class":68,"line":279},[66,9401,276],{"emptyLinePlaceholder":275},[66,9403,9404,9406,9409,9412,9415],{"class":68,"line":307},[66,9405,6828],{"class":223},[66,9407,9408],{"class":240}," TestPerf",[66,9410,9411],{"class":230}," : ",[66,9413,9414],{"class":223},"public",[66,9416,9417],{"class":240}," QObject\n",[66,9419,9420],{"class":68,"line":329},[66,9421,1924],{"class":230},[66,9423,9424],{"class":68,"line":334},[66,9425,9426],{"class":230},"    Q_OBJECT\n",[66,9428,9429],{"class":68,"line":340},[66,9430,6840],{"class":223},[66,9432,9433,9436],{"class":68,"line":355},[66,9434,9435],{"class":72},"    TestPerf",[66,9437,543],{"class":230},[66,9439,9440],{"class":68,"line":372},[66,9441,9442],{"class":230},"private Q_SLOTS:\n",[66,9444,9445,9447,9450],{"class":68,"line":395},[66,9446,7310],{"class":223},[66,9448,9449],{"class":72}," concat",[66,9451,543],{"class":230},[66,9453,9454,9456,9459],{"class":68,"line":400},[66,9455,7310],{"class":223},[66,9457,9458],{"class":72}," concat_data",[66,9460,543],{"class":230},[66,9462,9463],{"class":68,"line":416},[66,9464,906],{"class":230},[66,9466,9467],{"class":68,"line":421},[66,9468,276],{"emptyLinePlaceholder":275},[66,9470,9471,9474,9476,9478],{"class":68,"line":485},[66,9472,9473],{"class":240},"TestPerf",[66,9475,1001],{"class":230},[66,9477,9473],{"class":72},[66,9479,4820],{"class":230},[66,9481,9482],{"class":68,"line":490},[66,9483,1924],{"class":230},[66,9485,9486],{"class":68,"line":520},[66,9487,9488],{"class":230},"} \n",[66,9490,9491],{"class":68,"line":546},[66,9492,276],{"emptyLinePlaceholder":275},[66,9494,9495,9497,9499,9501,9504],{"class":68,"line":558},[66,9496,6260],{"class":223},[66,9498,9408],{"class":240},[66,9500,1001],{"class":230},[66,9502,9503],{"class":72},"concat",[66,9505,4820],{"class":230},[66,9507,9508],{"class":68,"line":607},[66,9509,1924],{"class":230},[66,9511,9512,9515,9517,9519],{"class":68,"line":645},[66,9513,9514],{"class":72},"    QFETCH",[66,9516,231],{"class":230},[66,9518,3993],{"class":223},[66,9520,9521],{"class":230},", useStringBuilder);\n",[66,9523,9524],{"class":68,"line":653},[66,9525,9526],{"class":230},"    QString result;\n",[66,9528,9529,9532,9534,9536,9539,9541,9543,9545,9548,9550,9552,9554,9557,9559,9562,9564,9567,9569,9571,9573,9576,9578,9581,9583,9586,9588,9591,9593,9596],{"class":68,"line":1278},[66,9530,9531],{"class":230},"    QString ",[66,9533,39],{"class":72},[66,9535,231],{"class":230},[66,9537,9538],{"class":76},"\"a\"",[66,9540,1162],{"class":230},[66,9542,1008],{"class":72},[66,9544,231],{"class":230},[66,9546,9547],{"class":76},"\"b\"",[66,9549,1162],{"class":230},[66,9551,7496],{"class":72},[66,9553,231],{"class":230},[66,9555,9556],{"class":76},"\"c\"",[66,9558,1162],{"class":230},[66,9560,9561],{"class":72},"d",[66,9563,231],{"class":230},[66,9565,9566],{"class":76},"\"d\"",[66,9568,1162],{"class":230},[66,9570,505],{"class":72},[66,9572,231],{"class":230},[66,9574,9575],{"class":76},"\"e\"",[66,9577,1162],{"class":230},[66,9579,9580],{"class":72},"f",[66,9582,231],{"class":230},[66,9584,9585],{"class":76},"\"f\"",[66,9587,1162],{"class":230},[66,9589,9590],{"class":72},"g",[66,9592,231],{"class":230},[66,9594,9595],{"class":76},"\"g\"",[66,9597,9598],{"class":230},"),\n",[66,9600,9601,9604,9606,9609,9611,9614,9616,9619,9621,9624,9626,9629,9631,9634,9636,9639,9641,9644,9646,9649,9651,9654,9656,9659,9661,9664,9666,9669,9671,9674,9676,9679],{"class":68,"line":1301},[66,9602,9603],{"class":72},"    h",[66,9605,231],{"class":230},[66,9607,9608],{"class":76},"\"h\"",[66,9610,1162],{"class":230},[66,9612,9613],{"class":72},"i",[66,9615,231],{"class":230},[66,9617,9618],{"class":76},"\"i\"",[66,9620,1162],{"class":230},[66,9622,9623],{"class":72},"j",[66,9625,231],{"class":230},[66,9627,9628],{"class":76},"\"j\"",[66,9630,1162],{"class":230},[66,9632,9633],{"class":72},"k",[66,9635,231],{"class":230},[66,9637,9638],{"class":76},"\"k\"",[66,9640,1162],{"class":230},[66,9642,9643],{"class":72},"l",[66,9645,231],{"class":230},[66,9647,9648],{"class":76},"\"l\"",[66,9650,1162],{"class":230},[66,9652,9653],{"class":72},"m",[66,9655,231],{"class":230},[66,9657,9658],{"class":76},"\"m\"",[66,9660,1162],{"class":230},[66,9662,9663],{"class":72},"n",[66,9665,231],{"class":230},[66,9667,9668],{"class":76},"\"n\"",[66,9670,1162],{"class":230},[66,9672,9673],{"class":72},"o",[66,9675,231],{"class":230},[66,9677,9678],{"class":76},"\"o\"",[66,9680,9598],{"class":230},[66,9682,9683,9686,9688,9691,9693,9696,9698,9701,9703,9706,9708,9711,9713,9716,9718,9721,9723,9726,9728,9731,9733,9736,9738,9741,9743,9746,9748,9751,9753,9756,9758,9761],{"class":68,"line":1320},[66,9684,9685],{"class":72},"    p",[66,9687,231],{"class":230},[66,9689,9690],{"class":76},"\"p\"",[66,9692,1162],{"class":230},[66,9694,9695],{"class":72},"q",[66,9697,231],{"class":230},[66,9699,9700],{"class":76},"\"q\"",[66,9702,1162],{"class":230},[66,9704,9705],{"class":72},"r",[66,9707,231],{"class":230},[66,9709,9710],{"class":76},"\"r\"",[66,9712,1162],{"class":230},[66,9714,9715],{"class":72},"s",[66,9717,231],{"class":230},[66,9719,9720],{"class":76},"\"s\"",[66,9722,1162],{"class":230},[66,9724,9725],{"class":72},"t",[66,9727,231],{"class":230},[66,9729,9730],{"class":76},"\"t\"",[66,9732,1162],{"class":230},[66,9734,9735],{"class":72},"u",[66,9737,231],{"class":230},[66,9739,9740],{"class":76},"\"u\"",[66,9742,1162],{"class":230},[66,9744,9745],{"class":72},"v",[66,9747,231],{"class":230},[66,9749,9750],{"class":76},"\"v\"",[66,9752,1162],{"class":230},[66,9754,9755],{"class":72},"w",[66,9757,231],{"class":230},[66,9759,9760],{"class":76},"\"w\"",[66,9762,9598],{"class":230},[66,9764,9765,9768,9770,9773,9775,9778,9780,9783,9785,9788,9790,9793],{"class":68,"line":1328},[66,9766,9767],{"class":72},"    x",[66,9769,231],{"class":230},[66,9771,9772],{"class":76},"\"x\"",[66,9774,1162],{"class":230},[66,9776,9777],{"class":72},"y",[66,9779,231],{"class":230},[66,9781,9782],{"class":76},"\"y\"",[66,9784,1162],{"class":230},[66,9786,9787],{"class":72},"z",[66,9789,231],{"class":230},[66,9791,9792],{"class":76},"\"z\"",[66,9794,9795],{"class":230},"); \n",[66,9797,9798],{"class":68,"line":1367},[66,9799,276],{"emptyLinePlaceholder":275},[66,9801,9802,9804],{"class":68,"line":1398},[66,9803,493],{"class":223},[66,9805,9806],{"class":230}," (useStringBuilder)\n",[66,9808,9809],{"class":68,"line":1405},[66,9810,6190],{"class":230},[66,9812,9813],{"class":68,"line":1410},[66,9814,9815],{"class":230},"        QBENCHMARK {\n",[66,9817,9818],{"class":68,"line":3174},[66,9819,9820],{"class":351},"            \u002F\u002F Concaténation en utilisant QStringBuilder\n",[66,9822,9823],{"class":68,"line":3180},[66,9824,9825],{"class":351},"            \u002F\u002F Dans ce cas la concaténation devrait être plus rapide\n",[66,9827,9828,9831,9833,9836,9838,9841,9843,9846,9848,9851,9853,9856,9858,9861,9863,9866,9868,9871,9873,9876,9878,9881,9883,9886,9888,9891],{"class":68,"line":3186},[66,9829,9830],{"class":230},"            result ",[66,9832,378],{"class":223},[66,9834,9835],{"class":230}," a ",[66,9837,9196],{"class":223},[66,9839,9840],{"class":230}," b ",[66,9842,9196],{"class":223},[66,9844,9845],{"class":230}," c ",[66,9847,9196],{"class":223},[66,9849,9850],{"class":230}," d ",[66,9852,9196],{"class":223},[66,9854,9855],{"class":230}," e ",[66,9857,9196],{"class":223},[66,9859,9860],{"class":230}," f ",[66,9862,9196],{"class":223},[66,9864,9865],{"class":230}," g ",[66,9867,9196],{"class":223},[66,9869,9870],{"class":230}," h ",[66,9872,9196],{"class":223},[66,9874,9875],{"class":230}," i ",[66,9877,9196],{"class":223},[66,9879,9880],{"class":230}," j ",[66,9882,9196],{"class":223},[66,9884,9885],{"class":230}," k ",[66,9887,9196],{"class":223},[66,9889,9890],{"class":230}," l ",[66,9892,9893],{"class":223},"%\n",[66,9895,9896,9899,9901,9904,9906,9909,9911,9914,9916,9919,9921,9924,9926,9929,9931,9934,9936,9939,9941,9944,9946,9949,9951,9954,9956,9959,9961],{"class":68,"line":3192},[66,9897,9898],{"class":230},"            m ",[66,9900,9196],{"class":223},[66,9902,9903],{"class":230}," n ",[66,9905,9196],{"class":223},[66,9907,9908],{"class":230}," o ",[66,9910,9196],{"class":223},[66,9912,9913],{"class":230}," p ",[66,9915,9196],{"class":223},[66,9917,9918],{"class":230}," q ",[66,9920,9196],{"class":223},[66,9922,9923],{"class":230}," r ",[66,9925,9196],{"class":223},[66,9927,9928],{"class":230}," s ",[66,9930,9196],{"class":223},[66,9932,9933],{"class":230}," t ",[66,9935,9196],{"class":223},[66,9937,9938],{"class":230}," u ",[66,9940,9196],{"class":223},[66,9942,9943],{"class":230}," v ",[66,9945,9196],{"class":223},[66,9947,9948],{"class":230}," w ",[66,9950,9196],{"class":223},[66,9952,9953],{"class":230}," x ",[66,9955,9196],{"class":223},[66,9957,9958],{"class":230}," y ",[66,9960,9196],{"class":223},[66,9962,9963],{"class":230}," z;\n",[66,9965,9966],{"class":68,"line":3198},[66,9967,9968],{"class":230},"        }\n",[66,9970,9971],{"class":68,"line":3204},[66,9972,656],{"class":230},[66,9974,9975],{"class":68,"line":3210},[66,9976,7952],{"class":223},[66,9978,9979],{"class":68,"line":3216},[66,9980,6190],{"class":230},[66,9982,9983],{"class":68,"line":3222},[66,9984,9985],{"class":230},"        QBENCHMARK\n",[66,9987,9988],{"class":68,"line":3228},[66,9989,9990],{"class":230},"        {\n",[66,9992,9993],{"class":68,"line":3234},[66,9994,9995],{"class":351},"            \u002F\u002F Concaténation en n'utilisant pas QStringBuilder. On\n",[66,9997,9998],{"class":68,"line":3239},[66,9999,10000],{"class":351},"            \u002F\u002F utilise alors la concaténation normal de chaînes de\n",[66,10002,10003],{"class":68,"line":3245},[66,10004,10005],{"class":351},"            \u002F\u002F caractères en utilisant QString\n",[66,10007,10008,10010,10012,10014,10016,10018,10020,10022,10024,10026,10028,10030,10032,10034,10036,10038,10040,10042,10044,10046,10048,10050,10052,10054,10056,10058],{"class":68,"line":3251},[66,10009,9830],{"class":230},[66,10011,378],{"class":223},[66,10013,9835],{"class":230},[66,10015,450],{"class":223},[66,10017,9840],{"class":230},[66,10019,450],{"class":223},[66,10021,9845],{"class":230},[66,10023,450],{"class":223},[66,10025,9850],{"class":230},[66,10027,450],{"class":223},[66,10029,9855],{"class":230},[66,10031,450],{"class":223},[66,10033,9860],{"class":230},[66,10035,450],{"class":223},[66,10037,9865],{"class":230},[66,10039,450],{"class":223},[66,10041,9870],{"class":230},[66,10043,450],{"class":223},[66,10045,9875],{"class":230},[66,10047,450],{"class":223},[66,10049,9880],{"class":230},[66,10051,450],{"class":223},[66,10053,9885],{"class":230},[66,10055,450],{"class":223},[66,10057,9890],{"class":230},[66,10059,10060],{"class":223},"+\n",[66,10062,10063,10065,10067,10069,10071,10073,10075,10077,10079,10081,10083,10085,10087,10089,10091,10093,10095,10097,10099,10101,10103,10105,10107,10109,10111,10113,10115],{"class":68,"line":3257},[66,10064,9898],{"class":230},[66,10066,450],{"class":223},[66,10068,9903],{"class":230},[66,10070,450],{"class":223},[66,10072,9908],{"class":230},[66,10074,450],{"class":223},[66,10076,9913],{"class":230},[66,10078,450],{"class":223},[66,10080,9918],{"class":230},[66,10082,450],{"class":223},[66,10084,9923],{"class":230},[66,10086,450],{"class":223},[66,10088,9928],{"class":230},[66,10090,450],{"class":223},[66,10092,9933],{"class":230},[66,10094,450],{"class":223},[66,10096,9938],{"class":230},[66,10098,450],{"class":223},[66,10100,9943],{"class":230},[66,10102,450],{"class":223},[66,10104,9948],{"class":230},[66,10106,450],{"class":223},[66,10108,9953],{"class":230},[66,10110,450],{"class":223},[66,10112,9958],{"class":230},[66,10114,450],{"class":223},[66,10116,9963],{"class":230},[66,10118,10119],{"class":68,"line":3263},[66,10120,9968],{"class":230},[66,10122,10123],{"class":68,"line":3269},[66,10124,656],{"class":230},[66,10126,10127],{"class":68,"line":3275},[66,10128,1413],{"class":230},[66,10130,10131],{"class":68,"line":3281},[66,10132,276],{"emptyLinePlaceholder":275},[66,10134,10135,10137,10139,10141,10144],{"class":68,"line":3287},[66,10136,6260],{"class":223},[66,10138,9408],{"class":240},[66,10140,1001],{"class":230},[66,10142,10143],{"class":72},"concat_data",[66,10145,4820],{"class":230},[66,10147,10148],{"class":68,"line":3293},[66,10149,1924],{"class":230},[66,10151,10152,10155,10158,10160,10162,10164,10167],{"class":68,"line":3299},[66,10153,10154],{"class":230},"    QTest::",[66,10156,10157],{"class":72},"addColumn",[66,10159,532],{"class":230},[66,10161,3993],{"class":223},[66,10163,6762],{"class":230},[66,10165,10166],{"class":76},"\"useStringBuilder\"",[66,10168,1188],{"class":230},[66,10170,10171,10173,10176,10178,10181,10183,10185,10188],{"class":68,"line":3305},[66,10172,10154],{"class":230},[66,10174,10175],{"class":72},"newRow",[66,10177,231],{"class":230},[66,10179,10180],{"class":76},"\"Don't use QStringBuilder\"",[66,10182,637],{"class":230},[66,10184,1932],{"class":223},[66,10186,10187],{"class":114}," false",[66,10189,1952],{"class":230},[66,10191,10192,10194,10196,10198,10201,10203,10205,10208],{"class":68,"line":3311},[66,10193,10154],{"class":230},[66,10195,10175],{"class":72},[66,10197,231],{"class":230},[66,10199,10200],{"class":76},"\"Use QStringBuilder\"",[66,10202,637],{"class":230},[66,10204,1932],{"class":223},[66,10206,10207],{"class":114}," true",[66,10209,1952],{"class":230},[66,10211,10213],{"class":68,"line":10212},55,[66,10214,1413],{"class":230},[66,10216,10218],{"class":68,"line":10217},56,[66,10219,276],{"emptyLinePlaceholder":275},[66,10221,10223,10226],{"class":68,"line":10222},57,[66,10224,10225],{"class":72},"QTEST_APPLESS_MAIN",[66,10227,10228],{"class":230},"(TestPerf);\n",[66,10230,10232],{"class":68,"line":10231},58,[66,10233,276],{"emptyLinePlaceholder":275},[66,10235,10237,10239],{"class":68,"line":10236},59,[66,10238,1887],{"class":223},[66,10240,10241],{"class":76}," \"tst_testperf.moc\"\n",[4389,10243,8720],{"id":8719},[17,10245,10246],{},"Le test a été fait en utilisant la version 4.6.3 de Qt. Le résultat est\nsensiblement le même avec la version 4.7.0",[8428,10248,10249,10259],{},[8431,10250,10251],{},[8434,10252,10253,10256],{},[8437,10254,10255],{},"Sans QStringBuilder",[8437,10257,10258],{},"Avec QStringBuilder",[8443,10260,10261],{},[8434,10262,10263,10266],{},[8448,10264,10265],{},"0.00367 msec",[8448,10267,10268],{},"0.00046 msec",[17,10270,10271],{},"On voit dans ce test que la version en utilisant QStringBuilder est 8\nfois plus rapide que sans. Bien sûr vu le temps que prend la\nconcaténation de chaînes de caractères, ce test commence à avoir de\nl'intérêt uniquement à partir du moment où on fait beaucoup de\nconcaténation dans la seconde, ou si les temps de réponses sont\ncritiques.",[17,10273,10274],{},"Sur ce, je vous souhaite à tous un Joyeux noël et une bonne année.",[4389,10276,10278],{"id":10277},"le-programme","Le programme",[17,10280,10281,10282,44],{},"Vous pouvez trouver le programme ",[39,10283,3437],{"href":10284},"\u002FProgrammation\u002Fqt-concatenation-de-chaine-de-caracteres\u002Ftest-perfconcat.7z",[1545,10286,10287],{},"html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}",{"title":61,"searchDepth":80,"depth":80,"links":10289},[10290,10291],{"id":3513,"depth":89,"text":3514},{"id":9103,"depth":80,"text":9104,"children":10292},[10293,10294],{"id":9182,"depth":89,"text":9183},{"id":8181,"depth":89,"text":8182},"2010-12-22",{"type":9,"value":10297},[10298,10300,10302,10304,10306],[12,10299,3514],{"id":3513},[17,10301,9091],{},[17,10303,9094],{},[17,10305,9097],{},[17,10307,9100],{},{},"\u002Fpost\u002Fqt-concatenation-de-chaine-de-caracteres",{"title":9084,"description":61},"qt-concatenation-de-chaine-de-caracteres","posts\u002FProgrammation\u002F2010-12-22-qt-concatenation-de-chaine-de-caracteres",[9080,1592],"tnYQV8OJKsLZvtUPPbMHph26Eitmdp4-hd-STXhGP2A",{"id":10316,"title":10317,"author":7,"body":10318,"category":1560,"categorySlug":1561,"date":11960,"description":61,"excerpt":11961,"extension":1584,"location":1585,"meta":11996,"navigation":275,"path":11997,"published":275,"seo":11998,"slug":11999,"stem":12000,"tags":12001,"timeToRead":334,"__hash__":12002},"posts\u002Fposts\u002FProgrammation\u002F2010-06-06-calcul-de-la-distance.md","Calcul de la distance entre deux fichiers",{"type":9,"value":10319,"toc":11954},[10320,10322,10330,10336,10344,10364,10366,10369,10372,10375,10378,10381,10384,10397,10408,10411,10426,10429,10445,10449,10462,10465,10959,10962,11070,11920,11923,11926,11933,11951],[12,10321,3514],{"id":3513},[17,10323,4290,10324,10329],{},[39,10325,10328],{"href":10326,"rel":10327},"http:\u002F\u002Flinuxfr.org\u002Fforums\u002F20\u002F28366.html",[43],"billet sur LinuxFR",", où je demandais comment calculer la\ndistance (ou le pourcentage de similitude entre deux logiciels), j'ai\nobtenu la formule suivante :",[56,10331,10334],{"className":10332,"code":10333,"language":840},[838],"distance = 1 - ( C(A) + C(B) - C(AB) ) \u002F Max(C(A), C(B))\n",[63,10335,10333],{"__ignoreMap":61},[17,10337,10338,10339,44],{},"où C(X) est la taille du fichier X compressé",[1607,10340,10341],{},[39,10342,461],{"href":1611,"ariaDescribedBy":10343,"dataFootnoteRef":61,"id":1614},[1613],[17,10345,10346,10347,251,10350,3581,10353,10356,10357,10359,10360,10363],{},"Après avoir testé les formats ",[63,10348,10349],{},"gzip",[63,10351,10352],{},"bzip2",[63,10354,10355],{},"lzma",", j'ai conclu que\nle format de compression le plus performant pour le calcul, est le\nformat ",[63,10358,10355],{},", car le dictionnaire avec ",[32,10361,10362],{},"la mise en commun"," était le\nplus gros, et donc le calcul de distance est plus efficace.",[12,10365,10278],{"id":10277},[17,10367,10368],{},"J'ai donc décidé d'écrire un programme parcourant un dossier (avec\nplusieurs milliers de fichiers) et de calculer pour toutes les\ncombinaisons des fichiers la distance entre chaque fichier. Ce programme\nconsommant énormément de mémoire, il se peut que pour un grand nombre de\nfichier, le programme se plante avec une erreur d'allocation de mémoire.",[17,10370,10371],{},"Ce programme permet de pouvoir faire une cartographie de ces fichiers et\nainsi de pouvoir les classer. Testé sur des fichiers textes (sources de\nlogiciels), le programme est assez efficace.",[17,10373,10374],{},"Testé sur des images, ou des vidéos, les fichiers sont considérés comme\ntous éloignés les uns des autres, même s'ils sont identiques à\ncompression différente près, ou s'ils sont identiques à un mouvement\nprès sur la photo (du genre une photo où une même personne se tient dans\nune position différente).",[17,10376,10377],{},"Si vous avez une idée sur comment calculer la distance entre deux\nfichiers déjà compressés (avec perte qui plus est), ca m'intéresse. :)",[17,10379,10380],{},"Comme l'exécution est très lente (compression lzma niveau 9), le\nprogramme peut être arrêté et redémarré.",[17,10382,10383],{},"Pour démarrer le programme, il faut exécuter la commande :",[56,10385,10387],{"className":58,"code":10386,"language":60,"meta":61,"style":61},".\u002Fcalcul_distance \u002Fmon\u002Fdossier\n",[63,10388,10389],{"__ignoreMap":61},[66,10390,10391,10394],{"class":68,"line":69},[66,10392,10393],{"class":72},".\u002Fcalcul_distance",[66,10395,10396],{"class":76}," \u002Fmon\u002Fdossier\n",[17,10398,10399,10400,10403,10404,10407],{},"Le programme va alors créer un fichier\n",[63,10401,10402],{},"{5ac1fd3c-504f-4110-9f7e-d6fc89e57bdb}.db"," où\n",[63,10405,10406],{},"{5ac1fd3c-504f-4110-9f7e-d6fc89e57bdb}"," est différent à chaque nouveau\nlancement.",[17,10409,10410],{},"Pour reprendre le traitement où il était, il suffit alors de lancer :",[56,10412,10414],{"className":58,"code":10413,"language":60,"meta":61,"style":61},".\u002Fcalcul_distance --uuid {5ac1fd3c-504f-4110-9f7e-d6fc89e57bdb}\n",[63,10415,10416],{"__ignoreMap":61},[66,10417,10418,10420,10423],{"class":68,"line":69},[66,10419,10393],{"class":72},[66,10421,10422],{"class":114}," --uuid",[66,10424,10425],{"class":76}," {5ac1fd3c-504f-4110-9f7e-d6fc89e57bdb}\n",[17,10427,10428],{},"Si on veut ajouter un dossier au traitement après coup :",[56,10430,10432],{"className":58,"code":10431,"language":60,"meta":61,"style":61},".\u002Fcalcul_distance \u002Fnouveau\u002Fdossier --uuid {5ac1fd3c-504f-4110-9f7e-d6fc89e57bdb}\n",[63,10433,10434],{"__ignoreMap":61},[66,10435,10436,10438,10441,10443],{"class":68,"line":69},[66,10437,10393],{"class":72},[66,10439,10440],{"class":76}," \u002Fnouveau\u002Fdossier",[66,10442,10422],{"class":114},[66,10444,10425],{"class":76},[12,10446,10448],{"id":10447},"exemple","Exemple",[17,10450,10451,10452,10454,10455,10457,10458,10461],{},"Par exemple soit les différentes versions d'un logiciel, mis dans des\narchives ",[63,10453,3642],{},". Pour ne prendre que le code source des versions, on va\nsupprimer tous les fichiers suivants de l'archive ",[63,10456,3642],{}," :\n",[63,10459,10460],{},"*.jpg, *.png, *.ico, *.qm, *.db",", ... les sources externes à\nl'application. On ne garde donc que les fichiers textes dont nous avons\nla possession.",[17,10463,10464],{},"Après le nettoyage des dossiers :",[56,10466,10468],{"className":58,"code":10467,"language":60,"meta":61,"style":61},"$ for i in `ls` ; do\n> tar -c $i\u002F*\n> $i.tar\n> done\n$ ls -l\n-rw-r--r-- 1 phoenix phoenix 2,5M  6 juin  13:24 v0.6.10.tar\n-rw-r--r-- 1 phoenix phoenix 440K  6 juin  13:24 v0.6.4.tar\n-rw-r--r-- 1 phoenix phoenix 530K  6 juin  13:24 v0.6.5.tar\n-rw-r--r-- 1 phoenix phoenix 610K  6 juin  13:24 v0.6.6.tar\n-rw-r--r-- 1 phoenix phoenix 690K  6 juin  13:24 v0.6.7.tar\n-rw-r--r-- 1 phoenix phoenix 1,2M  6 juin  13:24 v0.6.8.tar\n-rw-r--r-- 1 phoenix phoenix 1,3M  6 juin  13:24 v0.6.9.tar\n-rw-r--r-- 1 phoenix phoenix 2,9M  6 juin  13:24 v0.7.0.tar\n-rw-r--r-- 1 phoenix phoenix 2,2M  6 juin  13:24 v0.7.1.tar\n-rw-r--r-- 1 phoenix phoenix 3,3M  6 juin  13:24 v0.7.2.tar\n-rw-r--r-- 1 phoenix phoenix 3,3M  6 juin  13:24 v0.8.0.tar\n-rw-r--r-- 1 phoenix phoenix 3,1M  6 juin  13:24 v0.8.1_services.tar\n-rw-r--r-- 1 phoenix phoenix 3,1M  6 juin  13:24 v0.8.1.tar\n-rw-r--r-- 1 phoenix phoenix 3,8M  6 juin  13:24 v0.9.0.tar\n$ cd ..\n$ calcul_distance .\u002Fxinx\u002F\nStep 0 : Create database\nStep 1 : Create file list\nStep 2 : Compress single file\nStep 3 : Compress pair file\n$ ls\n{051b93a0-d9a9-4778-ac73-81ee01a3905d}.db\nxinx\n$ sqlite3 {051b93a0-d9a9-4778-ac73-81ee01a3905d}.db\n",[63,10469,10470,10498,10509,10518,10525,10535,10562,10584,10606,10628,10650,10672,10694,10716,10738,10760,10781,10803,10824,10846,10856,10866,10882,10898,10916,10932,10939,10944,10949],{"__ignoreMap":61},[66,10471,10472,10475,10477,10480,10483,10486,10489,10492,10495],{"class":68,"line":69},[66,10473,10474],{"class":72},"$",[66,10476,1821],{"class":76},[66,10478,10479],{"class":76}," i",[66,10481,10482],{"class":76}," in",[66,10484,10485],{"class":76}," `",[66,10487,10488],{"class":72},"ls",[66,10490,10491],{"class":76},"`",[66,10493,10494],{"class":230}," ; ",[66,10496,10497],{"class":223},"do\n",[66,10499,10500,10503,10506],{"class":68,"line":80},[66,10501,10502],{"class":230},"> tar -c ",[66,10504,10505],{"class":437},"$i",[66,10507,10508],{"class":230},"\u002F*\n",[66,10510,10511,10513,10515],{"class":68,"line":89},[66,10512,6274],{"class":230},[66,10514,10505],{"class":437},[66,10516,10517],{"class":230},".tar\n",[66,10519,10520,10522],{"class":68,"line":279},[66,10521,6274],{"class":230},[66,10523,10524],{"class":223},"done\n",[66,10526,10527,10529,10532],{"class":68,"line":307},[66,10528,10474],{"class":72},[66,10530,10531],{"class":76}," ls",[66,10533,10534],{"class":114}," -l\n",[66,10536,10537,10540,10542,10545,10547,10550,10553,10556,10559],{"class":68,"line":329},[66,10538,10539],{"class":72},"-rw-r--r--",[66,10541,502],{"class":114},[66,10543,10544],{"class":76}," phoenix",[66,10546,10544],{"class":76},[66,10548,10549],{"class":76}," 2,5M",[66,10551,10552],{"class":114},"  6",[66,10554,10555],{"class":76}," juin",[66,10557,10558],{"class":76},"  13:24",[66,10560,10561],{"class":76}," v0.6.10.tar\n",[66,10563,10564,10566,10568,10570,10572,10575,10577,10579,10581],{"class":68,"line":334},[66,10565,10539],{"class":72},[66,10567,502],{"class":114},[66,10569,10544],{"class":76},[66,10571,10544],{"class":76},[66,10573,10574],{"class":76}," 440K",[66,10576,10552],{"class":114},[66,10578,10555],{"class":76},[66,10580,10558],{"class":76},[66,10582,10583],{"class":76}," v0.6.4.tar\n",[66,10585,10586,10588,10590,10592,10594,10597,10599,10601,10603],{"class":68,"line":340},[66,10587,10539],{"class":72},[66,10589,502],{"class":114},[66,10591,10544],{"class":76},[66,10593,10544],{"class":76},[66,10595,10596],{"class":76}," 530K",[66,10598,10552],{"class":114},[66,10600,10555],{"class":76},[66,10602,10558],{"class":76},[66,10604,10605],{"class":76}," v0.6.5.tar\n",[66,10607,10608,10610,10612,10614,10616,10619,10621,10623,10625],{"class":68,"line":355},[66,10609,10539],{"class":72},[66,10611,502],{"class":114},[66,10613,10544],{"class":76},[66,10615,10544],{"class":76},[66,10617,10618],{"class":76}," 610K",[66,10620,10552],{"class":114},[66,10622,10555],{"class":76},[66,10624,10558],{"class":76},[66,10626,10627],{"class":76}," v0.6.6.tar\n",[66,10629,10630,10632,10634,10636,10638,10641,10643,10645,10647],{"class":68,"line":372},[66,10631,10539],{"class":72},[66,10633,502],{"class":114},[66,10635,10544],{"class":76},[66,10637,10544],{"class":76},[66,10639,10640],{"class":76}," 690K",[66,10642,10552],{"class":114},[66,10644,10555],{"class":76},[66,10646,10558],{"class":76},[66,10648,10649],{"class":76}," v0.6.7.tar\n",[66,10651,10652,10654,10656,10658,10660,10663,10665,10667,10669],{"class":68,"line":395},[66,10653,10539],{"class":72},[66,10655,502],{"class":114},[66,10657,10544],{"class":76},[66,10659,10544],{"class":76},[66,10661,10662],{"class":76}," 1,2M",[66,10664,10552],{"class":114},[66,10666,10555],{"class":76},[66,10668,10558],{"class":76},[66,10670,10671],{"class":76}," v0.6.8.tar\n",[66,10673,10674,10676,10678,10680,10682,10685,10687,10689,10691],{"class":68,"line":400},[66,10675,10539],{"class":72},[66,10677,502],{"class":114},[66,10679,10544],{"class":76},[66,10681,10544],{"class":76},[66,10683,10684],{"class":76}," 1,3M",[66,10686,10552],{"class":114},[66,10688,10555],{"class":76},[66,10690,10558],{"class":76},[66,10692,10693],{"class":76}," v0.6.9.tar\n",[66,10695,10696,10698,10700,10702,10704,10707,10709,10711,10713],{"class":68,"line":416},[66,10697,10539],{"class":72},[66,10699,502],{"class":114},[66,10701,10544],{"class":76},[66,10703,10544],{"class":76},[66,10705,10706],{"class":76}," 2,9M",[66,10708,10552],{"class":114},[66,10710,10555],{"class":76},[66,10712,10558],{"class":76},[66,10714,10715],{"class":76}," v0.7.0.tar\n",[66,10717,10718,10720,10722,10724,10726,10729,10731,10733,10735],{"class":68,"line":421},[66,10719,10539],{"class":72},[66,10721,502],{"class":114},[66,10723,10544],{"class":76},[66,10725,10544],{"class":76},[66,10727,10728],{"class":76}," 2,2M",[66,10730,10552],{"class":114},[66,10732,10555],{"class":76},[66,10734,10558],{"class":76},[66,10736,10737],{"class":76}," v0.7.1.tar\n",[66,10739,10740,10742,10744,10746,10748,10751,10753,10755,10757],{"class":68,"line":485},[66,10741,10539],{"class":72},[66,10743,502],{"class":114},[66,10745,10544],{"class":76},[66,10747,10544],{"class":76},[66,10749,10750],{"class":76}," 3,3M",[66,10752,10552],{"class":114},[66,10754,10555],{"class":76},[66,10756,10558],{"class":76},[66,10758,10759],{"class":76}," v0.7.2.tar\n",[66,10761,10762,10764,10766,10768,10770,10772,10774,10776,10778],{"class":68,"line":490},[66,10763,10539],{"class":72},[66,10765,502],{"class":114},[66,10767,10544],{"class":76},[66,10769,10544],{"class":76},[66,10771,10750],{"class":76},[66,10773,10552],{"class":114},[66,10775,10555],{"class":76},[66,10777,10558],{"class":76},[66,10779,10780],{"class":76}," v0.8.0.tar\n",[66,10782,10783,10785,10787,10789,10791,10794,10796,10798,10800],{"class":68,"line":520},[66,10784,10539],{"class":72},[66,10786,502],{"class":114},[66,10788,10544],{"class":76},[66,10790,10544],{"class":76},[66,10792,10793],{"class":76}," 3,1M",[66,10795,10552],{"class":114},[66,10797,10555],{"class":76},[66,10799,10558],{"class":76},[66,10801,10802],{"class":76}," v0.8.1_services.tar\n",[66,10804,10805,10807,10809,10811,10813,10815,10817,10819,10821],{"class":68,"line":546},[66,10806,10539],{"class":72},[66,10808,502],{"class":114},[66,10810,10544],{"class":76},[66,10812,10544],{"class":76},[66,10814,10793],{"class":76},[66,10816,10552],{"class":114},[66,10818,10555],{"class":76},[66,10820,10558],{"class":76},[66,10822,10823],{"class":76}," v0.8.1.tar\n",[66,10825,10826,10828,10830,10832,10834,10837,10839,10841,10843],{"class":68,"line":558},[66,10827,10539],{"class":72},[66,10829,502],{"class":114},[66,10831,10544],{"class":76},[66,10833,10544],{"class":76},[66,10835,10836],{"class":76}," 3,8M",[66,10838,10552],{"class":114},[66,10840,10555],{"class":76},[66,10842,10558],{"class":76},[66,10844,10845],{"class":76}," v0.9.0.tar\n",[66,10847,10848,10850,10853],{"class":68,"line":607},[66,10849,10474],{"class":72},[66,10851,10852],{"class":76}," cd",[66,10854,10855],{"class":76}," ..\n",[66,10857,10858,10860,10863],{"class":68,"line":645},[66,10859,10474],{"class":72},[66,10861,10862],{"class":76}," calcul_distance",[66,10864,10865],{"class":76}," .\u002Fxinx\u002F\n",[66,10867,10868,10871,10873,10876,10879],{"class":68,"line":653},[66,10869,10870],{"class":72},"Step",[66,10872,1949],{"class":114},[66,10874,10875],{"class":76}," :",[66,10877,10878],{"class":76}," Create",[66,10880,10881],{"class":76}," database\n",[66,10883,10884,10886,10888,10890,10892,10895],{"class":68,"line":1278},[66,10885,10870],{"class":72},[66,10887,502],{"class":114},[66,10889,10875],{"class":76},[66,10891,10878],{"class":76},[66,10893,10894],{"class":76}," file",[66,10896,10897],{"class":76}," list\n",[66,10899,10900,10902,10905,10907,10910,10913],{"class":68,"line":1301},[66,10901,10870],{"class":72},[66,10903,10904],{"class":114}," 2",[66,10906,10875],{"class":76},[66,10908,10909],{"class":76}," Compress",[66,10911,10912],{"class":76}," single",[66,10914,10915],{"class":76}," file\n",[66,10917,10918,10920,10923,10925,10927,10930],{"class":68,"line":1320},[66,10919,10870],{"class":72},[66,10921,10922],{"class":114}," 3",[66,10924,10875],{"class":76},[66,10926,10909],{"class":76},[66,10928,10929],{"class":76}," pair",[66,10931,10915],{"class":76},[66,10933,10934,10936],{"class":68,"line":1328},[66,10935,10474],{"class":72},[66,10937,10938],{"class":76}," ls\n",[66,10940,10941],{"class":68,"line":1367},[66,10942,10943],{"class":230},"{051b93a0-d9a9-4778-ac73-81ee01a3905d}.db\n",[66,10945,10946],{"class":68,"line":1398},[66,10947,10948],{"class":72},"xinx\n",[66,10950,10951,10953,10956],{"class":68,"line":1405},[66,10952,10474],{"class":72},[66,10954,10955],{"class":76}," sqlite3",[66,10957,10958],{"class":76}," {051b93a0-d9a9-4778-ac73-81ee01a3905d}.db\n",[17,10960,10961],{},"Nous allons maintenant faire une requête dans la base de données sqlite :",[56,10963,10967],{"className":10964,"code":10965,"language":10966,"meta":61,"style":61},"language-sql shiki shiki-themes one-dark-pro","$ .TABLES\ndistances  files\n$ SELECT files1.path, files2.path, distances.distance FROM distances, files files1, files files2 WHERE distances.id1=files1.id AND distances.id2=files2.id ORDER BY distance ASC;\n","sql",[63,10968,10969,10974,10979],{"__ignoreMap":61},[66,10970,10971],{"class":68,"line":69},[66,10972,10973],{"class":230},"$ .TABLES\n",[66,10975,10976],{"class":68,"line":80},[66,10977,10978],{"class":230},"distances  files\n",[66,10980,10981,10984,10987,10990,10992,10995,10997,11000,11002,11004,11006,11009,11011,11014,11017,11020,11023,11026,11028,11031,11033,11036,11038,11041,11044,11046,11048,11051,11053,11055,11057,11059,11062,11065,11068],{"class":68,"line":89},[66,10982,10983],{"class":230},"$ ",[66,10985,10986],{"class":223},"SELECT",[66,10988,10989],{"class":114}," files1",[66,10991,44],{"class":230},[66,10993,10994],{"class":114},"path",[66,10996,251],{"class":230},[66,10998,10999],{"class":114},"files2",[66,11001,44],{"class":230},[66,11003,10994],{"class":114},[66,11005,251],{"class":230},[66,11007,11008],{"class":114},"distances",[66,11010,44],{"class":230},[66,11012,11013],{"class":114},"distance",[66,11015,11016],{"class":223}," FROM",[66,11018,11019],{"class":230}," distances, files files1, files files2 ",[66,11021,11022],{"class":223},"WHERE",[66,11024,11025],{"class":114}," distances",[66,11027,44],{"class":230},[66,11029,11030],{"class":114},"id1",[66,11032,378],{"class":83},[66,11034,11035],{"class":114},"files1",[66,11037,44],{"class":230},[66,11039,11040],{"class":114},"id",[66,11042,11043],{"class":223}," AND",[66,11045,11025],{"class":114},[66,11047,44],{"class":230},[66,11049,11050],{"class":114},"id2",[66,11052,378],{"class":83},[66,11054,10999],{"class":114},[66,11056,44],{"class":230},[66,11058,11040],{"class":114},[66,11060,11061],{"class":223}," ORDER BY",[66,11063,11064],{"class":230}," distance ",[66,11066,11067],{"class":223},"ASC",[66,11069,1952],{"class":230},[8428,11071,11072,11085],{},[8431,11073,11074],{},[8434,11075,11076,11079,11082],{},[8437,11077,11078],{},"Version 1",[8437,11080,11081],{},"Version 2",[8437,11083,11084],{},"Distance",[8443,11086,11087,11098,11109,11119,11128,11139,11149,11159,11170,11180,11189,11198,11207,11216,11226,11235,11244,11254,11263,11272,11281,11290,11299,11308,11317,11326,11335,11344,11353,11362,11371,11380,11389,11398,11407,11416,11425,11434,11443,11452,11461,11470,11479,11488,11497,11506,11515,11524,11533,11542,11551,11560,11569,11578,11587,11596,11605,11614,11623,11632,11641,11650,11659,11668,11677,11686,11695,11704,11713,11722,11731,11740,11749,11758,11767,11776,11785,11794,11803,11812,11821,11830,11839,11848,11857,11866,11875,11884,11893,11902,11911],{},[8434,11088,11089,11092,11095],{},[8448,11090,11091],{},"v0.8.1",[8448,11093,11094],{},"v0.8.1_services",[8448,11096,11097],{},"0.0350740694634633",[8434,11099,11100,11103,11106],{},[8448,11101,11102],{},"v0.6.8",[8448,11104,11105],{},"v0.6.9",[8448,11107,11108],{},"0.132275346477201",[8434,11110,11111,11114,11116],{},[8448,11112,11113],{},"v0.8.0",[8448,11115,11091],{},[8448,11117,11118],{},"0.142321125298336",[8434,11120,11121,11123,11125],{},[8448,11122,11113],{},[8448,11124,11094],{},[8448,11126,11127],{},"0.161719318637048",[8434,11129,11130,11133,11136],{},[8448,11131,11132],{},"v0.6.5",[8448,11134,11135],{},"v0.6.6",[8448,11137,11138],{},"0.196933113059686",[8434,11140,11141,11144,11146],{},[8448,11142,11143],{},"v0.6.4",[8448,11145,11132],{},[8448,11147,11148],{},"0.231812199675573",[8434,11150,11151,11153,11156],{},[8448,11152,11135],{},[8448,11154,11155],{},"v0.6.7",[8448,11157,11158],{},"0.266593999923953",[8434,11160,11161,11164,11167],{},[8448,11162,11163],{},"v0.6.10",[8448,11165,11166],{},"v0.7.0",[8448,11168,11169],{},"0.27412838729727",[8434,11171,11172,11175,11177],{},[8448,11173,11174],{},"v0.7.2",[8448,11176,11113],{},[8448,11178,11179],{},"0.312111739912996",[8434,11181,11182,11184,11186],{},[8448,11183,11132],{},[8448,11185,11155],{},[8448,11187,11188],{},"0.351347925829225",[8434,11190,11191,11193,11195],{},[8448,11192,11143],{},[8448,11194,11135],{},[8448,11196,11197],{},"0.364115163581424",[8434,11199,11200,11202,11204],{},[8448,11201,11174],{},[8448,11203,11091],{},[8448,11205,11206],{},"0.386971922637303",[8434,11208,11209,11211,11213],{},[8448,11210,11174],{},[8448,11212,11094],{},[8448,11214,11215],{},"0.401055941017259",[8434,11217,11218,11221,11223],{},[8448,11219,11220],{},"v0.7.1",[8448,11222,11174],{},[8448,11224,11225],{},"0.436705836223058",[8434,11227,11228,11230,11232],{},[8448,11229,11166],{},[8448,11231,11220],{},[8448,11233,11234],{},"0.465121645779551",[8434,11236,11237,11239,11241],{},[8448,11238,11143],{},[8448,11240,11155],{},[8448,11242,11243],{},"0.468472350726879",[8434,11245,11246,11248,11251],{},[8448,11247,11094],{},[8448,11249,11250],{},"v0.9.0",[8448,11252,11253],{},"0.516795574578859",[8434,11255,11256,11258,11260],{},[8448,11257,11091],{},[8448,11259,11250],{},[8448,11261,11262],{},"0.51733623689019",[8434,11264,11265,11267,11269],{},[8448,11266,11113],{},[8448,11268,11250],{},[8448,11270,11271],{},"0.544376861655528",[8434,11273,11274,11276,11278],{},[8448,11275,11155],{},[8448,11277,11102],{},[8448,11279,11280],{},"0.558824765667689",[8434,11282,11283,11285,11287],{},[8448,11284,11220],{},[8448,11286,11113],{},[8448,11288,11289],{},"0.560609480175814",[8434,11291,11292,11294,11296],{},[8448,11293,11163],{},[8448,11295,11105],{},[8448,11297,11298],{},"0.594036969567445",[8434,11300,11301,11303,11305],{},[8448,11302,11220],{},[8448,11304,11091],{},[8448,11306,11307],{},"0.604226316444666",[8434,11309,11310,11312,11314],{},[8448,11311,11220],{},[8448,11313,11094],{},[8448,11315,11316],{},"0.613613062086946",[8434,11318,11319,11321,11323],{},[8448,11320,11155],{},[8448,11322,11105],{},[8448,11324,11325],{},"0.622950487834501",[8434,11327,11328,11330,11332],{},[8448,11329,11166],{},[8448,11331,11174],{},[8448,11333,11334],{},"0.631060763867616",[8434,11336,11337,11339,11341],{},[8448,11338,11163],{},[8448,11340,11220],{},[8448,11342,11343],{},"0.632444883185258",[8434,11345,11346,11348,11350],{},[8448,11347,11163],{},[8448,11349,11102],{},[8448,11351,11352],{},"0.637234847328374",[8434,11354,11355,11357,11359],{},[8448,11356,11135],{},[8448,11358,11102],{},[8448,11360,11361],{},"0.6494052372746",[8434,11363,11364,11366,11368],{},[8448,11365,11105],{},[8448,11367,11220],{},[8448,11369,11370],{},"0.666200571812458",[8434,11372,11373,11375,11377],{},[8448,11374,11174],{},[8448,11376,11250],{},[8448,11378,11379],{},"0.678423568871868",[8434,11381,11382,11384,11386],{},[8448,11383,11132],{},[8448,11385,11102],{},[8448,11387,11388],{},"0.692250570944195",[8434,11390,11391,11393,11395],{},[8448,11392,11102],{},[8448,11394,11220],{},[8448,11396,11397],{},"0.701063946130892",[8434,11399,11400,11402,11404],{},[8448,11401,11135],{},[8448,11403,11105],{},[8448,11405,11406],{},"0.701698986545754",[8434,11408,11409,11411,11413],{},[8448,11410,11105],{},[8448,11412,11166],{},[8448,11414,11415],{},"0.717262408423359",[8434,11417,11418,11420,11422],{},[8448,11419,11166],{},[8448,11421,11113],{},[8448,11423,11424],{},"0.720311680104721",[8434,11426,11427,11429,11431],{},[8448,11428,11132],{},[8448,11430,11105],{},[8448,11432,11433],{},"0.738013305804084",[8434,11435,11436,11438,11440],{},[8448,11437,11143],{},[8448,11439,11102],{},[8448,11441,11442],{},"0.747495551539097",[8434,11444,11445,11447,11449],{},[8448,11446,11163],{},[8448,11448,11174],{},[8448,11450,11451],{},"0.747929200720491",[8434,11453,11454,11456,11458],{},[8448,11455,11102],{},[8448,11457,11166],{},[8448,11459,11460],{},"0.748031544518325",[8434,11462,11463,11465,11467],{},[8448,11464,11166],{},[8448,11466,11091],{},[8448,11468,11469],{},"0.758510349354368",[8434,11471,11472,11474,11476],{},[8448,11473,11166],{},[8448,11475,11094],{},[8448,11477,11478],{},"0.767204482779187",[8434,11480,11481,11483,11485],{},[8448,11482,11143],{},[8448,11484,11105],{},[8448,11486,11487],{},"0.772451857549627",[8434,11489,11490,11492,11494],{},[8448,11491,11163],{},[8448,11493,11113],{},[8448,11495,11496],{},"0.796649043913944",[8434,11498,11499,11501,11503],{},[8448,11500,11220],{},[8448,11502,11250],{},[8448,11504,11505],{},"0.801221496333008",[8434,11507,11508,11510,11512],{},[8448,11509,11105],{},[8448,11511,11174],{},[8448,11513,11514],{},"0.804765901655414",[8434,11516,11517,11519,11521],{},[8448,11518,11102],{},[8448,11520,11174],{},[8448,11522,11523],{},"0.819917045496318",[8434,11525,11526,11528,11530],{},[8448,11527,11163],{},[8448,11529,11091],{},[8448,11531,11532],{},"0.823540395867048",[8434,11534,11535,11537,11539],{},[8448,11536,11163],{},[8448,11538,11094],{},[8448,11540,11541],{},"0.831055117394626",[8434,11543,11544,11546,11548],{},[8448,11545,11163],{},[8448,11547,11155],{},[8448,11549,11550],{},"0.838850951377793",[8434,11552,11553,11555,11557],{},[8448,11554,11105],{},[8448,11556,11113],{},[8448,11558,11559],{},"0.849001032539087",[8434,11561,11562,11564,11566],{},[8448,11563,11155],{},[8448,11565,11220],{},[8448,11567,11568],{},"0.853848016623182",[8434,11570,11571,11573,11575],{},[8448,11572,11166],{},[8448,11574,11250],{},[8448,11576,11577],{},"0.860291356912217",[8434,11579,11580,11582,11584],{},[8448,11581,11102],{},[8448,11583,11113],{},[8448,11585,11586],{},"0.86075956509228",[8434,11588,11589,11591,11593],{},[8448,11590,11163],{},[8448,11592,11135],{},[8448,11594,11595],{},"0.863340151908353",[8434,11597,11598,11600,11602],{},[8448,11599,11105],{},[8448,11601,11091],{},[8448,11603,11604],{},"0.872265541006983",[8434,11606,11607,11609,11611],{},[8448,11608,11135],{},[8448,11610,11220],{},[8448,11612,11613],{},"0.873275579233521",[8434,11615,11616,11618,11620],{},[8448,11617,11163],{},[8448,11619,11132],{},[8448,11621,11622],{},"0.875332023895544",[8434,11624,11625,11627,11629],{},[8448,11626,11105],{},[8448,11628,11094],{},[8448,11630,11631],{},"0.87987037883801",[8434,11633,11634,11636,11638],{},[8448,11635,11155],{},[8448,11637,11166],{},[8448,11639,11640],{},"0.879941907871053",[8434,11642,11643,11645,11647],{},[8448,11644,11102],{},[8448,11646,11091],{},[8448,11648,11649],{},"0.881174812987336",[8434,11651,11652,11654,11656],{},[8448,11653,11132],{},[8448,11655,11220],{},[8448,11657,11658],{},"0.886172606121206",[8434,11660,11661,11663,11665],{},[8448,11662,11102],{},[8448,11664,11094],{},[8448,11666,11667],{},"0.889515283880001",[8434,11669,11670,11672,11674],{},[8448,11671,11163],{},[8448,11673,11143],{},[8448,11675,11676],{},"0.892364892140999",[8434,11678,11679,11681,11683],{},[8448,11680,11135],{},[8448,11682,11166],{},[8448,11684,11685],{},"0.894375709613201",[8434,11687,11688,11690,11692],{},[8448,11689,11163],{},[8448,11691,11250],{},[8448,11693,11694],{},"0.895694726039398",[8434,11696,11697,11699,11701],{},[8448,11698,11155],{},[8448,11700,11174],{},[8448,11702,11703],{},"0.898582911617307",[8434,11705,11706,11708,11710],{},[8448,11707,11143],{},[8448,11709,11220],{},[8448,11711,11712],{},"0.902038058337369",[8434,11714,11715,11717,11719],{},[8448,11716,11132],{},[8448,11718,11166],{},[8448,11720,11721],{},"0.904821831317442",[8434,11723,11724,11726,11728],{},[8448,11725,11135],{},[8448,11727,11174],{},[8448,11729,11730],{},"0.910637046476578",[8434,11732,11733,11735,11737],{},[8448,11734,11143],{},[8448,11736,11166],{},[8448,11738,11739],{},"0.918347943544789",[8434,11741,11742,11744,11746],{},[8448,11743,11132],{},[8448,11745,11174],{},[8448,11747,11748],{},"0.919716704855963",[8434,11750,11751,11753,11755],{},[8448,11752,11105],{},[8448,11754,11250],{},[8448,11756,11757],{},"0.921714099772221",[8434,11759,11760,11762,11764],{},[8448,11761,11155],{},[8448,11763,11113],{},[8448,11765,11766],{},"0.924717744438112",[8434,11768,11769,11771,11773],{},[8448,11770,11102],{},[8448,11772,11250],{},[8448,11774,11775],{},"0.925849165227404",[8434,11777,11778,11780,11782],{},[8448,11779,11143],{},[8448,11781,11174],{},[8448,11783,11784],{},"0.928888262611658",[8434,11786,11787,11789,11791],{},[8448,11788,11155],{},[8448,11790,11091],{},[8448,11792,11793],{},"0.933685479216414",[8434,11795,11796,11798,11800],{},[8448,11797,11135],{},[8448,11799,11113],{},[8448,11801,11802],{},"0.933940067594635",[8434,11804,11805,11807,11809],{},[8448,11806,11155],{},[8448,11808,11094],{},[8448,11810,11811],{},"0.939898268404416",[8434,11813,11814,11816,11818],{},[8448,11815,11132],{},[8448,11817,11113],{},[8448,11819,11820],{},"0.940789807767177",[8434,11822,11823,11825,11827],{},[8448,11824,11135],{},[8448,11826,11091],{},[8448,11828,11829],{},"0.94210246370087",[8434,11831,11832,11834,11836],{},[8448,11833,11135],{},[8448,11835,11094],{},[8448,11837,11838],{},"0.946464528845253",[8434,11840,11841,11843,11845],{},[8448,11842,11143],{},[8448,11844,11113],{},[8448,11846,11847],{},"0.948830071149278",[8434,11849,11850,11852,11854],{},[8448,11851,11132],{},[8448,11853,11091],{},[8448,11855,11856],{},"0.94922082772201",[8434,11858,11859,11861,11863],{},[8448,11860,11132],{},[8448,11862,11094],{},[8448,11864,11865],{},"0.951278461132112",[8434,11867,11868,11870,11872],{},[8448,11869,11143],{},[8448,11871,11091],{},[8448,11873,11874],{},"0.955572468114482",[8434,11876,11877,11879,11881],{},[8448,11878,11143],{},[8448,11880,11094],{},[8448,11882,11883],{},"0.95567206186826",[8434,11885,11886,11888,11890],{},[8448,11887,11155],{},[8448,11889,11250],{},[8448,11891,11892],{},"0.96084453455483",[8434,11894,11895,11897,11899],{},[8448,11896,11135],{},[8448,11898,11250],{},[8448,11900,11901],{},"0.964619158469125",[8434,11903,11904,11906,11908],{},[8448,11905,11132],{},[8448,11907,11250],{},[8448,11909,11910],{},"0.965955795849916",[8434,11912,11913,11915,11917],{},[8448,11914,11143],{},[8448,11916,11250],{},[8448,11918,11919],{},"0.968866861905835",[17,11921,11922],{},"On peut ainsi voir d'après ce tableau, les versions ayant peu de\ndifférences et celles qui ont fait des plus gros bonds en avant.",[17,11924,11925],{},"On voit ainsi qu'il y a plus de différences entre la version 0.8.0 et la\n0.9.0, qu'il y en a eu entre la version 0.6.8 et la 0.6.9. On peut\négalement voir que les versions 0.6.4 et 0.9.0 n'ont plus rien à voir\nentre elles.",[17,11927,11928,11929,44],{},"Vous pouvez télécharger le programme attaché à ",[39,11930,11932],{"href":11931},"\u002FProgrammation\u002Fcalcul-de-la-distance\u002Fcalcul_distance.7z","ce lien",[3349,11934,11936,11939],{"className":11935,"dataFootnotes":61},[3352],[1432,11937,3357],{"className":11938,"id":1613},[3356],[3359,11940,11941],{},[165,11942,11943,11944,5538,11948],{"id":3363},"On peut retrouver l'explication de cette formule ",[39,11945,3437],{"href":11946,"rel":11947},"http:\u002F\u002Finterstices.info\u002Fjcms\u002Fc_21828\u002Fclasser-musiques-langues-images-textes-et-genomes",[43],[39,11949,3371],{"href":3367,"ariaLabel":3368,"className":11950,"dataFootnoteBackref":61},[3370],[1545,11952,11953],{},"html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}",{"title":61,"searchDepth":80,"depth":80,"links":11955},[11956,11957,11958,11959],{"id":3513,"depth":89,"text":3514},{"id":10277,"depth":89,"text":10278},{"id":10447,"depth":89,"text":10448},{"id":1613,"depth":80,"text":3357},"2010-06-06",{"type":9,"value":11962},[11963,11965,11970,11975,11982,11994],[12,11964,3514],{"id":3513},[17,11966,4290,11967,10329],{},[39,11968,10328],{"href":10326,"rel":11969},[43],[56,11971,11973],{"className":11972,"code":10333,"language":840},[838],[63,11974,10333],{"__ignoreMap":61},[17,11976,10338,11977,44],{},[1607,11978,11979],{},[39,11980,461],{"href":1611,"ariaDescribedBy":11981,"dataFootnoteRef":61,"id":1614},[1613],[17,11983,10346,11984,251,11986,3581,11988,10356,11990,10359,11992,10363],{},[63,11985,10349],{},[63,11987,10352],{},[63,11989,10355],{},[63,11991,10355],{},[32,11993,10362],{},[1545,11995,11953],{},{},"\u002Fpost\u002Fcalcul-de-la-distance",{"title":10317,"description":61},"calcul-de-la-distance","posts\u002FProgrammation\u002F2010-06-06-calcul-de-la-distance",[1592,9080],"f5dJI_rOrb9a2Kflve8ejZKhwpF_zkBfNrrcWae0dOg",{"id":12004,"title":12005,"author":7,"body":12006,"category":4311,"categorySlug":5899,"date":12641,"description":12642,"excerpt":12643,"extension":1584,"location":1585,"meta":12671,"navigation":275,"path":12672,"published":275,"seo":12673,"slug":12674,"stem":12675,"tags":12676,"timeToRead":340,"__hash__":12677},"posts\u002Fposts\u002FXINX\u002F2010-05-02-presentation-de-xinx.md","Présentation de XINX",{"type":9,"value":12007,"toc":12628},[12008,12028,12034,12043,12048,12052,12068,12071,12096,12099,12107,12113,12119,12128,12131,12144,12147,12151,12159,12171,12173,12179,12184,12204,12215,12218,12235,12239,12269,12285,12289,12306,12312,12316,12323,12326,12383,12387,12391,12394,12397,12403,12407,12413,12423,12458,12478,12483,12487,12497,12500,12506,12510,12513,12524,12528,12536,12541,12547,12549,12560,12566,12572,12575,12591,12599,12625],[17,12009,12010,12011,12013,12014,12016,12017,12020,12021,3581,12024,12027],{},"Ce billet fait suite à la sortie de la version 0.9.0 de ",[1534,12012,4311],{}," et va\nvous décrire ce logiciel. ",[1534,12015,4311],{}," est éditeur de feuille de style ",[32,12018,12019],{},"XSL","\n(il fait également éditeur ",[32,12022,12023],{},"JavaScript",[32,12025,12026],{},"CSS"," mais actuellement moins\nbien que ce que peuvent faire d'autres).",[17,12029,12030,12031,44],{},"Il permet l'édition des feuilles de styles en proposant de compléter sur\nle nom des balises (normal), sur les attributs (normal), sur les valeurs\nd'attributs : les variables, les paramètres, ... Il propose également\nautomatiquement les différents paramètres lors de l'utilisation d'un\n",[63,12032,12033],{},"call:template",[17,12035,12036,12037,12039,12040,44],{},"L'éditeur est fortement tourné vers l'édition de feuille de style ",[32,12038,12019],{},"\npour génération d*'HTML* mais peut être utilisé pour générer du ",[32,12041,12042],{},"XML",[17,12044,12045],{},[1445,12046],{"alt":4311,"src":12047},"\u002FXINX\u002Fpresentation-de-xinx\u002Fsplash.png",[12,12049,12051],{"id":12050},"historique","Historique",[17,12053,12054,12055,12058,12059,12064,12065,44],{},"Depuis un certain temps déjà (5 ans), je travaille pour la société\n",[32,12056,12057],{},"Generix Group"," éditant et intégrant un ERP",[1607,12060,12061],{},[39,12062,461],{"href":1611,"ariaDescribedBy":12063,"dataFootnoteRef":61,"id":1614},[1613]," du nom de ",[32,12066,12067],{},"GCE",[17,12069,12070],{},"Sur la partie Web de cet ERP, il est possible d'intervenir à plusieurs\nendroits pour modifier son fonctionnement :",[162,12072,12073,12080,12090],{},[165,12074,12075,12076,12079],{},"Le paramétrage (",[32,12077,12078],{},"BDD",") : Modification d'un paramètre pour agir sur\nle comportement du logiciel",[165,12081,12082,12083,12086,12087,12089],{},"La couche métier (",[32,12084,12085],{},"JAVA",") : Lit le paramétrage (",[32,12088,12078],{},") et réalise\nles traitements. Il est possible de développer de nouveaux objets,\nmais aussi de dériver ceux existants.",[165,12091,12092,12093,12095],{},"La couche de présentation (",[32,12094,12019],{},") : A l'aide d'un flux de\nprésentation généré par la couche métier et d'un fichier de\nconfiguration, présente les données à l'écran.",[17,12097,12098],{},"La dernière couche est donc l'interprétation d'un flux de donnée,\ngénérée à partir de la couche métier (JAVA), à l'aide de feuille de\nstyle XSL.",[17,12100,12101,12103,12104,12106],{},[1534,12102,4311],{}," sert à modifier la couche de présentation (",[32,12105,12019],{},"). Sur cette\ndernière couche, on crée et modifie des feuilles de styles pour modifier\nla présentation des données à l'écran (Déplacer des champs, supprimer\ndes champs, ajouter des champs, règle de gestion simple ...).",[17,12108,12109,12110,12112],{},"En mode ",[32,12111,4352],{},", chez les clients, les modifications ne sont pas faites\ndirectement sur les feuilles de styles standard livrées, mais sur des\nfeuilles de styles dérivées, afin de faciliter les migrations, et la\ncorrection des anomalies.",[17,12114,12115],{},[1445,12116],{"alt":12117,"src":12118},"Structure","\u002FXINX\u002Fpresentation-de-xinx\u002Fstructure_dossier.png",[17,12120,12121,12122,12125,12126,44],{},"Lors de la modification de feuille de style ",[32,12123,12124],{},"standard",", il faut alors\nrenommer et placer ce fichier dans un dossier séparé. C'est de cette\ntâche récurrente qu'est venue la création de l'éditeur de feuille de\nstyle ",[1534,12127,4311],{},[17,12129,12130],{},"Le but était alors, lors de la sauvegarde d'un fichier standard, de\nproposer automatiquement la sauvegarde dans le bon dossier.",[17,12132,12133,12134,12136,12137,12139,12140,12143],{},"L'autre point à l'origine de la création de ",[1534,12135,4311],{}," est la\nnon-existence d'un logiciel de développement de feuille de style ",[32,12138,12019],{},"\ngratuit et\u002Fou libre (Il y a bien ",[32,12141,12142],{},"XML Spy"," qui correspondait à peu prés\nmais qui était payant, et dont nous n'avions pas la licence).",[17,12145,12146],{},"Sont alors venu s'ajouter d'autres fonctionnalités : la complétion sur\nles balises, les attributs, les variables, .... :)",[12,12148,12150],{"id":12149},"quest-que-xinx-aujourdhui","Qu'est que XINX aujourd'hui ?",[17,12152,12153,12155,12156,12158],{},[1534,12154,4311],{}," prévu initialement comme aide au développement des consultants\nqui font des développements de feuille de style, est maintenant un\néditeur de feuille de style ",[32,12157,12019],{}," avec gestion des plugins. L'un des\nplugins contient des petites fonctionnalités utiles au quotidien par les\nconsultants travaillants sur l'ERP, fonctionnalité auparavant implémenté\ndirectement dans le logiciel.",[17,12160,12161,12162,12164,12165,12167,12168,12170],{},"Dit autrement, cette nouvelle version marque donc une étape : La partie\nde ",[1534,12163,4311],{}," propre à ",[32,12166,12057],{}," à été séparée dans un plugin.\n",[1534,12169,4311],{}," en lui même n'est alors plus qu'un éditeur de feuille de style,\nextensible via des plugins, mais il retrouve les mêmes fonctionnalités\ngrâce à ce plugin.",[12,12172,3704],{"id":3703},[17,12174,12175],{},[1445,12176],{"alt":12177,"src":12178},"Licence GPLv3","http:\u002F\u002Fwww.gnu.org\u002Fgraphics\u002Fgplv3-127x51.png",[17,12180,12181,12183],{},[1534,12182,4311],{}," est un logiciel libre dont la licence choisie est la GPLv3. Ce\nqui signifie que vous pouvez :",[162,12185,12186,12189,12192,12195,12198,12201],{},[165,12187,12188],{},"télécharger le logiciel",[165,12190,12191],{},"utiliser le logiciel pour faire ce que vous voulez",[165,12193,12194],{},"télécharger les sources du logiciels",[165,12196,12197],{},"modifier les sources du logiciels",[165,12199,12200],{},"utiliser le logiciel modifié par vos soins",[165,12202,12203],{},"distribuer le logiciel ou la version modifiée (attention à\ndifférencier les parties originales du logiciel avec le bon\ncopyright, et les parties modifiées).",[17,12205,12206,12207,12209,12210,12214],{},"En tant que logiciel libre ",[1534,12208,4311],{}," possède une plateforme de\ncontribution (ticket, wiki, source, ...) qui se trouve à l'adresse\n",[39,12211,12212],{"href":12212,"rel":12213},"http:\u002F\u002Fxinx.shadoware.org",[43],". Vous pouvez donc y aller pour contribuer.",[17,12216,12217],{},"Vous pouvez contribuer de plusieurs façons :",[162,12219,12220,12223,12229,12232],{},[165,12221,12222],{},"Développement d'un Plugin",[165,12224,12225,12226],{},"Développement d'un script ",[32,12227,12228],{},"ECMAScript",[165,12230,12231],{},"Développement d'un petit patch",[165,12233,12234],{},"Développement d'un gros patch",[12,12236,12238],{"id":12237},"technologie","Technologie",[17,12240,12241,12243,12244,12246,12247,12250,12251,12253,12254,12257,12258,12261,12262,3581,12265,12268],{},[1534,12242,4311],{}," est un logiciel développé en ",[32,12245,3803],{},". Il compile et tourne sous\n",[32,12248,12249],{},"Gnu\u002FDebian"," (normalement n'importe quelle distribution devrait faire\nl'affaire, mais ",[32,12252,12249],{}," est la seule distribution testée), et sous\n",[32,12255,12256],{},"MS\u002FWindows",". Il devrait normalement également tourner sous ",[32,12259,12260],{},"MacOS"," (si\nles dépendances comme les librairies ",[32,12263,12264],{},"libxml2",[32,12266,12267],{},"libxslt"," sont\ncompilables sous cet OS).",[17,12270,12271,12272,12274,12275,12278,12279,12281,12282,12284],{},"A chaque version un paquet ",[32,12273,12249],{}," est mis à disposition sur le\ndépôt (",[63,12276,12277],{},"apt.shadoware.org",") et un binaire ",[32,12280,12256],{}," est proposé en\ntéléchargement. ",[1534,12283,4311],{}," est toujours compilable à partir des sources\npour les autres distributions ou juste parce que vous préférez ainsi. 😄",[12,12286,12288],{"id":12287},"intégration-continue-tests","Intégration continue & Tests",[17,12290,12291,12292,12295,12296,12299,12300,12305],{},"A chaque ",[32,12293,12294],{},"validation"," sur le référenciel ",[32,12297,12298],{},"SubVersion",", l'application est\ncompilée et testée (vous pouvez voir le résultat des tests à l'adresse\n",[39,12301,12304],{"href":12302,"rel":12303},"http:\u002F\u002Fxinx.shadoware.org\u002Fbuild",[43],"suivante",". A la sortie de la version 0.9.0, les tests couvrent 27% de\nla librairie principale. Je dois donc encore écrire d'autres jeux de\ntests.",[17,12307,12308],{},[1445,12309],{"alt":12310,"src":12311},"Intégration","\u002FXINX\u002Fpresentation-de-xinx\u002Fbitten.png",[12,12313,12315],{"id":12314},"code-réutilisable-pour-dautres-projets","Code réutilisable pour d'autres projets",[17,12317,12318,12320,12321,44],{},[1534,12319,4311],{}," peut également être intéressant pour d'autres développeurs\n",[32,12322,3803],{},[17,12324,12325],{},"En effet, vous pouvez trouver dans la dernière version, ainsi que dans\nles versions précédentes plusieurs classes utilitaires.Par exemple\n(liste presque non exhaustive) :",[162,12327,12328,12336,12344,12352,12360,12375],{},[165,12329,12330,12335],{},[39,12331,12334],{"href":12332,"rel":12333},"http:\u002F\u002Fxinx.shadoware.org\u002Fdoxygen\u002Fdevel\u002Fhtml\u002FclassTreeProxyItemModel.html",[43],"TreeProxyItemModel"," : convertit un modèle format table en modèle\nformat arbre. Utile lorsque l'arbre est représenté dans une base de\ndonnée relationnelle par exemple.",[165,12337,12338,12343],{},[39,12339,12342],{"href":12340,"rel":12341},"http:\u002F\u002Fxinx.shadoware.org\u002Fdoxygen\u002Fdevel\u002Fhtml\u002FclassRecursiveSortFilterProxyModel.html",[43],"RecursiveSortFilterProxyModel"," : Utilisé pour rechercher\nfacilement des données dans un arbre et permet d'afficher les\nenfants.",[165,12345,12346,12351],{},[39,12347,12350],{"href":12348,"rel":12349},"http:\u002F\u002Fxinx.shadoware.org\u002Fdoxygen\u002Fdevel\u002Fhtml\u002FclassXinxLineEdit.html",[43],"XinxLineEdit"," : Inspiré de KDE, affiche un bouton pour effacer le\ntexte dans la ligne d'édition",[165,12353,12354,12359],{},[39,12355,12358],{"href":12356,"rel":12357},"http:\u002F\u002Fxinx.shadoware.org\u002Fdoxygen\u002Fdevel\u002Fhtml\u002FclassXinxListWidgetImpl.html",[43],"XinxListWidgetImpl"," : Permet de modifier une liste de valeur\n(ajout, suppression, valeur par défaut, classement, ...)",[165,12361,12362,12367,12368,12371,12372,44],{},[39,12363,12366],{"href":12364,"rel":12365},"http:\u002F\u002Fxinx.shadoware.org\u002Fdoxygen\u002Fdevel\u002Fhtml\u002FclassPluginSelector.html",[43],"PluginSelector"," : Inspiré de KDE, permet d'afficher une liste des\nplugins, avec un bouton ",[32,12369,12370],{},"A propos de ..."," et un bouton ",[32,12373,12374],{},"Configurer\n...",[165,12376,12377,12382],{},[39,12378,12381],{"href":12379,"rel":12380},"http:\u002F\u002Fxinx.shadoware.org\u002Fdoxygen\u002Fdevel\u002Fhtml\u002FclassQMenuView.html",[43],"QMenuView"," : Inspiré d'un exemple de Qt et permet d'afficher un\nmenu à partir d'un modèle.",[12,12384,12386],{"id":12385},"fonctionnalités","Fonctionnalités",[4389,12388,12390],{"id":12389},"recherche-parmi-les-fichiers-dun-dossier","Recherche parmi les fichiers d'un dossier",[17,12392,12393],{},"Un dock sur le coté permet en mode projet de rechercher et d'ouvrir un\nfichier parmi une multitude de fichier d'un projet (utile pour les\nfichiers avec beaucoup de feuille de style).",[17,12395,12396],{},"La recherche peut se faire avec des Jockers (*)",[17,12398,12399],{},[1445,12400],{"alt":12401,"src":12402},"Dock","\u002FXINX\u002Fpresentation-de-xinx\u002Fdockprojet.png",[4389,12404,12406],{"id":12405},"la-complétion-xsl","La complétion XSL",[17,12408,12409],{},[1445,12410],{"alt":12411,"src":12412},"Completion","\u002FXINX\u002Fpresentation-de-xinx\u002Fcompletion.png",[17,12414,12415,12417,12418,4405],{},[1534,12416,4311],{}," permet de compléter sur les feuilles de styles à plusieurs\nniveaux",[1607,12419,12420],{},[39,12421,476],{"href":1637,"ariaDescribedBy":12422,"dataFootnoteRef":61,"id":1639},[1613],[162,12424,12425,12431,12437],{},[165,12426,12427,12428,12430],{},"la balise (fonctionnalité standard vous allez me dire) : ",[1534,12429,4311],{},"\npermet de compléter sur les balises xsl:, les balises html ...",[165,12432,12433,12434,12436],{},"les attributs (encore standard). Pour chaque balise, ",[1534,12435,4311],{}," est\ncapable de compléter sur les attributs de la balise saisie.",[165,12438,12439,12440,12442,12443,12445,12446,251,12448,12450,12451,12454,12455,12457],{},"les valeurs d'attribut (là c'est intéressant). Permet de compléter\nsur les variables déclarées dans le fichier ",[32,12441,12019],{},", ainsi que dans\nles fichiers importés (pour retrouver les fichiers importés,\n",[1534,12444,4311],{},", utilise le mode projet et les paramètres qui y sont\ndéfinits). De plus sur les attributs non ",[32,12447,12019],{},[1534,12449,4311],{}," ajoute\nautomatiquement les accolades ",[63,12452,12453],{},"{ }"," et les ",[63,12456,10474],{}," pour les variables\net les paramètres.",[17,12459,12460,12461,12463,12464,12467,12468,12471,12472,5538,12475,12477],{},"De plus lors de l'utilisation de la balise call:template, ",[1534,12462,4311],{}," va\nchercher automatiquement les paramètres (",[63,12465,12466],{},"xsl:param",") du template donné,\net les ajoute automatiquement en ",[63,12469,12470],{},"xsl:with-param",".Pour les balises\n",[63,12473,12474],{},"xsl:apply-templates",[1534,12476,4311],{}," propose la liste des modes des templates\nexistants.",[17,12479,12480],{},[1445,12481],{"alt":12411,"src":12482},"\u002FXINX\u002Fpresentation-de-xinx\u002Fcompletion2.png",[4389,12484,12486],{"id":12485},"le-parsing-de-la-feuille-de-style","Le parsing de la feuille de style",[17,12488,12489,12490,12492,12493,12496],{},"Fonctionnalité du moment, si vous indiquez un flux de données et une\nfeuille de style, ",[1534,12491,4311],{}," est capable d'afficher le résultat (la source\n",[32,12494,12495],{},"HTML"," et le résultat dans un navigateur Webkit)",[17,12498,12499],{},"Si l'emplacement où doivent s'exécuter les pages est définit alors, les\nfeuilles de styles, les images, ... pourront être affichées.",[17,12501,12502],{},[1445,12503],{"alt":12504,"src":12505},"Représentation","\u002FXINX\u002Fpresentation-de-xinx\u002Frepresentation_html.png",[12,12507,12509],{"id":12508},"a-venir","A venir",[17,12511,12512],{},"Bien que l'avenir du logiciel dépend de ces utilisateurs, voici les\nnouvelles fonctionnalités que devrait apporter la prochaine version :",[162,12514,12515,12518,12521],{},[165,12516,12517],{},"Déverminage de feuille de style XSL",[165,12519,12520],{},"Amélioration du parseur JavaScript et CSS",[165,12522,12523],{},"Quelques réécritures (Vue projet, ...)",[12,12525,12527],{"id":12526},"le-plugin-gce","Le plugin GCE",[17,12529,12530,12531,12533,12534,44],{},"Comme indiqué ci-dessous, il existe un plugin ",[32,12532,12067],{}," utilisé par les\nconsultants travaillants sur l'ERP ",[32,12535,12067],{},[17,12537,12538,12539,44],{},"Ce plugin permet de dupliquer une feuille de style d'un dossier à un\nautre (sans modification des fichiers standards), de lire les\ndictionnaires de libellé de l'ERP GCE, la lecture du fichier de\nconfiguration du lecteur ",[32,12540,12067],{},[17,12542,12543],{},[1445,12544],{"alt":12545,"src":12546},"Dérivation","\u002FXINX\u002Fpresentation-de-xinx\u002Fderivation.png",[12,12548,3716],{"id":3715},[17,12550,12551,12552,12554,12555,12559],{},"Vous pouvez télécharger ",[1534,12553,4311],{}," à l'adresse\n",[39,12556,12557],{"href":12557,"rel":12558},"http:\u002F\u002Fxinx.shadoware.org\u002Fdownloads",[43]," (source et version Windows).",[17,12561,12562,12563,12565],{},"Si vous voulez installer ",[1534,12564,4311],{}," sur une Gnu\u002FDebian (32 ou 64 bits)\nvous pouvez inclure le dépôt suivant :",[56,12567,12570],{"className":12568,"code":12569,"language":840},[838],"# Shadoware.Org\ndeb http:\u002F\u002Fapt.shadoware.org\u002F squeeze main\n",[63,12571,12569],{"__ignoreMap":61},[17,12573,12574],{},"Et installé de la façon suivante :",[56,12576,12578],{"className":58,"code":12577,"language":60,"meta":61,"style":61},"aptitude install xinx\n",[63,12579,12580],{"__ignoreMap":61},[66,12581,12582,12585,12588],{"class":68,"line":69},[66,12583,12584],{"class":72},"aptitude",[66,12586,12587],{"class":76}," install",[66,12589,12590],{"class":76}," xinx\n",[17,12592,12593,12594],{},"Vous pouvez vous tenir au courant des sorties de version grâce à la\n",[39,12595,12598],{"href":12596,"rel":12597},"http:\u002F\u002Flists.shadoware.org\u002Flistinfo\u002Fxinx",[43],"mailing list",[3349,12600,12602,12605],{"className":12601,"dataFootnotes":61},[3352],[1432,12603,3357],{"className":12604,"id":1613},[3356],[3359,12606,12607,12613],{},[165,12608,12609,12610],{"id":3363},"Un ERP et un logiciel de gestion d'entreprise. Un ERP permet de gérer, par exemple, les produits, les clients, les fournisseurs, les stocks, les ventes, les achats, la logistique, la comptabilité, .... Je ne vais pas vous faire une présentation des ERPs, car même si cela pourrait faire un billet intéressant, ce n'est pas le but ici. ",[39,12611,3371],{"href":3367,"ariaLabel":3368,"className":12612,"dataFootnoteBackref":61},[3370],[165,12614,12615,12616,12621,12622],{"id":3374},"Merci à ",[39,12617,12620],{"href":12618,"rel":12619},"http:\u002F\u002Fqcodeedit.edyuk.org\u002F",[43],"QCodeEdit"," qui me fournit quelques fonctionnalités utiles. ",[39,12623,3371],{"href":3378,"ariaLabel":3379,"className":12624,"dataFootnoteBackref":61},[3370],[1545,12626,12627],{},"html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":61,"searchDepth":80,"depth":80,"links":12629},[12630,12631,12632,12633,12634,12635,12636,12637,12638,12639,12640],{"id":12050,"depth":89,"text":12051},{"id":12149,"depth":89,"text":12150},{"id":3703,"depth":89,"text":3704},{"id":12237,"depth":89,"text":12238},{"id":12287,"depth":89,"text":12288},{"id":12314,"depth":89,"text":12315},{"id":12385,"depth":89,"text":12386},{"id":12508,"depth":89,"text":12509},{"id":12526,"depth":89,"text":12527},{"id":3715,"depth":89,"text":3716},{"id":1613,"depth":80,"text":3357},"2010-05-02","Ce billet fait suite à la sortie de la version 0.9.0 de XINX et va\nvous décrire ce logiciel. XINX est éditeur de feuille de style XSL\n(il fait également éditeur JavaScript et CSS mais actuellement moins\nbien que ce que peuvent faire d'autres).",{"type":9,"value":12644},[12645,12657,12661,12667],[17,12646,12010,12647,12013,12649,12016,12651,12020,12653,3581,12655,12027],{},[1534,12648,4311],{},[1534,12650,4311],{},[32,12652,12019],{},[32,12654,12023],{},[32,12656,12026],{},[17,12658,12030,12659,44],{},[63,12660,12033],{},[17,12662,12036,12663,12039,12665,44],{},[32,12664,12019],{},[32,12666,12042],{},[17,12668,12669],{},[1445,12670],{"alt":4311,"src":12047},{},"\u002Fpost\u002Fpresentation-de-xinx",{"title":12005,"description":12642},"presentation-de-xinx","posts\u002FXINX\u002F2010-05-02-presentation-de-xinx",[5899,5930,1592,5931],"wli16MFeBVMaJbc921USFquc6EZTDzFocvtCkto8yo8",{"id":12679,"title":12680,"author":7,"body":12681,"category":1560,"categorySlug":1561,"date":15171,"description":12685,"excerpt":15172,"extension":1584,"location":1585,"meta":15186,"navigation":275,"path":15187,"published":275,"seo":15188,"slug":15189,"stem":15190,"tags":15191,"timeToRead":416,"__hash__":15192},"posts\u002Fposts\u002FProgrammation\u002F2009-09-21-qt-transformation-d-une-vue-tableau-en-une-vue-hierarchique.md","Qt - Transformation d'une vue tableau en une vue hiérarchique",{"type":9,"value":12682,"toc":15164},[12683,12686,12692,12695,12701,12704,12710,12713,12721,12725,12728,12734,12737,12753,12768,12775,12779,12783,12794,12800,12803,12807,12810,13004,13011,13028,13048,13058,13062,13066,13069,13158,13165,13182,13185,13189,13192,13199,13202,13238,13245,13525,13533,13536,13539,13743,13746,13753,13756,13759,13762,13765,13841,13844,13904,13919,14004,14010,14082,14091,14097,14117,14120,14123,14129,14201,14204,14239,14242,14290,14293,14328,14334,14352,14367,14370,14386,14423,14426,14510,14520,14578,14581,14600,14609,14612,14615,14674,14684,14767,14773,14785,14788,14794,14825,14828,14891,14894,15007,15014,15022,15025,15028,15041,15045,15048,15082,15086,15089,15123,15127,15130,15144,15147,15161],[17,12684,12685],{},"Pour visualiser des données internes à l'écran, Nokia\u002FQt nous propose\nl'architecture MVC à l'aide des classes QAbstractItemModel et de ses\nsous classes (QAbstractListModel, QAbstractTableModel, ...). Le but de\nl'architecture MVC est de séparer la représentation mémoire des données,\nde l'affichage qu'elles auront.",[17,12687,12688],{},[1445,12689],{"alt":12690,"src":12691},"mvc1","\u002FProgrammation\u002Fqt-transformation-d-une-vue-tableau-en-une-vue-hierarchique\u002Fmvc1.png",[17,12693,12694],{},"Si les données sont par exemple issue d'une requête SQL, le modèle\nQSqlQueryModel permet de représenter la sélection SQL, à l'écran dans un\ncomposant QTableView. Ces données sont alors représentées sous forme\nd'un tableau deux dimensions.",[17,12696,12697],{},[1445,12698],{"alt":12699,"src":12700},"tableau","\u002FProgrammation\u002Fqt-transformation-d-une-vue-tableau-en-une-vue-hierarchique\u002Ftableau.png",[17,12702,12703],{},"Si l'on veut représenter les dossiers de l'ordinateur, le modèle\nQDirView permet d'afficher les données de façon hiérarchique.",[17,12705,12706],{},[1445,12707],{"alt":12708,"src":12709},"qdirview","\u002FProgrammation\u002Fqt-transformation-d-une-vue-tableau-en-une-vue-hierarchique\u002Fqdirview.png",[17,12711,12712],{},"Il est également possible d'écrire nos propres modèles pour représenter\nnos propres données.",[17,12714,12715,12716,44],{},"Le but de cet article est de présenter l'écriture d'un modèle,\ntransformant une vue plane (tableau deux dimensions) en vue\nhiérarchique. Pour cela nous allons prendre l'exemple de l'affichage\nd'une liste de catégorie",[1607,12717,12718],{},[39,12719,461],{"href":1611,"ariaDescribedBy":12720,"dataFootnoteRef":61,"id":1614},[1613],[12,12722,12724],{"id":12723},"présentation-de-lexemple","Présentation de l'exemple",[17,12726,12727],{},"Nous allons voir ci-dessous comment transformer une vue plane en une vue\nhiérarchique. Pour cela nous allons prendre l'exemple d'une liste de\ncatégorie. Ces catégories seront stockées dans une base de données\nSqlite. Ceci n'a pas d'importance mais permet d'expliquer pourquoi les\ndonnées en mémoire ne sont pas déjà sous forme hiérarchique.",[17,12729,12730],{},[1445,12731],{"alt":12732,"src":12733},"proxymodel","\u002FProgrammation\u002Fqt-transformation-d-une-vue-tableau-en-une-vue-hierarchique\u002Fproxymodel.png",[17,12735,12736],{},"La description d'une catégorie passe donc par :",[3359,12738,12739,12744,12747],{},[165,12740,12741,12742],{},"un identifiant unique appelé ",[32,12743,11040],{},[165,12745,12746],{},"un nom de catégorie",[165,12748,12749,12750],{},"un lien vers la catégorie parente appelé ",[32,12751,12752],{},"parent_id",[17,12754,12755,12756,12758,12759,12762,12763,12765,12766,44],{},"C'est le champ ",[32,12757,12752],{}," qui permettra de déterminer dans quelle\ncatégorie notre sous-catégorie se trouve. Dans notre cas, ",[32,12760,12761],{},"test3"," a\ncomme ",[32,12764,12752],{}," l'identifiant 11 qui est la catégorie ",[32,12767,1979],{},[17,12769,12770,12771,12774],{},"Dans notre exemple, nous allons nous conditionner à un modèle en lecture\nseul. Il est également possible de faire un modèle en lecture\u002Fécriture\nmais nous n'en parlerons pas dans cet article. Nous nous cantonnerons\ndonc à un modèle lecture seul sur un modèle source de type\n",[32,12772,12773],{},"QSqlTableView",". (Un modèle en lecture\u002Fécriture peut nécessiter de\nmettre à jour notre structure, ce qui peut être assez compliqué, par\nexemple en cas de changement de la catégorie parente).",[12,12776,12778],{"id":12777},"déclaration-dun-modèle","Déclaration d'un modèle",[4389,12780,12782],{"id":12781},"quest-quun-proxy","Qu'est qu'un proxy ?",[17,12784,12785,12786,12789,12790,12793],{},"Notre interface se basera sur la classe ",[32,12787,12788],{},"QAbstractProxyModel",". Le but de\ncette classe est de permettre de faire une transposition entre un\npremier modèle et une vue. Elle peut par exemple (à l'aide de\n",[32,12791,12792],{},"QSortFilterProxyModel",") permettre de filtrer ou trier les données d'une\nvue.",[17,12795,12796],{},[1445,12797],{"alt":12798,"src":12799},"mvc","\u002FProgrammation\u002Fqt-transformation-d-une-vue-tableau-en-une-vue-hierarchique\u002Fmvc.png",[17,12801,12802],{},"Cette vue nous permettra de faire la transposition entre un modèle\ntableau et une vue arborescente.",[4389,12804,12806],{"id":12805},"interface-du-proxy","Interface du proxy",[17,12808,12809],{},"Les méthodes à ré-implémenter pour faire fonctionner une proxy, sont les\nsuivantes :",[56,12811,12813],{"className":214,"code":12812,"language":216,"meta":61,"style":61},"virtual QModelIndex index( int row, int column, const QModelIndex & parent ) const;\nvirtual QModelIndex parent( const QModelIndex & index ) const;\n\nvirtual int rowCount( const QModelIndex & parent = QModelIndex() ) const;\nvirtual int columnCount( const QModelIndex & parent = QModelIndex() ) const;\n\nvirtual QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const;\nvirtual QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const;\n",[63,12814,12815,12860,12884,12888,12919,12948,12952,12978],{"__ignoreMap":61},[66,12816,12817,12820,12823,12826,12829,12831,12834,12836,12838,12841,12843,12845,12847,12850,12853,12856,12858],{"class":68,"line":69},[66,12818,12819],{"class":223},"virtual",[66,12821,12822],{"class":240}," QModelIndex",[66,12824,12825],{"class":72}," index",[66,12827,12828],{"class":230},"( ",[66,12830,1899],{"class":223},[66,12832,12833],{"class":247}," row",[66,12835,251],{"class":230},[66,12837,1899],{"class":223},[66,12839,12840],{"class":247}," column",[66,12842,251],{"class":230},[66,12844,234],{"class":223},[66,12846,12822],{"class":240},[66,12848,12849],{"class":223}," &",[66,12851,12852],{"class":247}," parent",[66,12854,12855],{"class":230}," ) ",[66,12857,234],{"class":223},[66,12859,1952],{"class":230},[66,12861,12862,12864,12866,12868,12870,12872,12874,12876,12878,12880,12882],{"class":68,"line":80},[66,12863,12819],{"class":223},[66,12865,12822],{"class":240},[66,12867,12852],{"class":72},[66,12869,12828],{"class":230},[66,12871,234],{"class":223},[66,12873,12822],{"class":240},[66,12875,12849],{"class":223},[66,12877,12825],{"class":247},[66,12879,12855],{"class":230},[66,12881,234],{"class":223},[66,12883,1952],{"class":230},[66,12885,12886],{"class":68,"line":89},[66,12887,276],{"emptyLinePlaceholder":275},[66,12889,12890,12892,12895,12898,12900,12902,12904,12906,12908,12910,12912,12915,12917],{"class":68,"line":279},[66,12891,12819],{"class":223},[66,12893,12894],{"class":223}," int",[66,12896,12897],{"class":72}," rowCount",[66,12899,12828],{"class":230},[66,12901,234],{"class":223},[66,12903,12822],{"class":240},[66,12905,12849],{"class":223},[66,12907,12852],{"class":247},[66,12909,2883],{"class":223},[66,12911,12822],{"class":72},[66,12913,12914],{"class":230},"() ) ",[66,12916,234],{"class":223},[66,12918,1952],{"class":230},[66,12920,12921,12923,12925,12928,12930,12932,12934,12936,12938,12940,12942,12944,12946],{"class":68,"line":307},[66,12922,12819],{"class":223},[66,12924,12894],{"class":223},[66,12926,12927],{"class":72}," columnCount",[66,12929,12828],{"class":230},[66,12931,234],{"class":223},[66,12933,12822],{"class":240},[66,12935,12849],{"class":223},[66,12937,12852],{"class":247},[66,12939,2883],{"class":223},[66,12941,12822],{"class":72},[66,12943,12914],{"class":230},[66,12945,234],{"class":223},[66,12947,1952],{"class":230},[66,12949,12950],{"class":68,"line":329},[66,12951,276],{"emptyLinePlaceholder":275},[66,12953,12954,12956,12958,12961,12963,12965,12967,12969,12972,12974,12976],{"class":68,"line":334},[66,12955,12819],{"class":223},[66,12957,12822],{"class":240},[66,12959,12960],{"class":72}," mapFromSource",[66,12962,5012],{"class":230},[66,12964,234],{"class":223},[66,12966,12822],{"class":240},[66,12968,12849],{"class":223},[66,12970,12971],{"class":247}," sourceIndex",[66,12973,12855],{"class":230},[66,12975,234],{"class":223},[66,12977,1952],{"class":230},[66,12979,12980,12982,12984,12987,12989,12991,12993,12995,12998,13000,13002],{"class":68,"line":340},[66,12981,12819],{"class":223},[66,12983,12822],{"class":240},[66,12985,12986],{"class":72}," mapToSource",[66,12988,5012],{"class":230},[66,12990,234],{"class":223},[66,12992,12822],{"class":240},[66,12994,12849],{"class":223},[66,12996,12997],{"class":247}," proxyIndex",[66,12999,12855],{"class":230},[66,13001,234],{"class":223},[66,13003,1952],{"class":230},[17,13005,13006,13007,13010],{},"Les quatre premières méthodes appartiennent à l'objet\n",[32,13008,13009],{},"QAbstractItemModel"," et seront questionnées par la vue (liste, arbre, …)\npour connaître la représentation à l'écran.",[17,13012,13013,13014,9277,13017,13020,13021,13023,13024,13027],{},"Les méthodes ",[32,13015,13016],{},"mapFromSource()",[32,13018,13019],{},"mapToSource()"," sont à implémenter\npour l'objet ",[32,13022,12788],{},". Elles permettent de faire la liaison\nentre les indexes (",[32,13025,13026],{},"QModelIndex",") du modèle d'origine et les indexes du\nnouveau modèle.",[17,13029,13013,13030,251,13033,251,13036,13039,13040,13042,13043,3581,13045,13047],{},[32,13031,13032],{},"data()",[32,13034,13035],{},"headerData()",[32,13037,13038],{},"flags()"," sont réimplémentées par\nl'objet ",[32,13041,12788],{}," et utilisent les méthodes\n",[32,13044,13016],{},[32,13046,13019],{}," pour, lors de l'appel d'une de ces\nméthodes, récupérer les informations stockées sur le modèle d'origine.",[17,13049,13050,13051,3581,13054,13057],{},"Des méthodes ",[32,13052,13053],{},"sourceModel()",[32,13055,13056],{},"setSourceModel()"," permettent de\nspécifier le modèle d'origine.",[12,13059,13061],{"id":13060},"implémentation-de-notre-modèle","Implémentation de notre modèle",[4389,13063,13065],{"id":13064},"structure-interne","Structure interne",[17,13067,13068],{},"Nous allons, dans cette partie, parler de la structure interne utilisée\npar notre objet.",[56,13070,13072],{"className":214,"code":13071,"language":216,"meta":61,"style":61},"struct Mapping {\n    int id, parrentId;\n    int index, parentIndex;\n    QVector\u003Cint> source_rows;\n};\ntypedef QMap\u003Cint,Mapping*> IndexMap;\n\nIndexMap m_sourcesIndexMapping;\nQHash\u003Cint,int> m_categoryIdMapping;\n",[63,13073,13074,13083,13091,13098,13109,13113,13133,13137,13142],{"__ignoreMap":61},[66,13075,13076,13078,13081],{"class":68,"line":69},[66,13077,873],{"class":223},[66,13079,13080],{"class":240}," Mapping",[66,13082,555],{"class":230},[66,13084,13085,13088],{"class":68,"line":80},[66,13086,13087],{"class":223},"    int",[66,13089,13090],{"class":230}," id, parrentId;\n",[66,13092,13093,13095],{"class":68,"line":89},[66,13094,13087],{"class":223},[66,13096,13097],{"class":230}," index, parentIndex;\n",[66,13099,13100,13103,13106],{"class":68,"line":279},[66,13101,13102],{"class":230},"    QVector",[66,13104,13105],{"class":223},"\u003Cint>",[66,13107,13108],{"class":230}," source_rows;\n",[66,13110,13111],{"class":68,"line":307},[66,13112,906],{"class":230},[66,13114,13115,13118,13121,13124,13127,13130],{"class":68,"line":329},[66,13116,13117],{"class":223},"typedef",[66,13119,13120],{"class":230}," QMap",[66,13122,13123],{"class":223},"\u003Cint",[66,13125,13126],{"class":230},",Mapping",[66,13128,13129],{"class":223},"*>",[66,13131,13132],{"class":230}," IndexMap;\n",[66,13134,13135],{"class":68,"line":334},[66,13136,276],{"emptyLinePlaceholder":275},[66,13138,13139],{"class":68,"line":340},[66,13140,13141],{"class":230},"IndexMap m_sourcesIndexMapping;\n",[66,13143,13144,13147,13149,13152,13155],{"class":68,"line":355},[66,13145,13146],{"class":230},"QHash",[66,13148,13123],{"class":223},[66,13150,13151],{"class":230},",",[66,13153,13154],{"class":223},"int>",[66,13156,13157],{"class":230}," m_categoryIdMapping;\n",[17,13159,13160,13161,13164],{},"Nous allons créer une structure ",[32,13162,13163],{},"Mapping"," qui associera pour une ligne\ndans le modèle source, les informations concernant :",[3359,13166,13167,13170,13173,13176,13179],{},[165,13168,13169],{},"l'identifiant de la ligne.",[165,13171,13172],{},"l'identifiant de la ligne parente.",[165,13174,13175],{},"l'index dans le modèle source.",[165,13177,13178],{},"l'index du parent dans le modèle source.",[165,13180,13181],{},"la liste des indexes dans le modèle source des enfants dans notre\nmodèle.",[17,13183,13184],{},"Une table de hashage permettra de retrouver à partir d'un identifiant\n(id), la ligne dans le modèle source correspondante. On ne gardera que\nla seconde colonne (le nom de la catégorie), on ne fera donc\nl'association qu'entre le nom de la colonne de notre modèle et le modèle\nsource en dure dans le programme.",[4389,13186,13188],{"id":13187},"createmapping","createMapping()",[17,13190,13191],{},"Le but de cette méthode est de générer l'arborescence qui sera ensuite\nutilisée dans la suite des méthodes. Cette arborescence étant générée\nune fois pour toute (ou à chaque fois que le modèle source sera\nréinitialisé), il faudra parcourir l'ensemble des lignes du modèle\nsource pour construire notre arbre. Parcourir l'ensemble des lignes du\nmodèle source peut prendre du temps si ce dernier contient beaucoup de\nligne.",[17,13193,13194,13195,13198],{},"Nous allons considérer dans la suite, que l'identifiant de ligne 1 (id)\ncorrespond à la catégorie de plus haut niveau (ci-dessus du nom de\n",[32,13196,13197],{},"Categories","). Nous allons créer une catégorie fictive 0 qui\ncorrespondra à la racine de notre modèle. Cette catégorie sera donc la\ncatégorie parente de celle à l'identifiant 1.Dans notre modèle source,\nla catégorie 0 n'a pas d'équivalence parmi les lignes du modèle source.\nNous allons donc lui associer la ligne -1 dans le modèle source.",[17,13200,13201],{},"Maintenant voyons la génération de la structure interne.",[56,13203,13205],{"className":214,"code":13204,"language":216,"meta":61,"style":61},"qDeleteAll( m_sourcesIndexMapping );\nm_sourcesIndexMapping.clear();\nm_categoryIdMapping.clear();\n",[63,13206,13207,13215,13227],{"__ignoreMap":61},[66,13208,13209,13212],{"class":68,"line":69},[66,13210,13211],{"class":72},"qDeleteAll",[66,13213,13214],{"class":230},"( m_sourcesIndexMapping );\n",[66,13216,13217,13220,13222,13225],{"class":68,"line":80},[66,13218,13219],{"class":240},"m_sourcesIndexMapping",[66,13221,44],{"class":230},[66,13223,13224],{"class":72},"clear",[66,13226,543],{"class":230},[66,13228,13229,13232,13234,13236],{"class":68,"line":89},[66,13230,13231],{"class":240},"m_categoryIdMapping",[66,13233,44],{"class":230},[66,13235,13224],{"class":72},[66,13237,543],{"class":230},[17,13239,13240,13241,13244],{},"Nous commençons ci-dessous par nettoyer les différentes structures afin\nde les régénérer. Il faudra à la suite de la création du mapping appeler\nla méthode ",[32,13242,13243],{},"reset()"," afin de prévenir la vue que l'ensemble des indexes\ndu modèle sont obsolètes.",[56,13246,13248],{"className":214,"code":13247,"language":216,"meta":61,"style":61},"int source_rows = m_sourceModel->rowCount();\nfor( int i = -1; i \u003C source_rows; ++i ) {\n    Mapping * m = new Mapping;\n    IndexMap::const_iterator it = IndexMap::const_iterator( m_sourcesIndexMapping.insert( i, m ) );\n    m->index = i;\n    m->parrentId = 0;\n    m->parentIndex = 0;\n\n    if( i >= 0 ) {\n        QSqlRecord record = m_sourceModel->record( i );\n        m_categoryIdMapping[ record.value( list_id ).toInt() ] = i;\n        m->id = record.value( list_id ).toInt();\n    } else { \u002F\u002F Create the root Item\n        m->id = 0;\n        m_categoryIdMapping[ 0 ] = -1;\n    }\n}\n",[63,13249,13250,13269,13299,13316,13341,13356,13371,13386,13390,13405,13422,13449,13473,13484,13498,13517,13521],{"__ignoreMap":61},[66,13251,13252,13254,13257,13259,13262,13264,13267],{"class":68,"line":69},[66,13253,1899],{"class":223},[66,13255,13256],{"class":230}," source_rows ",[66,13258,378],{"class":223},[66,13260,13261],{"class":240}," m_sourceModel",[66,13263,2829],{"class":230},[66,13265,13266],{"class":72},"rowCount",[66,13268,543],{"class":230},[66,13270,13271,13273,13275,13277,13279,13281,13283,13285,13288,13290,13293,13296],{"class":68,"line":80},[66,13272,2013],{"class":223},[66,13274,12828],{"class":230},[66,13276,1899],{"class":223},[66,13278,9875],{"class":230},[66,13280,378],{"class":223},[66,13282,2209],{"class":223},[66,13284,461],{"class":114},[66,13286,13287],{"class":230},"; i ",[66,13289,532],{"class":223},[66,13291,13292],{"class":230}," source_rows; ",[66,13294,13295],{"class":223},"++",[66,13297,13298],{"class":230},"i ) {\n",[66,13300,13301,13304,13306,13309,13311,13313],{"class":68,"line":89},[66,13302,13303],{"class":230},"    Mapping ",[66,13305,593],{"class":223},[66,13307,13308],{"class":230}," m ",[66,13310,378],{"class":223},[66,13312,2811],{"class":223},[66,13314,13315],{"class":230}," Mapping;\n",[66,13317,13318,13321,13323,13326,13329,13331,13333,13335,13338],{"class":68,"line":279},[66,13319,13320],{"class":230},"    IndexMap::const_iterator it ",[66,13322,378],{"class":223},[66,13324,13325],{"class":230}," IndexMap::",[66,13327,13328],{"class":72},"const_iterator",[66,13330,12828],{"class":230},[66,13332,13219],{"class":240},[66,13334,44],{"class":230},[66,13336,13337],{"class":72},"insert",[66,13339,13340],{"class":230},"( i, m ) );\n",[66,13342,13343,13346,13348,13351,13353],{"class":68,"line":307},[66,13344,13345],{"class":240},"    m",[66,13347,2829],{"class":230},[66,13349,13350],{"class":437},"index",[66,13352,2883],{"class":223},[66,13354,13355],{"class":230}," i;\n",[66,13357,13358,13360,13362,13365,13367,13369],{"class":68,"line":329},[66,13359,13345],{"class":240},[66,13361,2829],{"class":230},[66,13363,13364],{"class":437},"parrentId",[66,13366,2883],{"class":223},[66,13368,1949],{"class":114},[66,13370,1952],{"class":230},[66,13372,13373,13375,13377,13380,13382,13384],{"class":68,"line":334},[66,13374,13345],{"class":240},[66,13376,2829],{"class":230},[66,13378,13379],{"class":437},"parentIndex",[66,13381,2883],{"class":223},[66,13383,1949],{"class":114},[66,13385,1952],{"class":230},[66,13387,13388],{"class":68,"line":340},[66,13389,276],{"emptyLinePlaceholder":275},[66,13391,13392,13394,13397,13400,13402],{"class":68,"line":355},[66,13393,493],{"class":223},[66,13395,13396],{"class":230},"( i ",[66,13398,13399],{"class":223},">=",[66,13401,1949],{"class":114},[66,13403,13404],{"class":230}," ) {\n",[66,13406,13407,13410,13412,13414,13416,13419],{"class":68,"line":372},[66,13408,13409],{"class":230},"        QSqlRecord record ",[66,13411,378],{"class":223},[66,13413,13261],{"class":240},[66,13415,2829],{"class":230},[66,13417,13418],{"class":72},"record",[66,13420,13421],{"class":230},"( i );\n",[66,13423,13424,13427,13430,13432,13434,13436,13439,13442,13445,13447],{"class":68,"line":395},[66,13425,13426],{"class":240},"        m_categoryIdMapping",[66,13428,13429],{"class":230},"[ ",[66,13431,13418],{"class":240},[66,13433,44],{"class":230},[66,13435,3977],{"class":72},[66,13437,13438],{"class":230},"( list_id ).",[66,13440,13441],{"class":72},"toInt",[66,13443,13444],{"class":230},"() ] ",[66,13446,378],{"class":223},[66,13448,13355],{"class":230},[66,13450,13451,13454,13456,13458,13460,13463,13465,13467,13469,13471],{"class":68,"line":400},[66,13452,13453],{"class":240},"        m",[66,13455,2829],{"class":230},[66,13457,11040],{"class":437},[66,13459,2883],{"class":223},[66,13461,13462],{"class":240}," record",[66,13464,44],{"class":230},[66,13466,3977],{"class":72},[66,13468,13438],{"class":230},[66,13470,13441],{"class":72},[66,13472,543],{"class":230},[66,13474,13475,13477,13479,13481],{"class":68,"line":416},[66,13476,549],{"class":230},[66,13478,552],{"class":223},[66,13480,879],{"class":230},[66,13482,13483],{"class":351}," \u002F\u002F Create the root Item\n",[66,13485,13486,13488,13490,13492,13494,13496],{"class":68,"line":421},[66,13487,13453],{"class":240},[66,13489,2829],{"class":230},[66,13491,11040],{"class":437},[66,13493,2883],{"class":223},[66,13495,1949],{"class":114},[66,13497,1952],{"class":230},[66,13499,13500,13502,13504,13506,13509,13511,13513,13515],{"class":68,"line":485},[66,13501,13426],{"class":240},[66,13503,13429],{"class":230},[66,13505,444],{"class":114},[66,13507,13508],{"class":230}," ] ",[66,13510,378],{"class":223},[66,13512,2209],{"class":223},[66,13514,461],{"class":114},[66,13516,1952],{"class":230},[66,13518,13519],{"class":68,"line":490},[66,13520,656],{"class":230},[66,13522,13523],{"class":68,"line":520},[66,13524,1413],{"class":230},[17,13526,13527,13528,13530,13531,44],{},"Nous récupérons le nombre de ligne dans le modèle source et commençons à\ninitialiser notre structure. Le but de cette boucle est surtout\nd'initialiser dans notre correspondance identifiant\u002Findex\n(",[32,13529,13231],{},"), l'emplacement des identifiants dans notre\ntableau. Ainsi dans la suite lorsque l'on essaiera d'associer une ligne\nà son parent, nous pourrons savoir à quel emplacement retrouver notre id\ndans la structure ",[32,13532,13219],{},[17,13534,13535],{},"Nous profitons également de cette boucle pour initialiser les différents\nchamps de notre structure comme l'index (qui correspond à la ligne dans\nle modèle source), et l'id qui correspond à un identifiant unique dans\nnotre liste.",[17,13537,13538],{},"Nous n'oublions pas notre cas particulier que représente notre racine\n(ligne source -1 inexistante).",[56,13540,13542],{"className":214,"code":13541,"language":216,"meta":61,"style":61},"for( int i = 0; i \u003C source_rows; ++i ) {\n    QSqlRecord record = m_sourceModel->record( i );\n\n    int parentCategoryId = record.value( list_parentid ).toInt();\n    int parentCategoryIndex = m_categoryIdMapping.value( parentCategoryId, -2 );\n    Q_ASSERT( parentCategoryIndex > -2 );\n    Mapping * mapping = m_sourcesIndexMapping.value( i );\n    mapping->parentIndex = parentCategoryIndex;\n    mapping->parrentId   = parentCategoryId;\n\n    Mapping * categoryMapping = m_sourcesIndexMapping.value( parentCategoryIndex );\n    categoryMapping->source_rows.append( i );\n}\n",[63,13543,13544,13568,13583,13587,13609,13635,13651,13671,13685,13699,13703,13723,13739],{"__ignoreMap":61},[66,13545,13546,13548,13550,13552,13554,13556,13558,13560,13562,13564,13566],{"class":68,"line":69},[66,13547,2013],{"class":223},[66,13549,12828],{"class":230},[66,13551,1899],{"class":223},[66,13553,9875],{"class":230},[66,13555,378],{"class":223},[66,13557,1949],{"class":114},[66,13559,13287],{"class":230},[66,13561,532],{"class":223},[66,13563,13292],{"class":230},[66,13565,13295],{"class":223},[66,13567,13298],{"class":230},[66,13569,13570,13573,13575,13577,13579,13581],{"class":68,"line":80},[66,13571,13572],{"class":230},"    QSqlRecord record ",[66,13574,378],{"class":223},[66,13576,13261],{"class":240},[66,13578,2829],{"class":230},[66,13580,13418],{"class":72},[66,13582,13421],{"class":230},[66,13584,13585],{"class":68,"line":89},[66,13586,276],{"emptyLinePlaceholder":275},[66,13588,13589,13591,13594,13596,13598,13600,13602,13605,13607],{"class":68,"line":279},[66,13590,13087],{"class":223},[66,13592,13593],{"class":230}," parentCategoryId ",[66,13595,378],{"class":223},[66,13597,13462],{"class":240},[66,13599,44],{"class":230},[66,13601,3977],{"class":72},[66,13603,13604],{"class":230},"( list_parentid ).",[66,13606,13441],{"class":72},[66,13608,543],{"class":230},[66,13610,13611,13613,13616,13618,13621,13623,13625,13628,13630,13632],{"class":68,"line":307},[66,13612,13087],{"class":223},[66,13614,13615],{"class":230}," parentCategoryIndex ",[66,13617,378],{"class":223},[66,13619,13620],{"class":240}," m_categoryIdMapping",[66,13622,44],{"class":230},[66,13624,3977],{"class":72},[66,13626,13627],{"class":230},"( parentCategoryId, ",[66,13629,508],{"class":223},[66,13631,476],{"class":114},[66,13633,13634],{"class":230}," );\n",[66,13636,13637,13640,13643,13645,13647,13649],{"class":68,"line":329},[66,13638,13639],{"class":72},"    Q_ASSERT",[66,13641,13642],{"class":230},"( parentCategoryIndex ",[66,13644,6157],{"class":223},[66,13646,2209],{"class":223},[66,13648,476],{"class":114},[66,13650,13634],{"class":230},[66,13652,13653,13655,13657,13660,13662,13665,13667,13669],{"class":68,"line":334},[66,13654,13303],{"class":230},[66,13656,593],{"class":223},[66,13658,13659],{"class":230}," mapping ",[66,13661,378],{"class":223},[66,13663,13664],{"class":240}," m_sourcesIndexMapping",[66,13666,44],{"class":230},[66,13668,3977],{"class":72},[66,13670,13421],{"class":230},[66,13672,13673,13676,13678,13680,13682],{"class":68,"line":340},[66,13674,13675],{"class":240},"    mapping",[66,13677,2829],{"class":230},[66,13679,13379],{"class":437},[66,13681,2883],{"class":223},[66,13683,13684],{"class":230}," parentCategoryIndex;\n",[66,13686,13687,13689,13691,13693,13696],{"class":68,"line":355},[66,13688,13675],{"class":240},[66,13690,2829],{"class":230},[66,13692,13364],{"class":437},[66,13694,13695],{"class":223},"   =",[66,13697,13698],{"class":230}," parentCategoryId;\n",[66,13700,13701],{"class":68,"line":372},[66,13702,276],{"emptyLinePlaceholder":275},[66,13704,13705,13707,13709,13712,13714,13716,13718,13720],{"class":68,"line":395},[66,13706,13303],{"class":230},[66,13708,593],{"class":223},[66,13710,13711],{"class":230}," categoryMapping ",[66,13713,378],{"class":223},[66,13715,13664],{"class":240},[66,13717,44],{"class":230},[66,13719,3977],{"class":72},[66,13721,13722],{"class":230},"( parentCategoryIndex );\n",[66,13724,13725,13728,13730,13733,13735,13737],{"class":68,"line":400},[66,13726,13727],{"class":240},"    categoryMapping",[66,13729,2829],{"class":230},[66,13731,13732],{"class":240},"source_rows",[66,13734,44],{"class":230},[66,13736,7512],{"class":72},[66,13738,13421],{"class":230},[66,13740,13741],{"class":68,"line":416},[66,13742,1413],{"class":230},[17,13744,13745],{},"Enfin pour chaque enregistrement de notre modèle source, nous récupérons\nl'identifiant du parent et recherchons dans la structure que nous venons\nde créer l'index dans le modèle source de la catégorie parente.",[17,13747,13748,13749,13752],{},"Ces valeurs sont alors renseignées dans le modèle. Nos ajoutons\négalement dans la structure de ",[32,13750,13751],{},"mapping"," de la catégorie parent, notre\nligne dans la liste des enfants.",[17,13754,13755],{},"Notre structure est ainsi complètement initialisé. Un identifiant\nconnaît donc son parent, et la liste de ses enfants. C'est sur cette\nstructure que se basera le reste des méthodes de notre modèle.",[4389,13757,13016],{"id":13758},"mapfromsource",[17,13760,13761],{},"Le but de cette méthode est de convertir notre index venant du modèle\nsource vers un index de notre modèle à nous.",[17,13763,13764],{},"L'index du modèle source nous donne l'emplacement de la donnée dans le\nmodèle source sous forme (ligne, colonne) alors que l'index de notre\nmodèle doit donner l'emplacement dans notre modèle sous la forme (ligne,\ncolonne, pointeur indiquant le parent).",[56,13766,13768],{"className":214,"code":13767,"language":216,"meta":61,"style":61},"if( ! sourceIndex.isValid() ) return QModelIndex();\nif( sourceIndex.model() != m_sourceModel ) {\n    qWarning( \"CategoryItemModel: index from wrong model passed to mapFromSource\" );\n    return QModelIndex();\n}\n",[63,13769,13770,13795,13817,13829,13837],{"__ignoreMap":61},[66,13771,13772,13774,13776,13779,13781,13783,13786,13788,13791,13793],{"class":68,"line":69},[66,13773,4791],{"class":223},[66,13775,12828],{"class":230},[66,13777,13778],{"class":83},"!",[66,13780,12971],{"class":240},[66,13782,44],{"class":230},[66,13784,13785],{"class":72},"isValid",[66,13787,12914],{"class":230},[66,13789,13790],{"class":223},"return",[66,13792,12822],{"class":72},[66,13794,543],{"class":230},[66,13796,13797,13799,13801,13804,13806,13809,13811,13814],{"class":68,"line":80},[66,13798,4791],{"class":223},[66,13800,12828],{"class":230},[66,13802,13803],{"class":240},"sourceIndex",[66,13805,44],{"class":230},[66,13807,13808],{"class":72},"model",[66,13810,590],{"class":230},[66,13812,13813],{"class":223},"!=",[66,13815,13816],{"class":230}," m_sourceModel ) {\n",[66,13818,13819,13822,13824,13827],{"class":68,"line":89},[66,13820,13821],{"class":72},"    qWarning",[66,13823,12828],{"class":230},[66,13825,13826],{"class":76},"\"CategoryItemModel: index from wrong model passed to mapFromSource\"",[66,13828,13634],{"class":230},[66,13830,13831,13833,13835],{"class":68,"line":279},[66,13832,1946],{"class":223},[66,13834,12822],{"class":72},[66,13836,543],{"class":230},[66,13838,13839],{"class":68,"line":307},[66,13840,1413],{"class":230},[17,13842,13843],{},"Il faut donc d'abord vérifier que l'index du modèle source est valide.\nS'il n'est pas valide, alors il ne sera pas valide non plus dans notre\nmodèle à nous.",[56,13845,13847],{"className":214,"code":13846,"language":216,"meta":61,"style":61},"int row = sourceIndex.row();\nIndexMap::const_iterator it = m_sourcesIndexMapping.constFind( row );\nQ_ASSERT( it != m_sourcesIndexMapping.constEnd() );\n",[63,13848,13849,13867,13884],{"__ignoreMap":61},[66,13850,13851,13853,13856,13858,13860,13862,13865],{"class":68,"line":69},[66,13852,1899],{"class":223},[66,13854,13855],{"class":230}," row ",[66,13857,378],{"class":223},[66,13859,12971],{"class":240},[66,13861,44],{"class":230},[66,13863,13864],{"class":72},"row",[66,13866,543],{"class":230},[66,13868,13869,13872,13874,13876,13878,13881],{"class":68,"line":80},[66,13870,13871],{"class":230},"IndexMap::const_iterator it ",[66,13873,378],{"class":223},[66,13875,13664],{"class":240},[66,13877,44],{"class":230},[66,13879,13880],{"class":72},"constFind",[66,13882,13883],{"class":230},"( row );\n",[66,13885,13886,13889,13892,13894,13896,13898,13901],{"class":68,"line":89},[66,13887,13888],{"class":72},"Q_ASSERT",[66,13890,13891],{"class":230},"( it ",[66,13893,13813],{"class":223},[66,13895,13664],{"class":240},[66,13897,44],{"class":230},[66,13899,13900],{"class":72},"constEnd",[66,13902,13903],{"class":230},"() );\n",[17,13905,13906,13907,13909,13910,13912,13913,13915,13916,13918],{},"Nous récupérons l'index dans le modèle source, et à l'aide de notre\ntableau d'index source, nous allons retrouver l'objet ",[32,13908,13163],{},"\ncorrespondant. Cette objet ",[32,13911,13163],{}," correspondra à celui de notre index\nsource. Ce dont nous avons besoin pour notre modèle est l'objet\n",[32,13914,13163],{}," de l'objet parent (En effet, notre index est construit sous la\nforme : ligne, colonne, pointeur sur la structure ",[32,13917,13163],{}," du parent de\nnotre index). Nous récupérons donc l'index de la ligne source dans\nl'objet parent.",[56,13920,13922],{"className":214,"code":13921,"language":216,"meta":61,"style":61},"int parentRow = it.value()->parentIndex;\nIndexMap::const_iterator parentIt = m_sourcesIndexMapping.constFind( parentRow );\nQ_ASSERT( parentIt != m_sourcesIndexMapping.constEnd() );\n\nMapping * m = parentIt.value();\n",[63,13923,13924,13947,13963,13980,13984],{"__ignoreMap":61},[66,13925,13926,13928,13931,13933,13936,13938,13940,13943,13945],{"class":68,"line":69},[66,13927,1899],{"class":223},[66,13929,13930],{"class":230}," parentRow ",[66,13932,378],{"class":223},[66,13934,13935],{"class":240}," it",[66,13937,44],{"class":230},[66,13939,3977],{"class":72},[66,13941,13942],{"class":230},"()->",[66,13944,13379],{"class":437},[66,13946,1952],{"class":230},[66,13948,13949,13952,13954,13956,13958,13960],{"class":68,"line":80},[66,13950,13951],{"class":230},"IndexMap::const_iterator parentIt ",[66,13953,378],{"class":223},[66,13955,13664],{"class":240},[66,13957,44],{"class":230},[66,13959,13880],{"class":72},[66,13961,13962],{"class":230},"( parentRow );\n",[66,13964,13965,13967,13970,13972,13974,13976,13978],{"class":68,"line":89},[66,13966,13888],{"class":72},[66,13968,13969],{"class":230},"( parentIt ",[66,13971,13813],{"class":223},[66,13973,13664],{"class":240},[66,13975,44],{"class":230},[66,13977,13900],{"class":72},[66,13979,13903],{"class":230},[66,13981,13982],{"class":68,"line":279},[66,13983,276],{"emptyLinePlaceholder":275},[66,13985,13986,13989,13991,13993,13995,13998,14000,14002],{"class":68,"line":307},[66,13987,13988],{"class":230},"Mapping ",[66,13990,593],{"class":223},[66,13992,13308],{"class":230},[66,13994,378],{"class":223},[66,13996,13997],{"class":240}," parentIt",[66,13999,44],{"class":230},[66,14001,3977],{"class":72},[66,14003,543],{"class":230},[17,14005,14006,14007,14009],{},"Cela nous permet de récupérer l'objet ",[32,14008,13163],{}," de l'index parent.",[56,14011,14013],{"className":214,"code":14012,"language":216,"meta":61,"style":61},"int proxyRow    = m->source_rows.indexOf( row );\nint proxyColumn = sourceColumnToProxy( sourceIndex.column() );\nif( proxyColumn == -1 ) return QModelIndex();\n",[63,14014,14015,14038,14061],{"__ignoreMap":61},[66,14016,14017,14019,14022,14024,14027,14029,14031,14033,14036],{"class":68,"line":69},[66,14018,1899],{"class":223},[66,14020,14021],{"class":230}," proxyRow    ",[66,14023,378],{"class":223},[66,14025,14026],{"class":240}," m",[66,14028,2829],{"class":230},[66,14030,13732],{"class":240},[66,14032,44],{"class":230},[66,14034,14035],{"class":72},"indexOf",[66,14037,13883],{"class":230},[66,14039,14040,14042,14045,14047,14050,14052,14054,14056,14059],{"class":68,"line":80},[66,14041,1899],{"class":223},[66,14043,14044],{"class":230}," proxyColumn ",[66,14046,378],{"class":223},[66,14048,14049],{"class":72}," sourceColumnToProxy",[66,14051,12828],{"class":230},[66,14053,13803],{"class":240},[66,14055,44],{"class":230},[66,14057,14058],{"class":72},"column",[66,14060,13903],{"class":230},[66,14062,14063,14065,14068,14070,14072,14074,14076,14078,14080],{"class":68,"line":89},[66,14064,4791],{"class":223},[66,14066,14067],{"class":230},"( proxyColumn ",[66,14069,9175],{"class":223},[66,14071,2209],{"class":223},[66,14073,461],{"class":114},[66,14075,12855],{"class":230},[66,14077,13790],{"class":223},[66,14079,12822],{"class":72},[66,14081,543],{"class":230},[17,14083,8295,14084,14087,14088,44],{},[32,14085,14086],{},"sourceColumnToProxy()"," permet de transformer une colonne de\nl'objet source en une colonne de l'objet courant. Cela signifie que la\ncolonne 2 sera convertie en colonne 1, et que les colonnes 1 et 3 ne\nseront pas converties (et cachées). Dans ce dernier cas, nous retournons\n",[32,14089,14090],{},"QModelIndex()",[17,14092,14093,14094,14096],{},"L'index de la ligne dans notre modèle sera donné par la position dans la\nliste ",[32,14095,13732],{}," dans notre structure de conversion.",[56,14098,14100],{"className":214,"code":14099,"language":216,"meta":61,"style":61},"return createIndex( proxyRow, proxyColumn, *parentIt );\n",[63,14101,14102],{"__ignoreMap":61},[66,14103,14104,14106,14109,14112,14114],{"class":68,"line":69},[66,14105,13790],{"class":223},[66,14107,14108],{"class":72}," createIndex",[66,14110,14111],{"class":230},"( proxyRow, proxyColumn, ",[66,14113,593],{"class":223},[66,14115,14116],{"class":230},"parentIt );\n",[17,14118,14119],{},"Nous pouvons alors créer notre index.",[4389,14121,13019],{"id":14122},"maptosource",[17,14124,14125,14126,14128],{},"De la manière inverse à la méthode ",[32,14127,13016],{},", cette méthode\npermet de convertir un index de notre objet en un index du modèle\nsource.",[56,14130,14132],{"className":214,"code":14131,"language":216,"meta":61,"style":61},"if( ! proxyIndex.isValid() ) return QModelIndex();\nif( proxyIndex.model() != this ) {\n    qWarning( \"CategoryItemModel: index from wrong model passed to mapToSource\" );\n    return QModelIndex();\n}\n",[63,14133,14134,14156,14178,14189,14197],{"__ignoreMap":61},[66,14135,14136,14138,14140,14142,14144,14146,14148,14150,14152,14154],{"class":68,"line":69},[66,14137,4791],{"class":223},[66,14139,12828],{"class":230},[66,14141,13778],{"class":83},[66,14143,12997],{"class":240},[66,14145,44],{"class":230},[66,14147,13785],{"class":72},[66,14149,12914],{"class":230},[66,14151,13790],{"class":223},[66,14153,12822],{"class":72},[66,14155,543],{"class":230},[66,14157,14158,14160,14162,14165,14167,14169,14171,14173,14176],{"class":68,"line":80},[66,14159,4791],{"class":223},[66,14161,12828],{"class":230},[66,14163,14164],{"class":240},"proxyIndex",[66,14166,44],{"class":230},[66,14168,13808],{"class":72},[66,14170,590],{"class":230},[66,14172,13813],{"class":223},[66,14174,14175],{"class":240}," this",[66,14177,13404],{"class":230},[66,14179,14180,14182,14184,14187],{"class":68,"line":89},[66,14181,13821],{"class":72},[66,14183,12828],{"class":230},[66,14185,14186],{"class":76},"\"CategoryItemModel: index from wrong model passed to mapToSource\"",[66,14188,13634],{"class":230},[66,14190,14191,14193,14195],{"class":68,"line":279},[66,14192,1946],{"class":223},[66,14194,12822],{"class":72},[66,14196,543],{"class":230},[66,14198,14199],{"class":68,"line":307},[66,14200,1413],{"class":230},[17,14202,14203],{},"Si le modèle est invalide dans notre modèle, il l'est aussi dans le\nmodèle source. Il n'y a pas d'équivalent dans le modèle source de\nl'index racine.",[56,14205,14207],{"className":214,"code":14206,"language":216,"meta":61,"style":61},"Mapping * m = static_cast\u003CMapping*>( proxyIndex.internalPointer() );\n",[63,14208,14209],{"__ignoreMap":61},[66,14210,14211,14213,14215,14217,14219,14222,14224,14226,14228,14230,14232,14234,14237],{"class":68,"line":69},[66,14212,13988],{"class":230},[66,14214,593],{"class":223},[66,14216,13308],{"class":230},[66,14218,378],{"class":223},[66,14220,14221],{"class":230}," static_cast",[66,14223,532],{"class":223},[66,14225,13163],{"class":230},[66,14227,13129],{"class":223},[66,14229,12828],{"class":230},[66,14231,14164],{"class":240},[66,14233,44],{"class":230},[66,14235,14236],{"class":72},"internalPointer",[66,14238,13903],{"class":230},[17,14240,14241],{},"Nous récupérons la structure dans le pointeur interne de notre index.",[56,14243,14245],{"className":214,"code":14244,"language":216,"meta":61,"style":61},"int sourceColumn = proxyColumnToSource( proxyIndex.column() );\nif( sourceColumn == -1 ) return QModelIndex();\n",[63,14246,14247,14269],{"__ignoreMap":61},[66,14248,14249,14251,14254,14256,14259,14261,14263,14265,14267],{"class":68,"line":69},[66,14250,1899],{"class":223},[66,14252,14253],{"class":230}," sourceColumn ",[66,14255,378],{"class":223},[66,14257,14258],{"class":72}," proxyColumnToSource",[66,14260,12828],{"class":230},[66,14262,14164],{"class":240},[66,14264,44],{"class":230},[66,14266,14058],{"class":72},[66,14268,13903],{"class":230},[66,14270,14271,14273,14276,14278,14280,14282,14284,14286,14288],{"class":68,"line":80},[66,14272,4791],{"class":223},[66,14274,14275],{"class":230},"( sourceColumn ",[66,14277,9175],{"class":223},[66,14279,2209],{"class":223},[66,14281,461],{"class":114},[66,14283,12855],{"class":230},[66,14285,13790],{"class":223},[66,14287,12822],{"class":72},[66,14289,543],{"class":230},[17,14291,14292],{},"Nous récupérons également les informations sur notre colonne (Soit,\nconversion de la colonne 0 dans notre modèle, en la colonne 1 dans le\nmodèle source).",[56,14294,14296],{"className":214,"code":14295,"language":216,"meta":61,"style":61},"int sourceRow = m->source_rows.at( proxyIndex.row() );\n",[63,14297,14298],{"__ignoreMap":61},[66,14299,14300,14302,14305,14307,14309,14311,14313,14315,14318,14320,14322,14324,14326],{"class":68,"line":69},[66,14301,1899],{"class":223},[66,14303,14304],{"class":230}," sourceRow ",[66,14306,378],{"class":223},[66,14308,14026],{"class":240},[66,14310,2829],{"class":230},[66,14312,13732],{"class":240},[66,14314,44],{"class":230},[66,14316,14317],{"class":72},"at",[66,14319,12828],{"class":230},[66,14321,14164],{"class":240},[66,14323,44],{"class":230},[66,14325,13864],{"class":72},[66,14327,13903],{"class":230},[17,14329,14330,14331,14333],{},"Nous recherchons dans notre liste ",[32,14332,13732],{}," la ligne dans le modèle\nsource qui correspond à la ligne (relative au père) indiqué par notre\nindex et nous construisons un index de type (ligne, colonne)\ncorrespondant au modèle source.",[56,14335,14337],{"className":214,"code":14336,"language":216,"meta":61,"style":61},"return m_sourceModel->index( sourceRow, sourceColumn );\n",[63,14338,14339],{"__ignoreMap":61},[66,14340,14341,14343,14345,14347,14349],{"class":68,"line":69},[66,14342,13790],{"class":223},[66,14344,13261],{"class":240},[66,14346,2829],{"class":230},[66,14348,13350],{"class":72},[66,14350,14351],{"class":230},"( sourceRow, sourceColumn );\n",[17,14353,14354,14355,3581,14357,14359,14360,251,14362,9277,14364,14366],{},"L'implémentation des méthodes ",[32,14356,13016],{},[32,14358,13019],{},"\npermettent de faire fonctionner les implémentations des méthodes\n",[32,14361,13032],{},[32,14363,13035],{},[32,14365,13038],{},". Il n'y aura donc aucun intérêt à\nré-implémenter ces méthodes à moins de vouloir traiter les données de\nces fonctions. Nous ne les décrirons donc pas ici, mais vous pourrez\nvoir dans le fichier attaché à la fin du billet, un exemple d'utilisation.",[4389,14368,14369],{"id":13350},"index()",[17,14371,14372,14373,14376,14377,251,14379,251,14382,251,14384,44],{},"Le principe de cette méthode est de générer un index pour notre modèle.\nL'index doit être valide et réutilisable dans les méthodes ",[32,14374,14375],{},"rowCount()",",\n",[32,14378,13038],{},[32,14380,14381],{},"columnCount()",[32,14383,13032],{},[32,14385,13019],{},[56,14387,14389],{"className":214,"code":14388,"language":216,"meta":61,"style":61},"if( ( row \u003C 0 ) || ( column \u003C 0 ) ) return QModelIndex();\n",[63,14390,14391],{"__ignoreMap":61},[66,14392,14393,14395,14398,14400,14402,14404,14407,14410,14412,14414,14417,14419,14421],{"class":68,"line":69},[66,14394,4791],{"class":223},[66,14396,14397],{"class":230},"( ( row ",[66,14399,532],{"class":223},[66,14401,1949],{"class":114},[66,14403,12855],{"class":230},[66,14405,14406],{"class":83},"||",[66,14408,14409],{"class":230}," ( column ",[66,14411,532],{"class":223},[66,14413,1949],{"class":114},[66,14415,14416],{"class":230}," ) ) ",[66,14418,13790],{"class":223},[66,14420,12822],{"class":72},[66,14422,543],{"class":230},[17,14424,14425],{},"Si la ligne ou la colonne est inférieure à 0, l'index n'est pas valide.",[56,14427,14429],{"className":214,"code":14428,"language":216,"meta":61,"style":61},"IndexMap::const_iterator it = m_sourcesIndexMapping.constFind( -1 );\n\nQModelIndex sourceParent = mapToSource( parent );\nif( sourceParent.isValid() ) {\n    it = m_sourcesIndexMapping.constFind( sourceParent.row() );\n}\n",[63,14430,14431,14451,14455,14467,14483,14506],{"__ignoreMap":61},[66,14432,14433,14435,14437,14439,14441,14443,14445,14447,14449],{"class":68,"line":69},[66,14434,13871],{"class":230},[66,14436,378],{"class":223},[66,14438,13664],{"class":240},[66,14440,44],{"class":230},[66,14442,13880],{"class":72},[66,14444,12828],{"class":230},[66,14446,508],{"class":223},[66,14448,461],{"class":114},[66,14450,13634],{"class":230},[66,14452,14453],{"class":68,"line":80},[66,14454,276],{"emptyLinePlaceholder":275},[66,14456,14457,14460,14462,14464],{"class":68,"line":89},[66,14458,14459],{"class":230},"QModelIndex sourceParent ",[66,14461,378],{"class":223},[66,14463,12986],{"class":72},[66,14465,14466],{"class":230},"( parent );\n",[66,14468,14469,14471,14473,14476,14478,14480],{"class":68,"line":279},[66,14470,4791],{"class":223},[66,14472,12828],{"class":230},[66,14474,14475],{"class":240},"sourceParent",[66,14477,44],{"class":230},[66,14479,13785],{"class":72},[66,14481,14482],{"class":230},"() ) {\n",[66,14484,14485,14488,14490,14492,14494,14496,14498,14500,14502,14504],{"class":68,"line":307},[66,14486,14487],{"class":230},"    it ",[66,14489,378],{"class":223},[66,14491,13664],{"class":240},[66,14493,44],{"class":230},[66,14495,13880],{"class":72},[66,14497,12828],{"class":230},[66,14499,14475],{"class":240},[66,14501,44],{"class":230},[66,14503,13864],{"class":72},[66,14505,13903],{"class":230},[66,14507,14508],{"class":68,"line":329},[66,14509,1413],{"class":230},[17,14511,14512,14513,14515,14516,14519],{},"A partir de l'index ",[32,14514,6666],{}," nous retrouvons l'index qui correspond dans\nle modèle source (",[32,14517,14518],{},"sourceParent'). Si l'on ne trouve pas d'index dans le\nmodèle source, nous considérons être sur l'élément racine de notre\narbre. Sinon nous recherchons dans la table de","Mapping'' la structure\nqui correspond.",[56,14521,14523],{"className":214,"code":14522,"language":216,"meta":61,"style":61},"Q_ASSERT( it != m_sourcesIndexMapping.constEnd() );\nif( it.value()->source_rows.count() \u003C= row )\n    return QModelIndex();\n",[63,14524,14525,14541,14570],{"__ignoreMap":61},[66,14526,14527,14529,14531,14533,14535,14537,14539],{"class":68,"line":69},[66,14528,13888],{"class":72},[66,14530,13891],{"class":230},[66,14532,13813],{"class":223},[66,14534,13664],{"class":240},[66,14536,44],{"class":230},[66,14538,13900],{"class":72},[66,14540,13903],{"class":230},[66,14542,14543,14545,14547,14550,14552,14554,14556,14558,14560,14563,14565,14567],{"class":68,"line":80},[66,14544,4791],{"class":223},[66,14546,12828],{"class":230},[66,14548,14549],{"class":240},"it",[66,14551,44],{"class":230},[66,14553,3977],{"class":72},[66,14555,13942],{"class":230},[66,14557,13732],{"class":240},[66,14559,44],{"class":230},[66,14561,14562],{"class":72},"count",[66,14564,590],{"class":230},[66,14566,499],{"class":223},[66,14568,14569],{"class":230}," row )\n",[66,14571,14572,14574,14576],{"class":68,"line":89},[66,14573,1946],{"class":223},[66,14575,12822],{"class":72},[66,14577,543],{"class":230},[17,14579,14580],{},"Nous vérifions le nombre d'élément dans la structure et nous retournons\nun index non valide si l'index demandé va au delà de la taille du\ntableau.",[56,14582,14584],{"className":214,"code":14583,"language":216,"meta":61,"style":61},"return createIndex( row, column, *it );\n",[63,14585,14586],{"__ignoreMap":61},[66,14587,14588,14590,14592,14595,14597],{"class":68,"line":69},[66,14589,13790],{"class":223},[66,14591,14108],{"class":72},[66,14593,14594],{"class":230},"( row, column, ",[66,14596,593],{"class":223},[66,14598,14599],{"class":230},"it );\n",[17,14601,14602,14603,14605,14606,44],{},"Finalement nous retournons l'index créé avec le pointeur vers la\nstructure ",[32,14604,13163],{}," du père en ",[32,14607,14608],{},"internalData",[4389,14610,14611],{"id":6666},"parent()",[17,14613,14614],{},"Cette méthode permet de retourner pour l'index donné du proxy, l'index\ndu parent. Un index invalide n'a pas de parent.",[56,14616,14618],{"className":214,"code":14617,"language":216,"meta":61,"style":61},"if( ! index.isValid() ) return QModelIndex();\n\nMapping * m = static_cast\u003CMapping*>( index.internalPointer() );\n",[63,14619,14620,14642,14646],{"__ignoreMap":61},[66,14621,14622,14624,14626,14628,14630,14632,14634,14636,14638,14640],{"class":68,"line":69},[66,14623,4791],{"class":223},[66,14625,12828],{"class":230},[66,14627,13778],{"class":83},[66,14629,12825],{"class":240},[66,14631,44],{"class":230},[66,14633,13785],{"class":72},[66,14635,12914],{"class":230},[66,14637,13790],{"class":223},[66,14639,12822],{"class":72},[66,14641,543],{"class":230},[66,14643,14644],{"class":68,"line":80},[66,14645,276],{"emptyLinePlaceholder":275},[66,14647,14648,14650,14652,14654,14656,14658,14660,14662,14664,14666,14668,14670,14672],{"class":68,"line":89},[66,14649,13988],{"class":230},[66,14651,593],{"class":223},[66,14653,13308],{"class":230},[66,14655,378],{"class":223},[66,14657,14221],{"class":230},[66,14659,532],{"class":223},[66,14661,13163],{"class":230},[66,14663,13129],{"class":223},[66,14665,12828],{"class":230},[66,14667,13350],{"class":240},[66,14669,44],{"class":230},[66,14671,14236],{"class":72},[66,14673,13903],{"class":230},[17,14675,14676,14677,14680,14681,14683],{},"On récupère la structure de correspondance stockée dans le pointeur\ninterne de l'objet. Cette structure nous donne les informations du\nparent (en effet dans ",[32,14678,14679],{},"internalPointer()",", on stock la structure\n",[32,14682,13163],{}," du parent), et donc l'index dans le modèle source.",[56,14685,14687],{"className":214,"code":14686,"language":216,"meta":61,"style":61},"int sourceRow = m->index;\nif( sourceRow == -1 ) return QModelIndex();\n\nQModelIndex sourceParent = m_sourceModel->index( sourceRow, proxyColumnToSource( 0 ) );\nQModelIndex proxyParent = mapFromSource( sourceParent )\n",[63,14688,14689,14705,14726,14730,14755],{"__ignoreMap":61},[66,14690,14691,14693,14695,14697,14699,14701,14703],{"class":68,"line":69},[66,14692,1899],{"class":223},[66,14694,14304],{"class":230},[66,14696,378],{"class":223},[66,14698,14026],{"class":240},[66,14700,2829],{"class":230},[66,14702,13350],{"class":437},[66,14704,1952],{"class":230},[66,14706,14707,14709,14712,14714,14716,14718,14720,14722,14724],{"class":68,"line":80},[66,14708,4791],{"class":223},[66,14710,14711],{"class":230},"( sourceRow ",[66,14713,9175],{"class":223},[66,14715,2209],{"class":223},[66,14717,461],{"class":114},[66,14719,12855],{"class":230},[66,14721,13790],{"class":223},[66,14723,12822],{"class":72},[66,14725,543],{"class":230},[66,14727,14728],{"class":68,"line":89},[66,14729,276],{"emptyLinePlaceholder":275},[66,14731,14732,14734,14736,14738,14740,14742,14745,14748,14750,14752],{"class":68,"line":279},[66,14733,14459],{"class":230},[66,14735,378],{"class":223},[66,14737,13261],{"class":240},[66,14739,2829],{"class":230},[66,14741,13350],{"class":72},[66,14743,14744],{"class":230},"( sourceRow, ",[66,14746,14747],{"class":72},"proxyColumnToSource",[66,14749,12828],{"class":230},[66,14751,444],{"class":114},[66,14753,14754],{"class":230}," ) );\n",[66,14756,14757,14760,14762,14764],{"class":68,"line":307},[66,14758,14759],{"class":230},"QModelIndex proxyParent ",[66,14761,378],{"class":223},[66,14763,12960],{"class":72},[66,14765,14766],{"class":230},"( sourceParent )\n",[17,14768,14769,14770,14772],{},"On utilise alors notre méthode ",[32,14771,13016],{}," pour retrouver l'index\ndu parent dans le référentiel du proxy.",[56,14774,14776],{"className":214,"code":14775,"language":216,"meta":61,"style":61},"return proxyParent;\n",[63,14777,14778],{"__ignoreMap":61},[66,14779,14780,14782],{"class":68,"line":69},[66,14781,13790],{"class":223},[66,14783,14784],{"class":230}," proxyParent;\n",[4389,14786,14375],{"id":14787},"rowcount",[17,14789,14790,14791,14793],{},"Le but de cette méthode est de retourner le nombre de ligne enfant pour\nun index. Dans le modèle source les indexes n'ont pas d'enfant.Lorsque\nl'index vaut ",[32,14792,14090],{},", cela signifie qu'il faut retourner le\nnombre de ligne pour notre racine.",[56,14795,14797],{"className":214,"code":14796,"language":216,"meta":61,"style":61},"if( index.column() > 0 ) return 0;\n",[63,14798,14799],{"__ignoreMap":61},[66,14800,14801,14803,14805,14807,14809,14811,14813,14815,14817,14819,14821,14823],{"class":68,"line":69},[66,14802,4791],{"class":223},[66,14804,12828],{"class":230},[66,14806,13350],{"class":240},[66,14808,44],{"class":230},[66,14810,14058],{"class":72},[66,14812,590],{"class":230},[66,14814,6157],{"class":223},[66,14816,1949],{"class":114},[66,14818,12855],{"class":230},[66,14820,13790],{"class":223},[66,14822,1949],{"class":114},[66,14824,1952],{"class":230},[17,14826,14827],{},"Seul la première colonne a des enfants.",[56,14829,14831],{"className":214,"code":14830,"language":216,"meta":61,"style":61},"if( ! index.isValid() ) {\n    Mapping * rootMapping = m_sourcesIndexMapping.value( -1 );\n    return rootMapping->source_rows.count();\n",[63,14832,14833,14849,14874],{"__ignoreMap":61},[66,14834,14835,14837,14839,14841,14843,14845,14847],{"class":68,"line":69},[66,14836,4791],{"class":223},[66,14838,12828],{"class":230},[66,14840,13778],{"class":83},[66,14842,12825],{"class":240},[66,14844,44],{"class":230},[66,14846,13785],{"class":72},[66,14848,14482],{"class":230},[66,14850,14851,14853,14855,14858,14860,14862,14864,14866,14868,14870,14872],{"class":68,"line":80},[66,14852,13303],{"class":230},[66,14854,593],{"class":223},[66,14856,14857],{"class":230}," rootMapping ",[66,14859,378],{"class":223},[66,14861,13664],{"class":240},[66,14863,44],{"class":230},[66,14865,3977],{"class":72},[66,14867,12828],{"class":230},[66,14869,508],{"class":223},[66,14871,461],{"class":114},[66,14873,13634],{"class":230},[66,14875,14876,14878,14881,14883,14885,14887,14889],{"class":68,"line":89},[66,14877,1946],{"class":223},[66,14879,14880],{"class":240}," rootMapping",[66,14882,2829],{"class":230},[66,14884,13732],{"class":240},[66,14886,44],{"class":230},[66,14888,14562],{"class":72},[66,14890,543],{"class":230},[17,14892,14893],{},"Pour l'index racine, on récupère le nombre de ligne à la ligne -1 du\nmodèle source.",[56,14895,14897],{"className":214,"code":14896,"language":216,"meta":61,"style":61},"} else {\n    Mapping * parrentMapping = static_cast\u003CMapping*>( index.internalPointer() );\n    int sourceRowIndex = parrentMapping->source_rows.at( index.row() );\n    Mapping * rowMapping = m_sourcesIndexMapping.value( sourceRowIndex );\n\n    return rowMapping->source_rows.count();\n",[63,14898,14899,14907,14936,14966,14986,14990],{"__ignoreMap":61},[66,14900,14901,14903,14905],{"class":68,"line":69},[66,14902,5118],{"class":230},[66,14904,552],{"class":223},[66,14906,555],{"class":230},[66,14908,14909,14911,14913,14916,14918,14920,14922,14924,14926,14928,14930,14932,14934],{"class":68,"line":80},[66,14910,13303],{"class":230},[66,14912,593],{"class":223},[66,14914,14915],{"class":230}," parrentMapping ",[66,14917,378],{"class":223},[66,14919,14221],{"class":230},[66,14921,532],{"class":223},[66,14923,13163],{"class":230},[66,14925,13129],{"class":223},[66,14927,12828],{"class":230},[66,14929,13350],{"class":240},[66,14931,44],{"class":230},[66,14933,14236],{"class":72},[66,14935,13903],{"class":230},[66,14937,14938,14940,14943,14945,14948,14950,14952,14954,14956,14958,14960,14962,14964],{"class":68,"line":89},[66,14939,13087],{"class":223},[66,14941,14942],{"class":230}," sourceRowIndex ",[66,14944,378],{"class":223},[66,14946,14947],{"class":240}," parrentMapping",[66,14949,2829],{"class":230},[66,14951,13732],{"class":240},[66,14953,44],{"class":230},[66,14955,14317],{"class":72},[66,14957,12828],{"class":230},[66,14959,13350],{"class":240},[66,14961,44],{"class":230},[66,14963,13864],{"class":72},[66,14965,13903],{"class":230},[66,14967,14968,14970,14972,14975,14977,14979,14981,14983],{"class":68,"line":279},[66,14969,13303],{"class":230},[66,14971,593],{"class":223},[66,14973,14974],{"class":230}," rowMapping ",[66,14976,378],{"class":223},[66,14978,13664],{"class":240},[66,14980,44],{"class":230},[66,14982,3977],{"class":72},[66,14984,14985],{"class":230},"( sourceRowIndex );\n",[66,14987,14988],{"class":68,"line":307},[66,14989,276],{"emptyLinePlaceholder":275},[66,14991,14992,14994,14997,14999,15001,15003,15005],{"class":68,"line":329},[66,14993,1946],{"class":223},[66,14995,14996],{"class":240}," rowMapping",[66,14998,2829],{"class":230},[66,15000,13732],{"class":240},[66,15002,44],{"class":230},[66,15004,14562],{"class":72},[66,15006,543],{"class":230},[17,15008,15009,15010,15013],{},"Sinon on récupère la structure stockée dans le pointeur interne. Cette\nstructure est celle du parent de notre objet. On récupère à l'aide de la\nméthode ",[32,15011,15012],{},"row()"," de l'index l'emplacement de la ligne source. Cette ligne\nsource nous permet de récupérer la structure de correspondance de notre\nindex, et ainsi le nombre de ligne de notre index.",[56,15015,15016],{"className":214,"code":1413,"language":216,"meta":61,"style":61},[63,15017,15018],{"__ignoreMap":61},[66,15019,15020],{"class":68,"line":69},[66,15021,1413],{"class":230},[4389,15023,14381],{"id":15024},"columncount",[17,15026,15027],{},"Notre modèle ne possède qu'une seule colonne.",[56,15029,15031],{"className":214,"code":15030,"language":216,"meta":61,"style":61},"return 1;\n",[63,15032,15033],{"__ignoreMap":61},[66,15034,15035,15037,15039],{"class":68,"line":69},[66,15036,13790],{"class":223},[66,15038,502],{"class":114},[66,15040,1952],{"class":230},[4389,15042,15044],{"id":15043},"proxycolumntosource","proxyColumnToSource()",[17,15046,15047],{},"Si la colonne du proxy vaut 0, alors on retourne la colonne 1, sinon on\nretourne la colonne -1 : la colonne n'est pas convertible, elle n'existe\npas dans notre proxy.",[56,15049,15051],{"className":214,"code":15050,"language":216,"meta":61,"style":61},"if( proxyColumn == 0 )\n    return list_name;\nreturn -1;\n",[63,15052,15053,15065,15072],{"__ignoreMap":61},[66,15054,15055,15057,15059,15061,15063],{"class":68,"line":69},[66,15056,4791],{"class":223},[66,15058,14067],{"class":230},[66,15060,9175],{"class":223},[66,15062,1949],{"class":114},[66,15064,5021],{"class":230},[66,15066,15067,15069],{"class":68,"line":80},[66,15068,1946],{"class":223},[66,15070,15071],{"class":230}," list_name;\n",[66,15073,15074,15076,15078,15080],{"class":68,"line":89},[66,15075,13790],{"class":223},[66,15077,2209],{"class":223},[66,15079,461],{"class":114},[66,15081,1952],{"class":230},[4389,15083,15085],{"id":15084},"sourcecolumtoproxy","sourceColumToProxy()",[17,15087,15088],{},"Si la colonne source est 1, alors nous convertissons celle-ci en la\ncolonne 0. Sinon la colonne n'existe pas dans notre proxy.",[56,15090,15092],{"className":214,"code":15091,"language":216,"meta":61,"style":61},"if( sourceColumn == list_name )\n    return 0;\nreturn -1;\n",[63,15093,15094,15105,15113],{"__ignoreMap":61},[66,15095,15096,15098,15100,15102],{"class":68,"line":69},[66,15097,4791],{"class":223},[66,15099,14275],{"class":230},[66,15101,9175],{"class":223},[66,15103,15104],{"class":230}," list_name )\n",[66,15106,15107,15109,15111],{"class":68,"line":80},[66,15108,1946],{"class":223},[66,15110,1949],{"class":114},[66,15112,1952],{"class":230},[66,15114,15115,15117,15119,15121],{"class":68,"line":89},[66,15116,13790],{"class":223},[66,15118,2209],{"class":223},[66,15120,461],{"class":114},[66,15122,1952],{"class":230},[12,15124,15126],{"id":15125},"les-sources","Les sources",[17,15128,15129],{},"Vous pouvez trouver les sources suivants décrivants ce que l'on trouve\nci-dessus :",[162,15131,15132,15138],{},[165,15133,15134],{},[39,15135,15137],{"href":15136},"\u002FProgrammation\u002Fqt-transformation-d-une-vue-tableau-en-une-vue-hierarchique\u002Fcategoryitemmodel.h","categoryitemmodel.h",[165,15139,15140],{},[39,15141,15143],{"href":15142},"\u002FProgrammation\u002Fqt-transformation-d-une-vue-tableau-en-une-vue-hierarchique\u002Fcategoryitemmodel.cpp","categoryitemmodel.cpp",[17,15145,15146],{},"l'objet QSortFilterProxyModel de Nokia.",[3349,15148,15150,15153],{"className":15149,"dataFootnotes":61},[3352],[1432,15151,3357],{"className":15152,"id":1613},[3356],[3359,15154,15155],{},[165,15156,15157,15158],{"id":3363},"La construction de notre objet s'est basé sur l'analyse de ",[39,15159,3371],{"href":3367,"ariaLabel":3368,"className":15160,"dataFootnoteBackref":61},[3370],[1545,15162,15163],{},"html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .s_ZVi, html code.shiki .s_ZVi{--shiki-default:#E06C75;--shiki-default-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}",{"title":61,"searchDepth":80,"depth":80,"links":15165},[15166,15167,15168,15169,15170],{"id":12723,"depth":89,"text":12724},{"id":12777,"depth":89,"text":12778},{"id":13060,"depth":89,"text":13061},{"id":15125,"depth":89,"text":15126},{"id":1613,"depth":80,"text":3357},"2009-09-21",{"type":9,"value":15173},[15174,15176,15180,15182],[17,15175,12685],{},[17,15177,15178],{},[1445,15179],{"alt":12690,"src":12691},[17,15181,12694],{},[17,15183,15184],{},[1445,15185],{"alt":12699,"src":12700},{},"\u002Fpost\u002Fqt-transformation-d-une-vue-tableau-en-une-vue-hierarchique",{"title":12680,"description":12685},"qt-transformation-d-une-vue-tableau-en-une-vue-hierarchique","posts\u002FProgrammation\u002F2009-09-21-qt-transformation-d-une-vue-tableau-en-une-vue-hierarchique",[1592],"9hW60XZGhuixfVazFGe6eySQJPcsFBX02vlKbBhDNJs",{"id":15194,"title":15195,"author":7,"body":15196,"category":1560,"categorySlug":1561,"date":16366,"description":15200,"excerpt":16367,"extension":1584,"location":1585,"meta":16375,"navigation":275,"path":16376,"published":275,"seo":16377,"slug":16378,"stem":16379,"tags":16380,"timeToRead":334,"__hash__":16381},"posts\u002Fposts\u002FProgrammation\u002F2009-05-31-parseur-xml.md","Parseur XML",{"type":9,"value":15197,"toc":16360},[15198,15201,15208,15211,15215,15218,15221,15224,15227,15231,15234,15237,15281,15290,15434,15437,15440,15443,15449,15453,15456,15470,15473,15477,15490,15493,15499,15502,15508,15511,15515,15518,15521,16174,16188,16191,16197,16200,16337,16357],[17,15199,15200],{},"Bonjours à tous,",[17,15202,15203,15204,15207],{},"L'utilisation des fichiers XML est, à ce jour, un fait dans la plupart\ndes logiciels et est fortement à la mode. Une entreprise qui ne fait pas\nun peu de XML est souvent ",[32,15205,15206],{},"has-been",". On utilise alors le XML à bon ou\nmauvais escient.",[1545,15209,15210],{},"\nth {background-color: #E4E4E4;weigh: bold;}\n .veryslow {background-color: #FF0000;}\n .slow {background-color: #FF8686;}\n .good {background-color: #C3FFC7;}\n .ignored {background-color: #E4E4E4;}\n",[12,15212,15214],{"id":15213},"avantages-inconvénients","Avantages \u002F Inconvénients",[17,15216,15217],{},"Pourquoi utiliser les fichiers XML ? Les fichiers XML sont, pour\ncommencer, des fichiers textes, il seront donc toujours lisibles, ce qui\ngarantit une meilleur pérennité de l'information. Les fichiers XML sont\nstructurés hiérarchiquement et suivent une syntaxe stricte. Ainsi le XML\nest lisible informatiquement par les différents langages de\nprogrammation existant, pour organiser vos données, en utilisant\ndifférents niveaux. Les fichiers XML peuvent être commenté ce qui peut\naméliorer la lisibilité pour un humain.",[17,15219,15220],{},"Le gros inconvénient du XML est sa verbosité. Pour chaque noeud dans la\nhiérarchie, il y a une balise de début, et une balise de fin contenant\nle nom de la balise. Le fichier est moins compact que s'il avait été\nécrit en binaire. Cela peut poser des problèmes comme alourdir les\ncommunications réseaux (ex: pour les webservices). Le fichier est aussi\nplus long à lire qu'un fichier binaire et peut contenir des erreurs.",[17,15222,15223],{},"Si le fichier n'a pas besoin d'être hiérarchique, il est possible\nd'utiliser une structure de fichier INI pour ses données.",[17,15225,15226],{},"Nous nous arrêterons là pour les avantages\u002Finconvénients. L'utilisation\nou non d'un fichier XML est ensuite une question (besoin, éthique, ...)\nà se poser pour ses données et la nécessité de pouvoir les lire\nautrement que par le programme lui-même.",[12,15228,15230],{"id":15229},"performance-des-parseurs","Performance des parseurs.",[17,15232,15233],{},"Je me suis amusé à effectuer le test de lecture de différents fichiers\nde donnée au format XML de taille différentes par une variété de parseur\nXML en construisant si possible un arbre DOM. Le but est donc de créer\nun objet par noeud\u002Fattribut du fichier XML et de reconstituer la\nhiérarchie.",[17,15235,15236],{},"Les parseurs choisis pour ce test sont :",[162,15238,15239,15245,15251,15257,15263,15269,15275],{},[165,15240,15241,15244],{},[1534,15242,15243],{},"QtXml"," : Le module XML de la librairie Qt (de la société Nokia)",[165,15246,15247,15250],{},[1534,15248,15249],{},"LibXml2"," : Une librairie C permettant de faire du parsing XML en\nutilisant DOM ou SAX",[165,15252,15253,15256],{},[1534,15254,15255],{},"LibExpat"," : Un parseur orienté flux (plus proche de la méthode\nSAX que du DOM)",[165,15258,15259,15262],{},[1534,15260,15261],{},"SCEW"," : Un parseur basé sur Expat générant un arbre DOM (donc un\npeu plus comparable aux autre parseur).",[165,15264,15265,15268],{},[1534,15266,15267],{},"TinyXML"," : Encore un autre parseur XML",[165,15270,15271,15274],{},[1534,15272,15273],{},"Xerces-C++"," : Le parseur XML d’Apache",[165,15276,15277,15280],{},[1534,15278,15279],{},"Oracle XML Parser"," : Le parseur d’Oracle propriétaire utiliser\ndans le serveur d’application.",[17,15282,15283,15284,15289],{},"Pour faire cette suite de benchmark",[1607,15285,15286],{},[39,15287,461],{"href":1611,"ariaDescribedBy":15288,"dataFootnoteRef":61,"id":1614},[1613],", j’ai utilisé la librairie\nQTestLib de Nokia\u002FQt. Je vous offre donc en avant première le résultat\nde ce test :",[8428,15291,15293,15297],{"style":15292},"width:100%",[15294,15295,15296],"caption",{},"Temps de lecture d'un fichier XML en ms",[8443,15298,15299,15315,15333,15352,15371,15386,15402,15420],{},[8434,15300,15301,15304,15307,15308,15311,15312,15307],{},[8448,15302,15303],{},"               ",[8437,15305,15306],{},"250k","                     ",[8437,15309,15310],{},"9300k","                      ",[8437,15313,15314],{},"11300k",[8434,15316,15317,15320,15325,15329],{},[8437,15318,15319],{},"Qt DOM         ",[8448,15321,15324],{"className":15322},[15323],"veryslow","41,42 ms",[8448,15326,15328],{"className":15327},[15323],"2184,34 ms",[8448,15330,15332],{"className":15331},[15323],"2648,71 ms",[8434,15334,15335,15338,15341,15342,15347,15348,15347],{},[8437,15336,15337],{},"LibXML2        ",[8448,15339,15340],{},"16,55 ms","                 ",[8448,15343,15346],{"className":15344},[15345],"good","710,09 ms","     ",[8448,15349,15351],{"className":15350},[15345],"874,42 ms",[8434,15353,15354,15357,15362,15363,15362,15367,15362],{},[8437,15355,15356],{},"Expat (SAX)    ",[8448,15358,15361],{"className":15359},[15360],"ignored","5,95 ms","  ",[8448,15364,15366],{"className":15365},[15360],"312,02 ms",[8448,15368,15370],{"className":15369},[15360],"393,58 ms",[8434,15372,15373,15376,15341,15379,15382,15383,15341],{},[8437,15374,15375],{},"Oracle         ",[8448,15377,15378],{},"23,24 ms",[8448,15380,15381],{},"928,93 ms","                  ",[8448,15384,15385],{},"1135,86 ms",[8434,15387,15388,15391,15395,15396,15382,15399,15341],{},[8437,15389,15390],{},"Scew           ",[8448,15392,15394],{"className":15393},[15345],"12,05 ms","    ",[8448,15397,15398],{},"944,37 ms",[8448,15400,15401],{},"1184,46 ms",[8434,15403,15404,15407,15395,15412,15347,15416,15347],{},[8437,15405,15406],{},"Tiny XML       ",[8448,15408,15411],{"className":15409},[15410],"slow","28,91 ms",[8448,15413,15415],{"className":15414},[15410],"1101,8 ms",[8448,15417,15419],{"className":15418},[15410],"1369,8 ms",[8434,15421,15422,15425,15341,15428,15382,15431,15382],{},[8437,15423,15424],{},"Xerces (Apache)",[8448,15426,15427],{},"25,03 ms",[8448,15429,15430],{},"742,22 ms",[8448,15432,15433],{},"904,62 ms",[17,15435,15436],{},"La conclusion de ce résultat signifie que le parseur inclu dans Qt (pour\nla construction d'un arbre DOM) est très lent ;). Mais pour une\nutilisation dans une interface graphique, sur de petits fichiers, ne\ndevrait pas poser de problème.",[17,15438,15439],{},"Enfin le parseur le plus rapide (pour les gros fichiers) est Libxml2. Le\nparseur C d'oracle, bien que propriétaire n'a rien d'exceptionnel (si on\ncompte avec les problèmes présenté également ci-dessous). Peut-être que\nla version Java est elle plus performante.",[17,15441,15442],{},"Vous pouvez retrouver quelques graphiques ci-dessous :",[17,15444,15445],{},[1445,15446],{"alt":15447,"src":15448},"TestXMLPerf","\u002FProgrammation\u002Fparseur-xml\u002FTestXMLPerf.png",[12,15450,15452],{"id":15451},"le-source-du-benchmark","Le source du benchmark",[17,15454,15455],{},"Voici de suite :",[162,15457,15458,15464],{},[165,15459,15460],{},[39,15461,15463],{"href":15462},"\u002FProgrammation\u002Fparseur-xml\u002Fxmlparser-bench.7z","les sources de l'application",[165,15465,15466,44],{},[39,15467,15469],{"href":15468},"\u002FProgrammation\u002Fparseur-xml\u002Fbenchmark_100iterations.ods","le résultat du bench",[17,15471,15472],{},"Pour la partie utilisation du Parseur Oracle, il a fallut contourner\nplusieurs petits problèmes. Ceci est la joie des librairies propriétaires\nbien documentées.",[4389,15474,15476],{"id":15475},"compilation-avec-le-xdk-9","Compilation avec le XDK 9",[17,15478,15479,15480,15483,15484,15487,15488,44],{},"Lors de la compilation avec le XDK 9, l'application ne dépasse pas le\nstade du ",[32,15481,15482],{},"linkage",". Les méthodes sont pourtant bien dans les ",[32,15485,15486],{},"includes",".\nDe plus les librairies sont bien précisées pour le ",[32,15489,15482],{},[17,15491,15492],{},"La définition faite dans le projet est :",[56,15494,15497],{"className":15495,"code":15496,"language":840},[838],"XDKPATH = xdk9\nXDK_LIB = -lxmlg9 -lxml9 -lxsd9\nORA_LIB = -lcore9 -lnls9 -lunls9 -lcore9 -lnls9 -lcore9\nNET_LIB = -lnsl\nLIBS += -L$$XDKPATH\u002Flib $$XDK_LIB $$ORA_LIB $$NET_LIB -lpthread\nINCLUDEPATH += $$XDKPATH\u002Fxdk\u002Finclude\n",[63,15498,15496],{"__ignoreMap":61},[17,15500,15501],{},"A la suite de ça, lors de la phase de compilation, on se retrouve avec\nles messages d'erreurs suivants :",[56,15503,15506],{"className":15504,"code":15505,"language":840},[838],"g++ -Wl,-O1 -o xmlparserbenchmark libxml2parser.o expatparser.o xercescppparser.o oracleparser.o qtparser.o scewparser.o tinyparser.o tinyxml.o tinystr.o tinyxmlerror.o tinyxmlparser.o xmlparserbenchmark.o moc_xmlparserbenchmark.o -L\u002Fusr\u002Flib -lxml2 -lexpat -lxerces-c -Lxdk9\u002Flib -lxmlg9 -lxml9 -lxsd9 -lcore9 -lnls9 -lunls9 -lcore9 -lnls9 -lcore9 -lnsl -lpthread -Lscew\u002Fscew -lscew -lQtTest -lQtXml -lQtGui -lQtCore -lpthread\noracleparser.o: In function `parseWithOracleParser(QString const&)':\noracleparser.cpp:(.text+0x82): undefined reference to `XMLParser::xmlinit(unsigned char*, void (*)(void*, unsigned char const*, unsigned int), void*, xmlsaxcb*, void*, unsigned char*)'\noracleparser.cpp:(.text+0xa8): undefined reference to `XMLParser::xmlparse(unsigned char*, unsigned char*, unsigned int)'\noracleparser.cpp:(.text+0x2b4): undefined reference to `XMLParser::getDocumentElement()'\noracleparser.cpp:(.text+0x2ca): undefined reference to `XMLParser::xmlterm()'\n",[63,15507,15505],{"__ignoreMap":61},[17,15509,15510],{},"J'ai alors essayé de recompiler les exemples de démonstrations mais là,\nmême problème ...",[4389,15512,15514],{"id":15513},"compilation-avec-le-xdk-10","Compilation avec le XDK 10",[17,15516,15517],{},"Avec cette version du XDK, nous avons le droit à deux problèmes. Le\npremier est une grosse fuite mémoire (si on écrit le programme tel que\ndécrit dans la démo), et à un problème d'initialisation du parseur.",[17,15519,15520],{},"Le code permettant de parser le fichier XML et de générer l'arbre DOM\nressemble à ceci :",[56,15522,15524],{"className":214,"code":15523,"language":216,"meta":61,"style":61},"CXmlCtx * ctxp = 0;\ntry {\n    ctxp = new CXmlCtx();\n} catch( XmlException & e ) {\n    unsigned ecode = e.getCode();\n    QFAIL( qPrintable( QString(\"Failed to initialize XML context, error %1\").arg( ecode ) ) );\n}\n\nFactory\u003CCXmlCtx,xmlnode> * fp = 0;\ntry {\n    fp = new Factory\u003CCXmlCtx,xmlnode>( ctxp );\n} catch( FactoryException & fe ) {\n    unsigned ecode = fe.getCode();\n    QFAIL( qPrintable( QString(\"Failed to create create parser, error %1\").arg( ecode ) ) );\n}\n\nDOMParser\u003CCXmlCtx,xmlnode> * parserp = 0;\ntry {\n    parserp = fp->createDOMParser( DOMParCXml, NULL );\n} catch( FactoryException & fe ) {\n    delete fp;\n    unsigned ecode = fe.getCode();\n    QFAIL( qPrintable( QString(\"Failed to create parser, error %1\").arg( ecode ) ) );\n}\n\nconst char * fname = filename;\nFileSource * isrcp = new FileSource( (oratext*) fname );\ntry {\n    DocumentRef\u003Cxmlnode> * docrefp = parserp->parse( isrcp, FALSE );\n    if( docrefp == NULL ) {\n        QFAIL( qPrintable( QString(\"NULL document\") ) );\n        return;\n    }\n    xmlnode * np = docrefp->getDocumentElement();\n    if( np == NULL ) {\n        QFAIL( qPrintable( QString(\"Empty document\") ) );\n        return;\n    }\n    docrefp->markToDelete();\n    delete docrefp;\n} catch( ParserException & pe ) {\n    delete parserp;\n    delete isrcp;\n    delete fp;\n\n    unsigned ecode = pe.getCode();\n    QFAIL( qPrintable( QString( \"Failed to parse the document, error %1\").arg( ecode ) ) );\n}\n\u002F\u002F    delete parserp;\n\u002F\u002F    delete isrcp;\n\u002F\u002F    delete fp;\n\u002F\u002F    delete ctxp;\n",[63,15525,15526,15542,15549,15563,15578,15598,15625,15629,15633,15656,15662,15687,15701,15718,15741,15745,15749,15771,15777,15800,15812,15820,15836,15859,15863,15867,15884,15909,15915,15944,15958,15979,15985,15989,16011,16024,16043,16049,16053,16065,16072,16086,16093,16100,16106,16110,16127,16150,16154,16159,16164,16169],{"__ignoreMap":61},[66,15527,15528,15531,15533,15536,15538,15540],{"class":68,"line":69},[66,15529,15530],{"class":230},"CXmlCtx ",[66,15532,593],{"class":223},[66,15534,15535],{"class":230}," ctxp ",[66,15537,378],{"class":223},[66,15539,1949],{"class":114},[66,15541,1952],{"class":230},[66,15543,15544,15547],{"class":68,"line":80},[66,15545,15546],{"class":223},"try",[66,15548,555],{"class":230},[66,15550,15551,15554,15556,15558,15561],{"class":68,"line":89},[66,15552,15553],{"class":230},"    ctxp ",[66,15555,378],{"class":223},[66,15557,2811],{"class":223},[66,15559,15560],{"class":72}," CXmlCtx",[66,15562,543],{"class":230},[66,15564,15565,15567,15570,15573,15575],{"class":68,"line":279},[66,15566,5118],{"class":230},[66,15568,15569],{"class":223},"catch",[66,15571,15572],{"class":230},"( XmlException ",[66,15574,244],{"class":83},[66,15576,15577],{"class":230}," e ) {\n",[66,15579,15580,15583,15586,15588,15591,15593,15596],{"class":68,"line":307},[66,15581,15582],{"class":223},"    unsigned",[66,15584,15585],{"class":230}," ecode ",[66,15587,378],{"class":223},[66,15589,15590],{"class":240}," e",[66,15592,44],{"class":230},[66,15594,15595],{"class":72},"getCode",[66,15597,543],{"class":230},[66,15599,15600,15603,15605,15608,15610,15612,15614,15617,15619,15622],{"class":68,"line":329},[66,15601,15602],{"class":72},"    QFAIL",[66,15604,12828],{"class":230},[66,15606,15607],{"class":72},"qPrintable",[66,15609,12828],{"class":230},[66,15611,5996],{"class":72},[66,15613,231],{"class":230},[66,15615,15616],{"class":76},"\"Failed to initialize XML context, error %1\"",[66,15618,1640],{"class":230},[66,15620,15621],{"class":72},"arg",[66,15623,15624],{"class":230},"( ecode ) ) );\n",[66,15626,15627],{"class":68,"line":334},[66,15628,1413],{"class":230},[66,15630,15631],{"class":68,"line":340},[66,15632,276],{"emptyLinePlaceholder":275},[66,15634,15635,15638,15640,15643,15645,15647,15650,15652,15654],{"class":68,"line":355},[66,15636,15637],{"class":230},"Factory",[66,15639,532],{"class":223},[66,15641,15642],{"class":230},"CXmlCtx,xmlnode",[66,15644,6157],{"class":223},[66,15646,620],{"class":223},[66,15648,15649],{"class":230}," fp ",[66,15651,378],{"class":223},[66,15653,1949],{"class":114},[66,15655,1952],{"class":230},[66,15657,15658,15660],{"class":68,"line":372},[66,15659,15546],{"class":223},[66,15661,555],{"class":230},[66,15663,15664,15667,15669,15671,15674,15676,15679,15681,15684],{"class":68,"line":395},[66,15665,15666],{"class":230},"    fp ",[66,15668,378],{"class":223},[66,15670,2811],{"class":223},[66,15672,15673],{"class":72}," Factory",[66,15675,532],{"class":230},[66,15677,15678],{"class":240},"CXmlCtx",[66,15680,13151],{"class":230},[66,15682,15683],{"class":240},"xmlnode",[66,15685,15686],{"class":230},">( ctxp );\n",[66,15688,15689,15691,15693,15696,15698],{"class":68,"line":400},[66,15690,5118],{"class":230},[66,15692,15569],{"class":223},[66,15694,15695],{"class":230},"( FactoryException ",[66,15697,244],{"class":83},[66,15699,15700],{"class":230}," fe ) {\n",[66,15702,15703,15705,15707,15709,15712,15714,15716],{"class":68,"line":416},[66,15704,15582],{"class":223},[66,15706,15585],{"class":230},[66,15708,378],{"class":223},[66,15710,15711],{"class":240}," fe",[66,15713,44],{"class":230},[66,15715,15595],{"class":72},[66,15717,543],{"class":230},[66,15719,15720,15722,15724,15726,15728,15730,15732,15735,15737,15739],{"class":68,"line":421},[66,15721,15602],{"class":72},[66,15723,12828],{"class":230},[66,15725,15607],{"class":72},[66,15727,12828],{"class":230},[66,15729,5996],{"class":72},[66,15731,231],{"class":230},[66,15733,15734],{"class":76},"\"Failed to create create parser, error %1\"",[66,15736,1640],{"class":230},[66,15738,15621],{"class":72},[66,15740,15624],{"class":230},[66,15742,15743],{"class":68,"line":485},[66,15744,1413],{"class":230},[66,15746,15747],{"class":68,"line":490},[66,15748,276],{"emptyLinePlaceholder":275},[66,15750,15751,15754,15756,15758,15760,15762,15765,15767,15769],{"class":68,"line":520},[66,15752,15753],{"class":230},"DOMParser",[66,15755,532],{"class":223},[66,15757,15642],{"class":230},[66,15759,6157],{"class":223},[66,15761,620],{"class":223},[66,15763,15764],{"class":230}," parserp ",[66,15766,378],{"class":223},[66,15768,1949],{"class":114},[66,15770,1952],{"class":230},[66,15772,15773,15775],{"class":68,"line":546},[66,15774,15546],{"class":223},[66,15776,555],{"class":230},[66,15778,15779,15782,15784,15787,15789,15792,15795,15798],{"class":68,"line":558},[66,15780,15781],{"class":230},"    parserp ",[66,15783,378],{"class":223},[66,15785,15786],{"class":240}," fp",[66,15788,2829],{"class":230},[66,15790,15791],{"class":72},"createDOMParser",[66,15793,15794],{"class":230},"( DOMParCXml, ",[66,15796,15797],{"class":114},"NULL",[66,15799,13634],{"class":230},[66,15801,15802,15804,15806,15808,15810],{"class":68,"line":607},[66,15803,5118],{"class":230},[66,15805,15569],{"class":223},[66,15807,15695],{"class":230},[66,15809,244],{"class":83},[66,15811,15700],{"class":230},[66,15813,15814,15817],{"class":68,"line":645},[66,15815,15816],{"class":223},"    delete",[66,15818,15819],{"class":230}," fp;\n",[66,15821,15822,15824,15826,15828,15830,15832,15834],{"class":68,"line":653},[66,15823,15582],{"class":223},[66,15825,15585],{"class":230},[66,15827,378],{"class":223},[66,15829,15711],{"class":240},[66,15831,44],{"class":230},[66,15833,15595],{"class":72},[66,15835,543],{"class":230},[66,15837,15838,15840,15842,15844,15846,15848,15850,15853,15855,15857],{"class":68,"line":1278},[66,15839,15602],{"class":72},[66,15841,12828],{"class":230},[66,15843,15607],{"class":72},[66,15845,12828],{"class":230},[66,15847,5996],{"class":72},[66,15849,231],{"class":230},[66,15851,15852],{"class":76},"\"Failed to create parser, error %1\"",[66,15854,1640],{"class":230},[66,15856,15621],{"class":72},[66,15858,15624],{"class":230},[66,15860,15861],{"class":68,"line":1301},[66,15862,1413],{"class":230},[66,15864,15865],{"class":68,"line":1320},[66,15866,276],{"emptyLinePlaceholder":275},[66,15868,15869,15871,15874,15876,15879,15881],{"class":68,"line":1328},[66,15870,234],{"class":223},[66,15872,15873],{"class":223}," char",[66,15875,620],{"class":223},[66,15877,15878],{"class":230}," fname ",[66,15880,378],{"class":223},[66,15882,15883],{"class":230}," filename;\n",[66,15885,15886,15889,15891,15894,15896,15898,15901,15904,15906],{"class":68,"line":1367},[66,15887,15888],{"class":230},"FileSource ",[66,15890,593],{"class":223},[66,15892,15893],{"class":230}," isrcp ",[66,15895,378],{"class":223},[66,15897,2811],{"class":223},[66,15899,15900],{"class":72}," FileSource",[66,15902,15903],{"class":230},"( (oratext",[66,15905,593],{"class":223},[66,15907,15908],{"class":230},") fname );\n",[66,15910,15911,15913],{"class":68,"line":1398},[66,15912,15546],{"class":223},[66,15914,555],{"class":230},[66,15916,15917,15920,15922,15924,15926,15928,15931,15933,15936,15938,15941],{"class":68,"line":1405},[66,15918,15919],{"class":230},"    DocumentRef",[66,15921,532],{"class":223},[66,15923,15683],{"class":230},[66,15925,6157],{"class":223},[66,15927,620],{"class":223},[66,15929,15930],{"class":230}," docrefp ",[66,15932,378],{"class":223},[66,15934,15935],{"class":240}," parserp",[66,15937,2829],{"class":230},[66,15939,15940],{"class":72},"parse",[66,15942,15943],{"class":230},"( isrcp, FALSE );\n",[66,15945,15946,15948,15951,15953,15956],{"class":68,"line":1410},[66,15947,493],{"class":223},[66,15949,15950],{"class":230},"( docrefp ",[66,15952,9175],{"class":223},[66,15954,15955],{"class":114}," NULL",[66,15957,13404],{"class":230},[66,15959,15960,15963,15965,15967,15969,15971,15973,15976],{"class":68,"line":3174},[66,15961,15962],{"class":72},"        QFAIL",[66,15964,12828],{"class":230},[66,15966,15607],{"class":72},[66,15968,12828],{"class":230},[66,15970,5996],{"class":72},[66,15972,231],{"class":230},[66,15974,15975],{"class":76},"\"NULL document\"",[66,15977,15978],{"class":230},") ) );\n",[66,15980,15981,15983],{"class":68,"line":3180},[66,15982,523],{"class":223},[66,15984,1952],{"class":230},[66,15986,15987],{"class":68,"line":3186},[66,15988,656],{"class":230},[66,15990,15991,15994,15996,15999,16001,16004,16006,16009],{"class":68,"line":3192},[66,15992,15993],{"class":230},"    xmlnode ",[66,15995,593],{"class":223},[66,15997,15998],{"class":230}," np ",[66,16000,378],{"class":223},[66,16002,16003],{"class":240}," docrefp",[66,16005,2829],{"class":230},[66,16007,16008],{"class":72},"getDocumentElement",[66,16010,543],{"class":230},[66,16012,16013,16015,16018,16020,16022],{"class":68,"line":3198},[66,16014,493],{"class":223},[66,16016,16017],{"class":230},"( np ",[66,16019,9175],{"class":223},[66,16021,15955],{"class":114},[66,16023,13404],{"class":230},[66,16025,16026,16028,16030,16032,16034,16036,16038,16041],{"class":68,"line":3204},[66,16027,15962],{"class":72},[66,16029,12828],{"class":230},[66,16031,15607],{"class":72},[66,16033,12828],{"class":230},[66,16035,5996],{"class":72},[66,16037,231],{"class":230},[66,16039,16040],{"class":76},"\"Empty document\"",[66,16042,15978],{"class":230},[66,16044,16045,16047],{"class":68,"line":3210},[66,16046,523],{"class":223},[66,16048,1952],{"class":230},[66,16050,16051],{"class":68,"line":3216},[66,16052,656],{"class":230},[66,16054,16055,16058,16060,16063],{"class":68,"line":3222},[66,16056,16057],{"class":240},"    docrefp",[66,16059,2829],{"class":230},[66,16061,16062],{"class":72},"markToDelete",[66,16064,543],{"class":230},[66,16066,16067,16069],{"class":68,"line":3228},[66,16068,15816],{"class":223},[66,16070,16071],{"class":230}," docrefp;\n",[66,16073,16074,16076,16078,16081,16083],{"class":68,"line":3234},[66,16075,5118],{"class":230},[66,16077,15569],{"class":223},[66,16079,16080],{"class":230},"( ParserException ",[66,16082,244],{"class":83},[66,16084,16085],{"class":230}," pe ) {\n",[66,16087,16088,16090],{"class":68,"line":3239},[66,16089,15816],{"class":223},[66,16091,16092],{"class":230}," parserp;\n",[66,16094,16095,16097],{"class":68,"line":3245},[66,16096,15816],{"class":223},[66,16098,16099],{"class":230}," isrcp;\n",[66,16101,16102,16104],{"class":68,"line":3251},[66,16103,15816],{"class":223},[66,16105,15819],{"class":230},[66,16107,16108],{"class":68,"line":3257},[66,16109,276],{"emptyLinePlaceholder":275},[66,16111,16112,16114,16116,16118,16121,16123,16125],{"class":68,"line":3263},[66,16113,15582],{"class":223},[66,16115,15585],{"class":230},[66,16117,378],{"class":223},[66,16119,16120],{"class":240}," pe",[66,16122,44],{"class":230},[66,16124,15595],{"class":72},[66,16126,543],{"class":230},[66,16128,16129,16131,16133,16135,16137,16139,16141,16144,16146,16148],{"class":68,"line":3269},[66,16130,15602],{"class":72},[66,16132,12828],{"class":230},[66,16134,15607],{"class":72},[66,16136,12828],{"class":230},[66,16138,5996],{"class":72},[66,16140,12828],{"class":230},[66,16142,16143],{"class":76},"\"Failed to parse the document, error %1\"",[66,16145,1640],{"class":230},[66,16147,15621],{"class":72},[66,16149,15624],{"class":230},[66,16151,16152],{"class":68,"line":3275},[66,16153,1413],{"class":230},[66,16155,16156],{"class":68,"line":3281},[66,16157,16158],{"class":351},"\u002F\u002F    delete parserp;\n",[66,16160,16161],{"class":68,"line":3287},[66,16162,16163],{"class":351},"\u002F\u002F    delete isrcp;\n",[66,16165,16166],{"class":68,"line":3293},[66,16167,16168],{"class":351},"\u002F\u002F    delete fp;\n",[66,16170,16171],{"class":68,"line":3299},[66,16172,16173],{"class":351},"\u002F\u002F    delete ctxp;\n",[17,16175,16176,16177,16179,16180,16182,16183,44],{},"Le premier problème se situe lors de la suppression du contexte\n(dernière ligne, en commentaire). Si cette ligne est exécutée, alors\nnous avons une grosse erreur de segmentation. J'ai le problème, quels\nque soient les ",[63,16178,8608],{}," que je fais avant.Même en faisant le maximum de\n",[63,16181,8608],{}," (soit parserp, isrcp, fp), le fait de ne pas supprimer le\ncontext (ctxp), fait qu'au bout de plusieurs itérations, nous avons une\nbonne fuite mémoire",[1607,16184,16185],{},[39,16186,476],{"href":1637,"ariaDescribedBy":16187,"dataFootnoteRef":61,"id":1639},[1613],[17,16189,16190],{},"Vient ensuite le second problème, celui des erreurs d'intialisation. Si\nle parseur est lancé plusieurs fois de suite, alors l'application\naffiche les erreurs suivantes à l'écran :",[56,16192,16195],{"className":16193,"code":16194,"language":840},[838],"LPX-00202: Message 202 not found; No message file for product=XDK, facility=LPX\nFAIL!  : XmlParserBenchmark::oracleParser(file250k.xml) Failed to parse the document, error 202\n    Loc: [oracleparser.cpp(73)]\n",[63,16196,16194],{"__ignoreMap":61},[17,16198,16199],{},"Aucune explication sur le pourquoi. Parfois ça marche, parfois non...\nPour contourner le problème, j'ai forké le parseur pour l'exécuter isolé\ndu reste.",[56,16201,16204],{"className":16202,"code":16203,"language":7496,"meta":61,"style":61},"language-c shiki shiki-themes one-dark-pro","pid_t pid = fork();\nif( pid > 0 ) {\n    waitpid( pid, (int*)0, 0 );\n} else if( pid == 0 ) {\n    if( ! filename.isEmpty() )\n        parse( qPrintable( filename ) );\n    exit( 0 );\n} else {\n    QFAIL( \"Cannot fork\" );\n}\n",[63,16205,16206,16221,16234,16255,16272,16291,16303,16314,16322,16333],{"__ignoreMap":61},[66,16207,16208,16211,16214,16216,16219],{"class":68,"line":69},[66,16209,16210],{"class":223},"pid_t",[66,16212,16213],{"class":230}," pid ",[66,16215,378],{"class":223},[66,16217,16218],{"class":72}," fork",[66,16220,543],{"class":230},[66,16222,16223,16225,16228,16230,16232],{"class":68,"line":80},[66,16224,4791],{"class":223},[66,16226,16227],{"class":230},"( pid ",[66,16229,6157],{"class":223},[66,16231,1949],{"class":114},[66,16233,13404],{"class":230},[66,16235,16236,16239,16242,16245,16247,16249,16251,16253],{"class":68,"line":89},[66,16237,16238],{"class":72},"    waitpid",[66,16240,16241],{"class":230},"( pid, (",[66,16243,16244],{"class":223},"int*",[66,16246,1295],{"class":230},[66,16248,444],{"class":114},[66,16250,251],{"class":230},[66,16252,444],{"class":114},[66,16254,13634],{"class":230},[66,16256,16257,16259,16261,16264,16266,16268,16270],{"class":68,"line":279},[66,16258,5118],{"class":230},[66,16260,552],{"class":223},[66,16262,16263],{"class":223}," if",[66,16265,16227],{"class":230},[66,16267,9175],{"class":223},[66,16269,1949],{"class":114},[66,16271,13404],{"class":230},[66,16273,16274,16276,16278,16280,16283,16285,16288],{"class":68,"line":307},[66,16275,493],{"class":223},[66,16277,12828],{"class":230},[66,16279,13778],{"class":83},[66,16281,16282],{"class":240}," filename",[66,16284,44],{"class":230},[66,16286,16287],{"class":72},"isEmpty",[66,16289,16290],{"class":230},"() )\n",[66,16292,16293,16296,16298,16300],{"class":68,"line":329},[66,16294,16295],{"class":72},"        parse",[66,16297,12828],{"class":230},[66,16299,15607],{"class":72},[66,16301,16302],{"class":230},"( filename ) );\n",[66,16304,16305,16308,16310,16312],{"class":68,"line":334},[66,16306,16307],{"class":72},"    exit",[66,16309,12828],{"class":230},[66,16311,444],{"class":114},[66,16313,13634],{"class":230},[66,16315,16316,16318,16320],{"class":68,"line":340},[66,16317,5118],{"class":230},[66,16319,552],{"class":223},[66,16321,555],{"class":230},[66,16323,16324,16326,16328,16331],{"class":68,"line":355},[66,16325,15602],{"class":72},[66,16327,12828],{"class":230},[66,16329,16330],{"class":76},"\"Cannot fork\"",[66,16332,13634],{"class":230},[66,16334,16335],{"class":68,"line":372},[66,16336,1413],{"class":230},[3349,16338,16340,16343],{"className":16339,"dataFootnotes":61},[3352],[1432,16341,3357],{"className":16342,"id":1613},[3356],[3359,16344,16345,16351],{},[165,16346,16347,16348],{"id":3363},"Ces tests ont été réalisé dans un chroot 32-bits allant à 2,4GHz. Les temps sont une moyenne sur 100 itérations ",[39,16349,3371],{"href":3367,"ariaLabel":3368,"className":16350,"dataFootnoteBackref":61},[3370],[165,16352,16353,16354],{"id":3374},"Si quelqu'un a déjà utilisé ce parseur, et qu'il sait comment il fonctionne, il peut m'écrire ",[39,16355,3371],{"href":3378,"ariaLabel":3379,"className":16356,"dataFootnoteBackref":61},[3370],[1545,16358,16359],{},"html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":61,"searchDepth":80,"depth":80,"links":16361},[16362,16363,16364,16365],{"id":15213,"depth":89,"text":15214},{"id":15229,"depth":89,"text":15230},{"id":15451,"depth":89,"text":15452},{"id":1613,"depth":80,"text":3357},"2009-05-31",{"type":9,"value":16368},[16369,16371],[17,16370,15200],{},[17,16372,15203,16373,15207],{},[32,16374,15206],{},{},"\u002Fpost\u002Fparseur-xml",{"title":15195,"description":15200},"parseur-xml","posts\u002FProgrammation\u002F2009-05-31-parseur-xml",[9080,1592,5931],"G7dHisiUAKK_MNKBFUElPa66LJWw54bB5Z9U4-7H4Ck",{"id":16383,"title":16384,"author":7,"body":16385,"category":4311,"categorySlug":5899,"date":16557,"description":5624,"excerpt":16558,"extension":1584,"location":1585,"meta":16572,"navigation":275,"path":16573,"published":275,"seo":16574,"slug":16575,"stem":16576,"tags":16577,"timeToRead":279,"__hash__":16578},"posts\u002Fposts\u002FXINX\u002F2009-05-26-xinx-0.8.1.0.md","XINX 0.8.1.0",{"type":9,"value":16386,"toc":16549},[16387,16389,16397,16405,16409,16415,16418,16421,16427,16433,16437,16443,16446,16450,16457,16463,16476,16479,16482,16488,16492,16499,16503,16506,16509,16511,16526,16535],[17,16388,5624],{},[17,16390,16391],{},[8154,16392,16393,16396],{},[1534,16394,16395],{},"Erratum :"," La dernière version est numéroté 0.8.1.1. Un petit\nbug (pouvant être gênant lors de l'ouverture de feuille de style sans\nutilisation du mode projet) a été corrigé dans la foulé. La page est\ncorrigé en conséquence",[17,16398,16399,16400,16404],{},"Je souhaite vous annoncer la sortie de la version ",[16401,16402,16403],"strike",{},"0.8.1.0","\n0.8.1.1 de XINX. Pas d'énorme changement pour vous depuis la version 0.8.0.0\n(sinon nous serions passés à la version 0.9.0.0) mais de gros changements\ninternes.",[12,16406,16408],{"id":16407},"vue-contenue","Vue Contenue",[17,16410,16411],{},[1445,16412],{"alt":16413,"src":16414},"ContentViewDock.png","\u002FXINX\u002Fxinx-0.8.1.0\u002FContentViewDock.png",[17,16416,16417],{},"En fait, la partie gérant la vue contenue a été complètement ré-écrite.\nElle est maintenant parallélisée et partagée entre les différents\néditeurs. Au final l'empreinte mémoire, ainsi que la fluidité a chargé\nles différents fichiers de XINX devrait être amélioré. (Enfin j'espère,\ncar je n'ai pas fait de benchmark). De ce coté le code est lui aussi\nbeaucoup plus propre et plus souple.",[17,16419,16420],{},"XINX étant toujours dans les versions 0.XX, je n'ose vous rappeler que\nce n'est pas ce qu'on appelle une version finie, mais une série de bêta\n;) . Étant donné le peu de test que j'ai pu faire sur cette version en\nparticulier j'aurais dû la nommer en -rc ou en -beta mais je me suis dit\nque cela serait redondant, et que si ça ne convenait pas vous ajouteriez\nun ticket sur ce site pour me prévenir. Enfin j'espère que cette version\nne sera pas trop miner. 😄",[17,16422,16423,16424,16426],{},"La ré-écriture de la partie ",[32,16425,16408],{}," permet donc de préciser dans\nles propriétés du projet quelques fichiers qui seront pré-chargés au\nchargement du projet. Ces fichiers étant pré-chargés, l'ouverture des\nfeuilles de styles devrait être accéléré. Si de votre coté, XINX\nprésente quelques faiblesses, merci de me prévenir. La complétion a\négalement été améliorée (avec la suppression des bug, comme l'affichage\nde balise with-param en double). Lors de vos déplacements dans\nl'éditeur, la vue contenue vous indique votre emplacement dans la vue\ncontenue.",[17,16428,16429],{},[1445,16430],{"alt":16431,"src":16432},"PreloadedFiles.png","\u002FXINX\u002Fxinx-0.8.1.0\u002FPreloadedFiles.png",[12,16434,16436],{"id":16435},"dictionnaire","Dictionnaire",[17,16438,16439],{},[1445,16440],{"alt":16441,"src":16442},"Dictionary.png","\u002FXINX\u002Fxinx-0.8.1.0\u002FDictionary.png",[17,16444,16445],{},"L'autre nouveau point et l'ajout d'un nouveau Dock par l'intermédiaire\ndes plugins. Ce Dock vous propose l'affichage du dictionnaire dans les\nversions GCE130 et GCE140. Pour l'instant le seul intérêt de ce dock est\nl'affichage du dictionnaire à la recherche d'un label. C'est un point de\ndépart pouvant vous servir à faire des tickets sur des améliorations à\napporter. (Celle que j'ai en tête est la gestion de la complétion sur\nles libellés du dictionnaire). Merci de passer par le système de ticket\npour proposer d'autres améliorations sur le DOCK Dictionnaire.",[12,16447,16449],{"id":16448},"pré-visualisation","Pré-visualisation",[17,16451,16452,16453,16456],{},"Enfin, dernière évolution intéressante, est l'affichage de la\npré-visualisation de la page. Cette fonctionnalité est à noter comme\n",[32,16454,16455],{},"extrêmement expérimental",",et n'évoluera peut-être pas (selon les\ndemandes qui sont faites dessus, ainsi que suivant les problèmes\ntechniques rencontrés), et ne fonctionnera peut-être pas avec les\nprochaines versions de GCE. (En version 140, les libellés ne sont pas\nremplacés).",[17,16458,16459],{},[1445,16460],{"alt":16461,"src":16462},"CustomWebPlugin.png","\u002FXINX\u002Fxinx-0.8.1.0\u002FCustomWebPlugin.png",[17,16464,16465,16466,16469,16470,16475],{},"Pour faire fonctionner la prévisualisation, vous devez renseigner\nl'emplacement de la ",[32,16467,16468],{},"ServletControl",", configurer, dans les propriétés du\nplugin WEB, le parseur à utiliser",[1607,16471,16472],{},[39,16473,461],{"href":1611,"ariaDescribedBy":16474,"dataFootnoteRef":61,"id":1614},[1613]," et de configurer le lecteur\n(je vous conseille Webkit).",[17,16477,16478],{},"De là, lors des développements de feuille de style en mode projet, si\nvous sélectionnez un flux de présentation XML (dans le dock associé) et\nappuyé sur F9, vous devriez avoir la prévisualisation de votre feuille\nde style.",[17,16480,16481],{},"Le même principe peut-être appliqué pour une page HTML. Là, pas besoin\nde parseur, ni de flux de présentation. Vous pouvez avoir directement la\nprévisualisation de votre page HTML.",[17,16483,16484],{},[1445,16485],{"alt":16486,"src":16487},"ParseXsl.png","\u002FXINX\u002Fxinx-0.8.1.0\u002FParseXsl.png",[12,16489,16491],{"id":16490},"gestion-des-plugins","Gestion des plugins",[17,16493,16494,16495,16498],{},"Enfin, la gestion des plugins n'a cessé de s'améliorer. Il est de plus\nen plus facile d'étendre ",[32,16496,16497],{},"'XINX","'. Ceci par l'intermédiare de Script ou\nde Plugins. Si une fonctionnalité vous manque, vous pouvez donc non\nseulement la proposer, mais aussi l'écrire en script, ou si le script\nest trop limité, vous pouvez aussi écrire le plugin. Les plugins\npermettent donc d'ajouter des actions à XINX, des Docks, des éditeurs,\ndes gestionnaires de version, des pages de configuration du projet, ...",[12,16500,16502],{"id":16501},"d-bus","D-BUS",[17,16504,16505],{},"Alors que D-BUS avait été ajouté dans les précédentes versions afin de\npermettre une plus grande interopérabilité, ce dernier a été retiré pour\ncette version. Ainsi XINX est maintenant indépendant de D-BUS. Il a été\ndécidé de retirer D-BUS pour plusieurs raisons : Simplification de la\ncompilation, source de problème sous MS\u002FWindows. Il devient maintenant\nbeaucoup plus simple de compiler XINX sous Windows. L'interface avec\nD-BUS reviendra dans une future version mais sera alors optionnel.",[17,16507,16508],{},"Je vous souhaite une bonne installation.",[4389,16510,3716],{"id":3715},[162,16512,16513,16520],{},[165,16514,16515],{},[39,16516,16519],{"href":16517,"rel":16518},"http:\u002F\u002Fxinx.shadoware.org\u002Fdownloads\u002F45",[43],"binaire i386 windows",[165,16521,16522],{},[39,16523,4366],{"href":16524,"rel":16525},"http:\u002F\u002Fxinx.shadoware.org\u002Fdownloads\u002F46",[43],[17,16527,16528,16529,16532],{},"Sous Debian, ajout du dépôt :",[16530,16531],"br",{},[63,16533,16534],{},"deb http:\u002F\u002Fapt.shadoware.org\u002F sid main",[3349,16536,16538,16541],{"className":16537,"dataFootnotes":61},[3352],[1432,16539,3357],{"className":16540,"id":1613},[3356],[3359,16542,16543],{},[165,16544,16545,16546],{"id":3363},"je vous conseille celui d'Oracle, Il est plus long à se lancer mais permet de gérer les noms de domaine Generix. ",[39,16547,3371],{"href":3367,"ariaLabel":3368,"className":16548,"dataFootnoteBackref":61},[3370],{"title":61,"searchDepth":80,"depth":80,"links":16550},[16551,16552,16553,16554,16555,16556],{"id":16407,"depth":89,"text":16408},{"id":16435,"depth":89,"text":16436},{"id":16448,"depth":89,"text":16449},{"id":16490,"depth":89,"text":16491},{"id":16501,"depth":89,"text":16502},{"id":1613,"depth":80,"text":3357},"2009-05-26",{"type":9,"value":16559},[16560,16562,16568],[17,16561,5624],{},[17,16563,16564],{},[8154,16565,16566,16396],{},[1534,16567,16395],{},[17,16569,16399,16570,16404],{},[16401,16571,16403],{},{},"\u002Fpost\u002Fxinx-0.8.1.0",{"title":16384,"description":5624},"xinx-0.8.1.0","posts\u002FXINX\u002F2009-05-26-xinx-0.8.1.0",[5899,5930,1592,5931],"8aKIzfM_YqZZxhEq2D3RIfltjcXI7zx2CQJUUEok8_U",{"id":16580,"title":16581,"author":7,"body":16582,"category":16677,"categorySlug":16678,"date":16679,"description":61,"excerpt":16680,"extension":1584,"location":1585,"meta":16694,"navigation":275,"path":16695,"published":275,"seo":16696,"slug":16697,"stem":16698,"tags":16699,"timeToRead":80,"__hash__":16700},"posts\u002Fposts\u002FLogiciels\u002F2009-05-23-kmymoney-logiciel-de-compte.md","KMyMoney - Logiciel de compte",{"type":9,"value":16583,"toc":16674},[16584,16590,16593,16599,16602,16608,16617,16623,16626,16632,16639,16642,16648,16651,16657,16660],[17,16585,16586],{},[1445,16587],{"alt":16588,"src":16589},"Logo","\u002FLogiciels\u002Fkmymoney-logiciel-de-compte\u002Flogo.png",[17,16591,16592],{},"Voilà un bon logiciel sur lequel on peut compter (mouarf ! mouarf !\nmouarf !), KMyMoney est un éditeur de compte. Je l'utilise\nquotidiennement, et je décide donc d'en parler un peu, pour que d'autres\npersonnes puissent s'intéresser aussi à ce logiciel.",[17,16594,16595],{},[1445,16596],{"alt":16597,"src":16598},"Summary","\u002FLogiciels\u002Fkmymoney-logiciel-de-compte\u002FSummary.png",[17,16600,16601],{},"KMyMoney est un logiciel de gestion de compte pour particulier. Il vous\npermet de gérer plusieurs de vos comptes en banque, en vous permettant\nde saisir les dépenses et les recettes sur chacun de vos comptes.",[17,16603,16604],{},[1445,16605],{"alt":16606,"src":16607},"Registres","\u002FLogiciels\u002Fkmymoney-logiciel-de-compte\u002FRegistres.png",[17,16609,16610,16611,16616],{},"Vous pouvez également lui indiquer vos échéances (par exemple : forfait\ntéléphone, prêt immobilier",[1607,16612,16613],{},[39,16614,461],{"href":1611,"ariaDescribedBy":16615,"dataFootnoteRef":61,"id":1614},[1613],", mais aussi salaire, vos virements\ninternes ou externes, ...) qu'il s'occupera de mettre à jour dans le\nregistre automatiquement ou à votre demande.",[17,16618,16619],{},[1445,16620],{"alt":16621,"src":16622},"Echeancier","\u002FLogiciels\u002Fkmymoney-logiciel-de-compte\u002FEcheancier.png",[17,16624,16625],{},"Après une année d'utilisation, il vous permet également de sortir un\nrapport détaillé sur vos dépenses et vos recettes suivant les catégories\nsaisies pour vos opérations. Cette information peut vous être très utile\npour voir où se trouve le \"trou\" de votre porte monnaie et ainsi\nfaire une rustine. Il vous permet aussi de vous projeter vers l'avenir\net de faire votre budget pour l'année prochaine. KMyMoney vous offre\npour cela, la saisie de votre budget, ainsi que plusieurs rapports\nd'écart, vous permettant ainsi de retrouver facilement où vous avez\nfinalement dépensé plus que le budget prévu, et où vous avez dépensé\nmoins.",[17,16627,16628],{},[1445,16629],{"alt":16630,"src":16631},"Rapport","\u002FLogiciels\u002Fkmymoney-logiciel-de-compte\u002FRapport.png",[17,16633,16634,16635,16638],{},"En plus de vos comptes en banque ",[32,16636,16637],{},"normaux",", KMyMoney vous permet\négalement de gérer vos comptes titre, et les actions que vous y avez\nmises. Vous pouvez alors facilement suivre la chute vertigineuse de la\nbourse et votre portefeuille fondre littéralement, mais aussi la\nremontée (on espère), des actions d'ici quelques ... siècles.",[17,16640,16641],{},"Enfin pour les paranos, vos comptes peuvent être cryptés à l'aide de\nvotre clé GnuPG automatiquement par KMyMoney :)",[17,16643,16644],{},[1445,16645],{"alt":16646,"src":16647},"Cryptage","\u002FLogiciels\u002Fkmymoney-logiciel-de-compte\u002FCryptage.png",[17,16649,16650],{},"Après cette courte présentation, je vous souhaite bon compte ;)",[16652,16653,16654],"blockquote",{},[17,16655,16656],{},"Pour une vie équilibrée, n'oubliez pas de profiter du soleil, au lieu\nde passer votre temps sur votre ordinateur",[17,16658,16659],{},"... en fonction des différents chiffres que vous allez lui entrer.",[3349,16661,16663,16666],{"className":16662,"dataFootnotes":61},[3352],[1432,16664,3357],{"className":16665,"id":1613},[3356],[3359,16667,16668],{},[165,16669,16670,16671],{"id":3363},"Il s'occupera d'ailleurs de calculer la durée des échéances, ",[39,16672,3371],{"href":3367,"ariaLabel":3368,"className":16673,"dataFootnoteBackref":61},[3370],{"title":61,"searchDepth":80,"depth":80,"links":16675},[16676],{"id":1613,"depth":80,"text":3357},"Logiciels","logiciels","2009-05-23",{"type":9,"value":16681},[16682,16686,16688,16692],[17,16683,16684],{},[1445,16685],{"alt":16588,"src":16589},[17,16687,16592],{},[17,16689,16690],{},[1445,16691],{"alt":16597,"src":16598},[17,16693,16601],{},{},"\u002Fpost\u002Fkmymoney-logiciel-de-compte",{"title":16581,"description":61},"kmymoney-logiciel-de-compte","posts\u002FLogiciels\u002F2009-05-23-kmymoney-logiciel-de-compte",[3788,1592],"GMoM34deHfpP44yg0dNX_5SNO5lCcgbkTT8_04fCe6c",{"id":16702,"title":16703,"author":7,"body":16704,"category":16677,"categorySlug":16678,"date":16757,"description":16708,"excerpt":16758,"extension":1584,"location":1585,"meta":16776,"navigation":275,"path":16777,"published":275,"seo":16778,"slug":16779,"stem":16780,"tags":16781,"timeToRead":80,"__hash__":16782},"posts\u002Fposts\u002FLogiciels\u002F2009-04-11-kde4-devient-instable.md","KDE4 devient instable ...",{"type":9,"value":16705,"toc":16755},[16706,16709,16712,16725,16732,16735,16749,16752],[17,16707,16708],{},"Title: KDE4 devient instable ...\nTags: debian, kde, qt",[17,16710,16711],{},"Titre trolleur, cela ne veux pas dire que KDE 4 est moins stable\nqu'avant mais qu'il a passé une étape supplémentaire chez Debian.",[17,16713,16714,16715,16717,16718,16721,16722,44],{},"Voilà quelques jours déjà que la distribution ",[1534,16716,12249],{}," intègre\n",[1534,16719,16720],{},"KDE 4"," dans sa version instable. C'est une grande nouvelle car cela\nva permettre à toute les personnes se trouvant en instable et n'ayant\npas touchées à la branche expérimental de Debian de pouvoir tester ",[1534,16723,16724],{},"KDE\n4",[17,16726,16727,16728,16731],{},"Malheureusement pour les ",[32,16729,16730],{},"traumatisé de KDE 4",", l'intégration de ce\ndernier remplace KDE 3.5 et ne viens pas se positionner en parallèle. Il\nme semble pourtant que lors du passage de KDE 2 à KDE 3, il était\npossible d'avoir les deux bureaux en même temps sur sa machine et de\nswitcher de l'un à l'autre sans difficulté. Cela signifie donc peut-être\naussi la perte d'utilisateur pour KDE sous Gnu\u002FDebian au profit d'un\nautre environnement de bureau.",[17,16733,16734],{},"Afin d'effectuer la migration en douceur, Gnu\u002FDebian propose un\nassistant de migration de KDE du nom de Kaboom. Cet assistant, démarrer\nlors de la première connexion de l'utilisateur et vous propose alors de\nsauvegarder votre ancien dossier de configuration KDE 3 et de migrer le\ndossier .kde vers la version 4.",[17,16736,16737,16741,16745],{},[1445,16738],{"alt":16739,"src":16740},"kaboom1","\u002FLogiciels\u002Fkde4-devient-instable\u002Fkaboom1_s.jpg",[1445,16742],{"alt":16743,"src":16744},"kaboom2","\u002FLogiciels\u002Fkde4-devient-instable\u002Fkaboom2_s.jpg",[1445,16746],{"alt":16747,"src":16748},"kaboom3","\u002FLogiciels\u002Fkde4-devient-instable\u002Fkaboom3_s.jpg",[17,16750,16751],{},"Je viens donc de passer à KDE 4 et m'émerveille des nouvelles\nfonctionnalités de KWin (cube, placement des fenêtres) que je n'avais\npas avant, car n'avait jamais installé Compiz ...",[17,16753,16754],{},"Bonne installation,",{"title":61,"searchDepth":80,"depth":80,"links":16756},[],"2009-04-11",{"type":9,"value":16759},[16760,16762,16764,16772],[17,16761,16708],{},[17,16763,16711],{},[17,16765,16714,16766,16717,16768,16721,16770,44],{},[1534,16767,12249],{},[1534,16769,16720],{},[1534,16771,16724],{},[17,16773,16727,16774,16731],{},[32,16775,16730],{},{},"\u002Fpost\u002Fkde4-devient-instable",{"title":16703,"description":16708},"kde4-devient-instable","posts\u002FLogiciels\u002F2009-04-11-kde4-devient-instable",[1595,3788,1592],"Oj3jqh3sY77Ym6LYJ2tDQUMs5alVjGgGLz0JxRhI7k8",{"id":16784,"title":16785,"author":7,"body":16786,"category":4311,"categorySlug":5899,"date":17198,"description":61,"excerpt":17199,"extension":1584,"location":1585,"meta":17215,"navigation":275,"path":17216,"published":275,"seo":17217,"slug":17218,"stem":17219,"tags":17220,"timeToRead":279,"__hash__":17221},"posts\u002Fposts\u002FXINX\u002F2009-03-06-xinx-0.8.0.0.md","XINX 0.8.0.0",{"type":9,"value":16787,"toc":17191},[16788,16794,16799,16807,16810,16818,16821,16824,16828,16839,16846,16849,16854,16860,16877,16881,16887,16890,16893,16897,16902,16910,17091,17101,17105,17108,17116,17120,17124,17136,17139,17143,17146,17152,17155,17182,17188],[17,16789,16790],{},[1445,16791],{"alt":16792,"src":16793},"Editeur","\u002FXINX\u002Fxinx-0.8.0.0\u002Fediteur_de_texte.png",[17,16795,16796,16797,44],{},"J'ai le plaisir de vous annoncer la sortie de la nouvelle version de\n",[1534,16798,4311],{},[17,16800,16801,16803,16804,44],{},[1534,16802,4311],{}," est un éditeur de projet web basé sur les technologies XSL,\nHTML, CSS, JavaScript. Il possède un mode projet permettant de dériver\nles projets à la manière des consultants GCE de l'entreprise ",[32,16805,16806],{},"Generix\nGroup",[17,16808,16809],{},"Cette dernière version a mis beaucoup de temps pour sortir et est moins\ncomplète que celle que je souhaitais faire à l'origine. Cela viens de\nplusieurs raison :",[162,16811,16812,16815],{},[165,16813,16814],{},"de gros changement interne",[165,16816,16817],{},"moins de temps le soir et le week-end.",[17,16819,16820],{},"La prochaine version 0.8.1 contiendra les développements que je n'ai pu\nmettre dans cette version. N'hésitez pas à faire un retour sur les\nproblèmes que vous rencontrez pour que ces derniers soit également\ncorriger pour la prochaine version.",[17,16822,16823],{},"Nous allons détailler ci-dessous les différentes amélioration incluse\ndans cette version.",[12,16825,16827],{"id":16826},"qcodeedit-le-nouvel-éditeur","QCodeEdit - Le nouvel éditeur",[17,16829,16830,16831,16834,16835,16838],{},"L'éditeur de texte de cette version a complètement été remplacé. On est\npassé de QTextEdit (",[32,16832,16833],{},"éditeur de texte de Qt Software",") à QCodeEdit\n(",[32,16836,16837],{},"Développé par Luc Bruant aka fullmetalcoder","). Heureusement que les\nAPIs de ces deux éditeurs sont très similaire ce qui a permis\nd'effectuer les changements assez rapidement (quelques mois au lieu de\nquelques années ;) ).",[17,16840,16841,16842,16845],{},"Je tiens également à remercier ",[32,16843,16844],{},"fullmetalcoder"," de sa réactivité sur le\ndéveloppement de QCodeEdit.",[17,16847,16848],{},"Les nouveautés qu'apportent ce nouvel éditeur par rapport à QTextEdit\nsont :",[162,16850,16851],{},[165,16852,16853],{},"le folding",[17,16855,16856],{},[1445,16857],{"alt":16858,"src":16859},"Mark","\u002FXINX\u002Fxinx-0.8.0.0\u002Fmarqueur.png",[162,16861,16862,16865,16871,16874],{},[165,16863,16864],{},"les couleurs de fond sur les marque pages et les erreurs (pour une\nplus grande clarté).",[165,16866,16867,16868,1295],{},"un chargement plus rapide des fichiers (exemple :\n",[63,16869,16870],{},"configuration.xml",[165,16872,16873],{},"pourvoir faire des sélections verticales (à l'aide de Ctrl+Shift)\ncomme le font certain éditeurs",[165,16875,16876],{},"afficher les correspondances de parenthèses",[12,16878,16880],{"id":16879},"test-du-xpath","Test du XPATH",[17,16882,16883],{},[1445,16884],{"alt":16885,"src":16886},"X-Quey","\u002FXINX\u002Fxinx-0.8.0.0\u002Fxpath.png",[17,16888,16889],{},"Cette boite de dialogue permet d'exécuter un X-PATH (ou une requête\nXQuery) sur un fichier de présentation. Cela permet de tester rapidement\nles X-PATH compliqué avant de lancer la page sous le navigateur.",[17,16891,16892],{},"Il est possible de saisir des X-PATH relativement à un X-PATH\nsélectionné dans le flux de présentation ou de manière absolu.",[12,16894,16896],{"id":16895},"script-automatique","Script automatique",[17,16898,16899,16901],{},[1534,16900,4311],{}," permet également d'appeler un script lors de la sauvegarde d'un\nfichier. Pour cela un nouvel objet permettant de modifier le contenue de\nl'éditeur plus facilement a été créé.Comme exemple à la sauvegarde de\nscript ont été mis à jours :",[162,16903,16904,16907],{},[165,16905,16906],{},"La mise à jours des key('url-param','') par des X-PATH",[165,16908,16909],{},"La mise à jours du nom du fichier dans les feuilles de styles.",[56,16911,16915],{"className":16912,"code":16913,"language":16914,"meta":61,"style":61},"language-javascript shiki shiki-themes one-dark-pro","obj.beforeSave = function() {\n  this.run();\n};\n\nobj.run = function() {\n  var search = new DocumentSearch(textEdit);\n\n  search.options.regExp = true;\n  search.searchText = \"key\\\\('url-param', '(.*)'\\\\)\";\n  search.replaceText =\n    \"\u002Flayout_data\u002Fapplication_data\u002Ftemporaire\u002Fparam[@name='\\\\1']\";\n\n  while (search.next()) {}\n};\n","javascript",[63,16916,16917,16934,16946,16950,16954,16968,16990,16994,17015,17042,17053,17065,17069,17087],{"__ignoreMap":61},[66,16918,16919,16921,16923,16926,16928,16931],{"class":68,"line":69},[66,16920,8073],{"class":240},[66,16922,44],{"class":230},[66,16924,16925],{"class":72},"beforeSave",[66,16927,2883],{"class":83},[66,16929,16930],{"class":223}," function",[66,16932,16933],{"class":230},"() {\n",[66,16935,16936,16939,16941,16944],{"class":68,"line":80},[66,16937,16938],{"class":240},"  this",[66,16940,44],{"class":230},[66,16942,16943],{"class":72},"run",[66,16945,543],{"class":230},[66,16947,16948],{"class":68,"line":89},[66,16949,906],{"class":230},[66,16951,16952],{"class":68,"line":279},[66,16953,276],{"emptyLinePlaceholder":275},[66,16955,16956,16958,16960,16962,16964,16966],{"class":68,"line":307},[66,16957,8073],{"class":240},[66,16959,44],{"class":230},[66,16961,16943],{"class":72},[66,16963,2883],{"class":83},[66,16965,16930],{"class":223},[66,16967,16933],{"class":230},[66,16969,16970,16973,16976,16978,16980,16983,16985,16988],{"class":68,"line":329},[66,16971,16972],{"class":223},"  var",[66,16974,16975],{"class":437}," search",[66,16977,2883],{"class":83},[66,16979,2811],{"class":223},[66,16981,16982],{"class":72}," DocumentSearch",[66,16984,231],{"class":230},[66,16986,16987],{"class":437},"textEdit",[66,16989,1188],{"class":230},[66,16991,16992],{"class":68,"line":334},[66,16993,276],{"emptyLinePlaceholder":275},[66,16995,16996,16999,17001,17004,17006,17009,17011,17013],{"class":68,"line":340},[66,16997,16998],{"class":240},"  search",[66,17000,44],{"class":230},[66,17002,17003],{"class":240},"options",[66,17005,44],{"class":230},[66,17007,17008],{"class":437},"regExp",[66,17010,2883],{"class":83},[66,17012,10207],{"class":114},[66,17014,1952],{"class":230},[66,17016,17017,17019,17021,17024,17026,17029,17032,17035,17037,17040],{"class":68,"line":355},[66,17018,16998],{"class":240},[66,17020,44],{"class":230},[66,17022,17023],{"class":437},"searchText",[66,17025,2883],{"class":83},[66,17027,17028],{"class":76}," \"key",[66,17030,17031],{"class":83},"\\\\",[66,17033,17034],{"class":76},"('url-param', '(.*)'",[66,17036,17031],{"class":83},[66,17038,17039],{"class":76},")\"",[66,17041,1952],{"class":230},[66,17043,17044,17046,17048,17051],{"class":68,"line":372},[66,17045,16998],{"class":240},[66,17047,44],{"class":230},[66,17049,17050],{"class":437},"replaceText",[66,17052,2894],{"class":83},[66,17054,17055,17058,17060,17063],{"class":68,"line":395},[66,17056,17057],{"class":76},"    \"\u002Flayout_data\u002Fapplication_data\u002Ftemporaire\u002Fparam[@name='",[66,17059,17031],{"class":83},[66,17061,17062],{"class":76},"1']\"",[66,17064,1952],{"class":230},[66,17066,17067],{"class":68,"line":400},[66,17068,276],{"emptyLinePlaceholder":275},[66,17070,17071,17074,17076,17079,17081,17084],{"class":68,"line":416},[66,17072,17073],{"class":223},"  while",[66,17075,574],{"class":230},[66,17077,17078],{"class":240},"search",[66,17080,44],{"class":230},[66,17082,17083],{"class":72},"next",[66,17085,17086],{"class":230},"()) {}\n",[66,17088,17089],{"class":68,"line":421},[66,17090,906],{"class":230},[17,17092,17093,17094,17096,17097,17100],{},"La nouveauté se trouve dans l'ajout de quatre nouvelle méthodes. La\nméthode utilisé ici est ",[63,17095,16925],{}," et permet de faire des\nmodifications au texte avant sauvegarde. Tout comme ",[63,17098,17099],{},"afterSave"," permet\nd'effectuer des modifications au texte après sauvegarde. Nous avons\négalement deux méthodes beforeLoad et afterLoad pour les opérations à\nfaire lors de la lecture.",[12,17102,17104],{"id":17103},"autres-nouveautés","Autres nouveautés",[17,17106,17107],{},"Bien sur cet version apporte aussi d'autres nouveautés comme :",[162,17109,17110,17113],{},[165,17111,17112],{},"la fermeture automatique de balise",[165,17114,17115],{},"des nouvelles options, ...",[12,17117,17119],{"id":17118},"installation","Installation",[4389,17121,17123],{"id":17122},"sous-mswindows","Sous Ms\u002FWindows",[17,17125,17126,17127,17129,17130,17135],{},"Pour installer la dernière version de ",[1534,17128,4311],{}," vous pouvez télécharger\nle ",[39,17131,17134],{"href":17132,"rel":17133},"http:\u002F\u002Fxinx.shadoware.org\u002Fdownloads\u002F40",[43],"programme d'installation"," et le lancer. Il remplacera\nautomatiquement l'ancienne version.",[17,17137,17138],{},"Si vous avez des fichiers de données modifiés (template, script, ...)\npensez à les sauvegarder.",[4389,17140,17142],{"id":17141},"sous-gnulinux","Sous Gnu\u002FLinux",[17,17144,17145],{},"Sous Debian, vous pouvez ajouter le dépôt dans le fichier\n\u002Fetc\u002Fapt\u002Fsources.list. Ainsi vous serez automatiquement prévenu des\nmises à jours éventuelle.",[56,17147,17150],{"className":17148,"code":17149,"language":840},[838],"deb http:\u002F\u002Fapt.shadoware.org\u002F sid main\n",[63,17151,17149],{"__ignoreMap":61},[17,17153,17154],{},"puis dans une console :",[56,17156,17158],{"className":58,"code":17157,"language":60,"meta":61,"style":61},"sudo apt-cache search xinx\nsudo aptitude install xinx\n",[63,17159,17160,17171],{"__ignoreMap":61},[66,17161,17162,17164,17167,17169],{"class":68,"line":69},[66,17163,2984],{"class":72},[66,17165,17166],{"class":76}," apt-cache",[66,17168,16975],{"class":76},[66,17170,12590],{"class":76},[66,17172,17173,17175,17178,17180],{"class":68,"line":80},[66,17174,2984],{"class":72},[66,17176,17177],{"class":76}," aptitude",[66,17179,12587],{"class":76},[66,17181,12590],{"class":76},[17,17183,17184,17185,17187],{},"Pour les autres distributions ou pour les machines MacOS vous pouvez\ncompiler ",[1534,17186,4311],{}," à partir des sources.",[1545,17189,17190],{},"html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":61,"searchDepth":80,"depth":80,"links":17192},[17193,17194,17195,17196,17197],{"id":16826,"depth":89,"text":16827},{"id":16879,"depth":89,"text":16880},{"id":16895,"depth":89,"text":16896},{"id":17103,"depth":89,"text":17104},{"id":17118,"depth":89,"text":17119},"2009-03-06",{"type":9,"value":17200},[17201,17205,17209],[17,17202,17203],{},[1445,17204],{"alt":16792,"src":16793},[17,17206,16796,17207,44],{},[1534,17208,4311],{},[17,17210,17211,16803,17213,44],{},[1534,17212,4311],{},[32,17214,16806],{},{},"\u002Fpost\u002Fxinx-0.8.0.0",{"title":16785,"description":61},"xinx-0.8.0.0","posts\u002FXINX\u002F2009-03-06-xinx-0.8.0.0",[1595,5899,5930,1592,5931],"2LVP73RxAuNHiNwoDLW7n9zx61WC1hKRo8CPZUCY5rk",{"id":17223,"title":17224,"author":7,"body":17225,"category":16677,"categorySlug":16678,"date":17414,"description":17415,"excerpt":17416,"extension":1584,"location":1585,"meta":17466,"navigation":275,"path":17467,"published":275,"seo":17468,"slug":17469,"stem":17470,"tags":17471,"timeToRead":80,"__hash__":17472},"posts\u002Fposts\u002FLogiciels\u002F2009-03-03-qt-4.5-est-sortie.md","Qt 4.5 est sortie",{"type":9,"value":17226,"toc":17411},[17227,17233,17238,17246,17289,17294,17318,17329,17334,17365,17379,17385],[17,17228,17229,17230,17232],{},"Voilà quelques heures que la dernière version de ",[32,17231,3803],{}," est sortie. Cette\nversion, numéroté 4.5, est essentiellement orienté performance.",[17,17234,17235],{},[1445,17236],{"alt":16588,"src":17237},"\u002FLogiciels\u002Fqt-4.5-est-sortie\u002Flogo_nokia_qt.png",[17,17239,17240,17241],{},"Elle contient entre autre",[1607,17242,17243],{},[39,17244,461],{"href":1611,"ariaDescribedBy":17245,"dataFootnoteRef":61,"id":1614},[1613],[162,17247,17248,17263,17269,17275,17278],{},[165,17249,17250,17251,17254,17255,17258,17259,17262],{},"Une mise à jour de ",[32,17252,17253],{},"QtWebKit"," vers un version de ",[32,17256,17257],{},"WebKit"," plus\nrécente (avec un nouveau moteur JavaScript plus rapide, la\npossibilité d'ajouter des greffons comme ",[32,17260,17261],{},"Flash","...). Il est\négalement possible d'utiliser les balises d'HTML 5.",[165,17264,17265,17266,44],{},"Amélioration des performances sur le moteur de rendu ainsi que sur\nle rendu du texte. Une librairie permettant de faire des tests de\nperformance a été incluse : ",[32,17267,17268],{},"QtBenchLib",[165,17270,17271,17272],{},"Le support de ",[32,17273,17274],{},"Mac OS X Cocoa",[165,17276,17277],{},"La possibilité de faire des transformations XSLT",[165,17279,17280,17281,17284],{},"Un débuggeur ",[32,17282,17283],{},"QtScript",[1607,17285,17286],{},[39,17287,476],{"href":1637,"ariaDescribedBy":17288,"dataFootnoteRef":61,"id":1639},[1613],[17,17290,17291],{},[1445,17292],{"alt":3803,"src":17293},"\u002FLogiciels\u002Fqt-4.5-est-sortie\u002Fqtscript-debugger-small.png",[162,17295,17296,17303,17306,17315],{},[165,17297,17298,17299,17302],{},"Le support du format ",[32,17300,17301],{},"OpenDocument"," (ODF version 1.0, ne supportant\nque le texte et les images)",[165,17304,17305],{},"Amélioration du support des proxys",[165,17307,17308,17309,251,17312],{},"Amélioration de ",[32,17310,17311],{},"QtDesigner",[32,17313,17314],{},"QtLinguist",[165,17316,17317],{},"Une meilleur intégration au thème Gtk",[17,17319,17320,17321,17324,17325,17328],{},"Cette nouvelle version apporte également une grande nouveauté\npuisqu'elle est ",[32,17322,17323],{},"LGPL",". Il est donc désormais possible de faire une\napplication propriétaire à l'aide de cette librairie sans prendre une\nlicence chez ",[32,17326,17327],{},"Qt Software",". Par contre si une entreprise souhaite un\nsupport pour la librairie, il faudra tout de même acheter une licence.",[17,17330,17331],{},[1445,17332],{"alt":3716,"src":17333},"\u002FLogiciels\u002Fqt-4.5-est-sortie\u002FScreenShot166.png",[17,17335,17336,17337,17339,17340,17343,17344,17346,17347,17349,17350,17353,17354,17356,17357,251,17359,17361,17362,17364],{},"La sortie de ",[32,17338,3803],{}," 4.5 est accompagné de ",[32,17341,17342],{},"Qt Creator"," 1.0. ",[32,17345,17342],{},"\nest l'outil dernier né de chez ",[32,17348,17327],{}," (branche de ",[32,17351,17352],{},"Nokia",") et est\nun IDE de développement de programme ",[32,17355,3803],{},". Un paquet est proposé\ncontenant ",[32,17358,3803],{},[32,17360,17342],{},", ainsi que ",[32,17363,1691],{}," et permettant d'avoir\nune installation tout en un d'un poste de développement.",[17,17366,17367,17368,17370,17371,17373,17374,44],{},"Vous pouvez donc aller télécharger la dernière version de ",[32,17369,3803],{},", ainsi\nque de ",[32,17372,17342],{}," (attention les serveurs sont surchargés) à cette\n",[39,17375,17378],{"href":17376,"rel":17377},"http:\u002F\u002Fwww.qtsoftware.com\u002Fdownloads",[43],"adresse",[17,17380,17381,17382,17384],{},"Je remercie toute l'équipe de nouvellement ",[32,17383,17327],{}," de cette\nnouvelle version.",[3349,17386,17388,17391],{"className":17387,"dataFootnotes":61},[3352],[1432,17389,3357],{"className":17390,"id":1613},[3356],[3359,17392,17393,17403],{},[165,17394,17395,17396,5538,17400],{"id":3363},"pour plus de détail voir ",[39,17397,17398],{"href":17398,"rel":17399},"http:\u002F\u002Fdoc.trolltech.com\u002F4.5\u002Fqt4-5-intro.html",[43],[39,17401,3371],{"href":3367,"ariaLabel":3368,"className":17402,"dataFootnoteBackref":61},[3370],[165,17404,17405,17406,5538,17408],{"id":3374},"L'image du debugger viens du site ",[32,17407,17327],{},[39,17409,3371],{"href":3378,"ariaLabel":3379,"className":17410,"dataFootnoteBackref":61},[3370],{"title":61,"searchDepth":80,"depth":80,"links":17412},[17413],{"id":1613,"depth":80,"text":3357},"2009-03-03","Voilà quelques heures que la dernière version de Qt est sortie. Cette\nversion, numéroté 4.5, est essentiellement orienté performance.",{"type":9,"value":17417},[17418,17422,17426,17433,17462],[17,17419,17229,17420,17232],{},[32,17421,3803],{},[17,17423,17424],{},[1445,17425],{"alt":16588,"src":17237},[17,17427,17240,17428],{},[1607,17429,17430],{},[39,17431,461],{"href":1611,"ariaDescribedBy":17432,"dataFootnoteRef":61,"id":1614},[1613],[162,17434,17435,17443,17447,17451,17453],{},[165,17436,17250,17437,17254,17439,17258,17441,17262],{},[32,17438,17253],{},[32,17440,17257],{},[32,17442,17261],{},[165,17444,17265,17445,44],{},[32,17446,17268],{},[165,17448,17271,17449],{},[32,17450,17274],{},[165,17452,17277],{},[165,17454,17280,17455,17457],{},[32,17456,17283],{},[1607,17458,17459],{},[39,17460,476],{"href":1637,"ariaDescribedBy":17461,"dataFootnoteRef":61,"id":1639},[1613],[17,17463,17464],{},[1445,17465],{"alt":3803,"src":17293},{},"\u002Fpost\u002Fqt-4.5-est-sortie",{"title":17224,"description":17415},"qt-4.5-est-sortie","posts\u002FLogiciels\u002F2009-03-03-qt-4.5-est-sortie",[1592],"gWjLlhm92HnoKh4gr6rJd2ET4T4kKlZIkeq4_SEDikE",{"id":17474,"title":17475,"author":7,"body":17476,"category":4311,"categorySlug":5899,"date":17777,"description":15200,"excerpt":17778,"extension":1584,"location":1585,"meta":17794,"navigation":275,"path":17795,"published":275,"seo":17796,"slug":17797,"stem":17798,"tags":17799,"timeToRead":279,"__hash__":17800},"posts\u002Fposts\u002FXINX\u002F2009-02-18-xinx-editeur-de-feuille-de-style.md","XINX - Editeur de feuille de style",{"type":9,"value":17477,"toc":17772},[17478,17480,17489,17492,17498,17500,17514,17541,17563,17568,17592,17627,17631,17636,17641,17694,17715],[17,17479,15200],{},[17,17481,17482,17483,17485,17486,17488],{},"Ce billet, parle de ",[1534,17484,4311],{},", un logiciel libre que j'ai développé et\nque je continue à développer sur mon temps libre. Le but de se billet\nest de présenter ",[1534,17487,4311],{}," et d'être le début d'une longue série de\nbillet parlant de son développement.",[17,17490,17491],{},"En effet, même si le programme est propre à une utilisation particulière\npour un cercle de personne restreint, les méthodes, classes, et idées\nutilisées dans ce programme peuvent intéresser d'autres personnes.",[17,17493,17494],{},[1445,17495],{"alt":17496,"src":17497},"Nouvelle","\u002FXINX\u002Fxinx-editeur-de-feuille-de-style\u002FScreenShot151.png",[12,17499,3514],{"id":3513},[17,17501,17502,17504,17505,17508,17509,44],{},[1534,17503,4311],{}," est un éditeur de feuille de style sur lequel je travail depuis\ndébut 2006. En faite j'avais commencé un autre éditeur à l'aide de\n",[1534,17506,17507],{},"Borland\u002FDelphi 7"," mais il a été rapidement arrêté pour prendre une\nnouvelle direction dans un nouveau langage avec un nouveau\ndépart",[1607,17510,17511],{},[39,17512,461],{"href":1611,"ariaDescribedBy":17513,"dataFootnoteRef":61,"id":1614},[1613],[17,17515,17516,17517,17520,17521,17528,17533,17534,17536,17537,17540],{},"Cet éditeur de feuille de style à la particularité de pouvoir être\nutilisé dans le cadre de mon travail : sur l'application ",[32,17518,17519],{},"eGx"," (de la\nsociété ",[1534,17522,17523],{},[39,17524,17527],{"href":17525,"rel":17526},"http:\u002F\u002Fwww.fr.generixgroup.com",[43],"Générix",[1607,17529,17530],{},[39,17531,476],{"href":1637,"ariaDescribedBy":17532,"dataFootnoteRef":61,"id":1639},[1613],"). ",[1534,17535,4311],{}," permet non seulement\nl'édition de feuille de style (XSL), en proposant une ",[32,17538,17539],{},"complétion","\nintuitive, mais propose également un mode projet, dans lequel il est\npossible de dérivé une feuille de style plutôt que de la remplacer (de\nfaçon spécifique à notre méthode de travail en projet chez le client).",[17,17542,17543,17545,17546,17551,17552,17555,17556,17558,17559,17562],{},[1534,17544,4311],{}," est un acronyme récursive",[1607,17547,17548],{},[39,17549,1651],{"href":1648,"ariaDescribedBy":17550,"dataFootnoteRef":61,"id":1650},[1613]," qui signifie ",[32,17553,17554],{},"XINX Is Not\nXDME",". Ce nom a été choisis car ",[1534,17557,4311],{}," est le complément idéal à\n",[1534,17560,17561],{},"XDME"," (l'éditeur de fichier de configuration d*'eGx*).",[17,17564,17565],{},[1445,17566],{"alt":16588,"src":17567},"\u002FXINX\u002Fxinx-editeur-de-feuille-de-style\u002Flogo_nokia_qt.png",[17,17569,17570,17571,17574,17575,251,17577,17579,17580,17582,17583,17585,17586,17589,17591],{},"Au niveau du choix du langage, a contrario des autres applications\n",[1534,17572,17573],{},"Generix"," écritent en ",[32,17576,12085],{},[1534,17578,4311],{}," a été programmé en ",[32,17581,5416],{},". Le\nframework ",[32,17584,3803],{}," de la société ",[16401,17587,17588],{},"Trolltech",[1534,17590,17352],{}," a été\nchoisis pour simplifier la programmation. Pourquoi ce choix de langage :",[162,17593,17594,17602,17614],{},[165,17595,17596,17598,17599,17601],{},[1534,17597,4311],{}," est une application écrite sur mon temps libre, j'ai donc\nchoisis un langage que je souhaité apprendre. En faite la raison de\nl'existence de ",[1534,17600,4311],{},", et la volonté d'apprendre à utiliser ce\nframework.",[165,17603,17604,17605,17607,17608,17610,17611,44],{},"Le framework ",[32,17606,3803],{}," est utilisé par l'environnement de bureau ",[1534,17609,5947],{},".\nCet environnement de bureau est celui que j'utilise tous les jours,\npendant mon temps libre (chez moi), sous ",[1534,17612,17613],{},"Gnu\u002FLinux",[165,17615,17616,17617,17619,17620,1295,17622,44],{},"La version 4 de ce framework est utilisable sous ",[1534,17618,12256],{},",\nsans payer de licence, dans le cadre de l'écriture d'un logiciel\nlibre (au bureau tout nos poste sont sous ",[1534,17621,12256],{},[1607,17623,17624],{},[39,17625,1682],{"href":1679,"ariaDescribedBy":17626,"dataFootnoteRef":61,"id":1681},[1613],[12,17628,17630],{"id":17629},"architecture","Architecture",[17,17632,17633],{},[1445,17634],{"alt":17630,"src":17635},"\u002FXINX\u002Fxinx-editeur-de-feuille-de-style\u002FarchiXINX.png",[17,17637,17638,17640],{},[1534,17639,4311],{}," est décomposé en plusieurs parties :",[162,17642,17643,17646,17649,17669,17672,17678,17689],{},[165,17644,17645],{},"la librairie de composant (contenant un gestionnaire de plugin en\nQt, un combobox pour choisir une couleur, une liste de valeur avec\nles boutons pour ajouter ou supprimer des éléments, une barre\nd'édition pour faciliter l'édition de dossier)",[165,17647,17648],{},"la librairie principale (externalisant ce qui peut être nécessaire\naux plugins).",[165,17650,17651,17652,17654,17655],{},"une série de plugin permettant, dans ",[1534,17653,4311],{}," de",[162,17656,17657,17660,17663,17666],{},[165,17658,17659],{},"gérer CVS",[165,17661,17662],{},"gérer SubVersion",[165,17664,17665],{},"gérer les extentions XSL, JS, XML, HTML",[165,17667,17668],{},"gérer les WebServices",[165,17670,17671],{},"l'application elle-même",[165,17673,17674,17675,17677],{},"une application de migration de projet (pour migrer les fichiers\nprojets ",[1534,17676,4311],{}," quand ces derniers changent)",[165,17679,17680,17681,17684,1295],{},"une librairie gérant l'éditeur de code (l'éditeur utilisé pour la\nprochaine version est ",[39,17682,12620],{"href":12618,"rel":17683},[43],[1607,17685,17686],{},[39,17687,1699],{"href":1696,"ariaDescribedBy":17688,"dataFootnoteRef":61,"id":1698},[1613],[165,17690,17691,17692],{},"les librairies du framework ",[32,17693,3803],{},[17,17695,17696,17697,17702,17703,17708,17709,17714],{},"Vous pouvez une documentation sur l'écriture de ",[39,17698,17701],{"href":17699,"rel":17700},"http:\u002F\u002Fxinx.shadoware.org\u002Fwiki\u002FXinxPlugins",[43],"plugins"," sur le site\nde ",[1534,17704,17705],{},[39,17706,4311],{"href":12212,"rel":17707},[43]," ainsi qu'une documentation au format ",[39,17710,17713],{"href":17711,"rel":17712},"http:\u002F\u002Fxinx.shadoware.org\u002Fdoxygen\u002Fmain.html",[43],"Doxygen"," des\nlibrairies.",[3349,17716,17718,17721],{"className":17717,"dataFootnotes":61},[3352],[1432,17719,3357],{"className":17720,"id":1613},[3356],[3359,17722,17723,17731,17742,17755,17766],{},[165,17724,17725,17727,17728],{"id":3363},[1534,17726,17507],{}," étant limité à la plateforme de Microsoft, et l'application ayant pris dés le début une mauvaise direction (orienté fichier de configuration plutôt que feuille de style) ",[39,17729,3371],{"href":3367,"ariaLabel":3368,"className":17730,"dataFootnoteBackref":61},[3370],[165,17732,17733,17735,17736,5538,17739],{"id":3374},[1534,17734,17573],{}," est un éditeur de logiciel de gestion d'entreprise, dit ",[32,17737,17738],{},"ERP",[39,17740,3371],{"href":3378,"ariaLabel":3379,"className":17741,"dataFootnoteBackref":61},[3370],[165,17743,17744,17745,17748,17749,5538,17752],{"id":3383},"Un acronyme qui contient l'acronyme même, comme ",[1534,17746,17747],{},"Gnu"," pour ",[32,17750,17751],{},"Gnu Is not Unix",[39,17753,3371],{"href":3387,"ariaLabel":3388,"className":17754,"dataFootnoteBackref":61},[3370],[165,17756,17757,17759,17760,17762,17763],{"id":3392},[1534,17758,4311],{}," est un logiciel libre non parce que je n'avais pas le choix dû à la double licence de la librairie ",[32,17761,3803],{}," mais bien par choix personnelle de développer du logiciel libre sur mon temps personnel. ",[39,17764,3371],{"href":3396,"ariaLabel":3397,"className":17765,"dataFootnoteBackref":61},[3370],[165,17767,17768,17769],{"id":3401},"QCodeEdit est un éditeur de code écrit pour Qt. Il est très performant, et possède beaucoup de fonctionnalité utile. ",[39,17770,3371],{"href":3409,"ariaLabel":3410,"className":17771,"dataFootnoteBackref":61},[3370],{"title":61,"searchDepth":80,"depth":80,"links":17773},[17774,17775,17776],{"id":3513,"depth":89,"text":3514},{"id":17629,"depth":89,"text":17630},{"id":1613,"depth":80,"text":3357},"2009-02-18",{"type":9,"value":17779},[17780,17782,17788,17790],[17,17781,15200],{},[17,17783,17482,17784,17485,17786,17488],{},[1534,17785,4311],{},[1534,17787,4311],{},[17,17789,17491],{},[17,17791,17792],{},[1445,17793],{"alt":17496,"src":17497},{},"\u002Fpost\u002Fxinx-editeur-de-feuille-de-style",{"title":17475,"description":15200},"xinx-editeur-de-feuille-de-style","posts\u002FXINX\u002F2009-02-18-xinx-editeur-de-feuille-de-style",[5899,5930,1592,5931],"zpIhRB-KvKQE1lDggeBl1D-gfvOgwt-duiaJNbpQxj4",{"id":17802,"title":17803,"author":7,"body":17804,"category":16677,"categorySlug":16678,"date":17934,"description":17935,"excerpt":17936,"extension":1584,"location":1585,"meta":17951,"navigation":275,"path":17952,"published":275,"seo":17953,"slug":17954,"stem":17955,"tags":17956,"timeToRead":69,"__hash__":17957},"posts\u002Fposts\u002FLogiciels\u002F2008-10-19-nouvelles-fonctionnalites-de-qt-designer-45.md","Nouvelles fonctionnalités de Qt Designer 4.5",{"type":9,"value":17805,"toc":17931},[17806,17820,17823,17829,17835,17838,17844,17847,17890,17896,17899,17904,17907,17913],[17,17807,17808,17809,17814,17815,44],{},"Sur ",[32,17810,17811,17813],{},[16401,17812,17588],{},"Nokia Labs Blogs",", Friedelann Kleint nous\nprésente aujourd'hui les nouvelles fonctionnalités de Qt Designer 4.5",[1607,17816,17817],{},[39,17818,461],{"href":1611,"ariaDescribedBy":17819,"dataFootnoteRef":61,"id":1614},[1613],[17,17821,17822],{},"Au menu, on peut trouver l'ajout de filtre sur l'éditeur de propriétés\nainsi que sur l'inspecteur d'objet (Ce qui peut permettre de\nsélectionner un composant et d'en modifier les propriétés plus\nrapidement).",[17,17824,17825],{},[1445,17826],{"alt":17827,"src":17828},"objectinspector","\u002FLogiciels\u002Fnouvelles-fonctionnalites-de-qt-designer-45\u002Fobjectinspector.png",[17,17830,17831],{},[1445,17832],{"alt":17833,"src":17834},"propertyeditorfilter","\u002FLogiciels\u002Fnouvelles-fonctionnalites-de-qt-designer-45\u002Fpropertyeditorfilter.png",[17,17836,17837],{},"L'arrangement de la boite à outil est également différent :",[17,17839,17840],{},[1445,17841],{"alt":17842,"src":17843},"widgetbox_iconmode","\u002FLogiciels\u002Fnouvelles-fonctionnalites-de-qt-designer-45\u002Fwidgetbox_iconmode.png",[17,17845,17846],{},"De plus il est maintenant possible de :",[162,17848,17849,17860,17870,17877,17884,17887],{},[165,17850,17851,17852,17855,17856,17859],{},"Sélectionner l'objet ancêtre d'un ",[32,17853,17854],{},"widget"," en sélectionnant ",[32,17857,17858],{},"Select\nancestors"," du menu contextuel.",[165,17861,17862,17863,17866,17867,17869],{},"Changer le ",[32,17864,17865],{},"Layout"," sans casser et reconstruire le ",[32,17868,17865],{}," de la\nfeuille",[165,17871,17872,17873,17876],{},"Ajouter facilement une nouvelle ligne au layout (L'action ",[32,17874,17875],{},"Add form\nlayout row"," ouvrant la boite de dialogue ci-dessous)",[165,17878,17879,17880,17883],{},"Créer des Assistants (",[32,17881,17882],{},"Wizard",") linéaires",[165,17885,17886],{},"Désactiver la traduction de certaine chaîne.",[165,17888,17889],{},"...",[17,17891,17892],{},[1445,17893],{"alt":17894,"src":17895},"formlayout","\u002FLogiciels\u002Fnouvelles-fonctionnalites-de-qt-designer-45\u002Fformlayout.png",[17,17897,17898],{},"Enfin, pour terminer, comme le dit Friedemann",[16652,17900,17901],{},[17,17902,17903],{},"The general focus of the 4.5 release is on stability and performance.",[17,17905,17906],{},"Soit : Le but principal de la version 4.5 est la stabilité et les\nperformances.",[17,17908,17909,17910,44],{},"Pour plus de précision, je vous conseille d'aller voir la page d'origine\net\u002Fou de télécharger la ",[32,17911,17912],{},"snapshot",[3349,17914,17916,17919],{"className":17915,"dataFootnotes":61},[3352],[1432,17917,3357],{"className":17918,"id":1613},[3356],[3359,17920,17921],{},[165,17922,17923,17924,5538,17928],{"id":3363},"Référence : ",[39,17925,17926],{"href":17926,"rel":17927},"http:\u002F\u002Flabs.trolltech.com\u002Fblogs\u002F2008\u002F10\u002F16\u002Fnew-features-of-qt-designer-45\u002F",[43],[39,17929,3371],{"href":3367,"ariaLabel":3368,"className":17930,"dataFootnoteBackref":61},[3370],{"title":61,"searchDepth":80,"depth":80,"links":17932},[17933],{"id":1613,"depth":80,"text":3357},"2008-10-19","Sur TrolltechNokia Labs Blogs, Friedelann Kleint nous\nprésente aujourd'hui les nouvelles fonctionnalités de Qt Designer 4.51.",{"type":9,"value":17937},[17938,17949],[17,17939,17808,17940,17814,17944,44],{},[32,17941,17942,17813],{},[16401,17943,17588],{},[1607,17945,17946],{},[39,17947,461],{"href":1611,"ariaDescribedBy":17948,"dataFootnoteRef":61,"id":1614},[1613],[17,17950,17822],{},{},"\u002Fpost\u002Fnouvelles-fonctionnalites-de-qt-designer-45",{"title":17803,"description":17935},"nouvelles-fonctionnalites-de-qt-designer-45","posts\u002FLogiciels\u002F2008-10-19-nouvelles-fonctionnalites-de-qt-designer-45",[1592],"nm-5nCtyIY7ytRcB2NS0B1KwbYlYkEMuv_OrrHl_gZI",{"id":17959,"title":17960,"author":7,"body":17961,"category":16677,"categorySlug":16678,"date":18049,"description":18050,"excerpt":18051,"extension":1584,"location":1585,"meta":18052,"navigation":275,"path":18053,"published":275,"seo":18054,"slug":18055,"stem":18056,"tags":18057,"timeToRead":69,"__hash__":18058},"posts\u002Fposts\u002FLogiciels\u002F2008-10-06-qt-442-puis-qt-443-sont-sorties.md","QT 4.4.2 puis QT 4.4.3 sont sorties",{"type":9,"value":17962,"toc":18046},[17963,17968,17985,18006,18009,18023],[17,17964,17965,17966,44],{},"En une semaine sont sortie les versions 4.4.2 et 4.4.3 de ",[32,17967,3803],{},[17,17969,17970,17971,17974,17975,17979,17980,17982,17983,44],{},"La version 4.4.2 corrige de nombreux bugs (dont des fuites mémoires sur\nla partie ",[32,17972,17973],{},"XmlPatterns","). Vous pouvez trouver la listes des changements\n",[39,17976,17978],{"href":17977},"\u002FLogiciels\u002Fqt-442-puis-qt-443-sont-sorties\u002Fchanges-4.4.2","à cette adresse",", ou dans l'archive ",[32,17981,3803],{}," se trouvant sur le site\n",[32,17984,17588],{},[17,17986,17987,17988,17993,17994,6619,17996,17998,17999,18001,18002,1640],{},"La version 4.4.3",[1607,17989,17990],{},[39,17991,461],{"href":1611,"ariaDescribedBy":17992,"dataFootnoteRef":61,"id":1614},[1613]," modifie chaque entête de fichiers, les icônes,\n... pour refléter l'achat de ",[32,17995,17588],{},[32,17997,17352],{},". Par la même\noccasion le site de ",[32,18000,17588],{}," a été complètement refait\n(",[39,18003,18004],{"href":18004,"rel":18005},"http:\u002F\u002Ftrolltech.com",[43],[17,18007,18008],{},"Donc si vous avez la version 4.4.2, il n'est pas nécessaire de récupérer\nla 4.4.3 (sauf si vous souhaiter absolument la dernière version au nom\nde Nokia), par contre si vous êtes encore à la version 4.4.0 ou 4.4.1,\nil peut être intéressant d'installer la dernière version (suivant les\nfonctionnalités que vous utilisez).",[17,18010,18011,18012,18014,18015,18017,18018,1615],{},"Enfin, la question, sans réponse, est, est-ce que le site de ",[32,18013,17588],{},"\net de ",[32,18016,17352],{}," vont fusionner ou vont-il rester séparer",[1607,18019,18020],{},[39,18021,476],{"href":1637,"ariaDescribedBy":18022,"dataFootnoteRef":61,"id":1639},[1613],[3349,18024,18026,18029],{"className":18025,"dataFootnotes":61},[3352],[1432,18027,3357],{"className":18028,"id":1613},[3356],[3359,18030,18031,18040],{},[165,18032,18033,5538,18037],{"id":3363},[39,18034,18035],{"href":18035,"rel":18036},"http:\u002F\u002Ftrolltech.com\u002Fabout\u002Fnews\u002Fqt-4.4.3-released",[43],[39,18038,3371],{"href":3367,"ariaLabel":3368,"className":18039,"dataFootnoteBackref":61},[3370],[165,18041,18042,18043],{"id":3374},"ce dernier est tout de même plus pratique, je trouve ",[39,18044,3371],{"href":3378,"ariaLabel":3379,"className":18045,"dataFootnoteBackref":61},[3370],{"title":61,"searchDepth":80,"depth":80,"links":18047},[18048],{"id":1613,"depth":80,"text":3357},"2008-10-06","En une semaine sont sortie les versions 4.4.2 et 4.4.3 de Qt.",null,{},"\u002Fpost\u002Fqt-442-puis-qt-443-sont-sorties",{"title":17960,"description":18050},"qt-442-puis-qt-443-sont-sorties","posts\u002FLogiciels\u002F2008-10-06-qt-442-puis-qt-443-sont-sorties",[1592],"TNEywWz-ZtPa5b6pfMVBEL9D98bBfXfM5LASdSKmk7E",{"id":18060,"title":18061,"author":7,"body":18062,"category":1560,"categorySlug":1561,"date":19078,"description":19079,"excerpt":19080,"extension":1584,"location":1585,"meta":19092,"navigation":275,"path":19093,"published":275,"seo":19094,"slug":19095,"stem":19096,"tags":19097,"timeToRead":329,"__hash__":19098},"posts\u002Fposts\u002FProgrammation\u002F2008-09-08-paquet-debian-et-qt.md","Paquet Debian et Qt",{"type":9,"value":18063,"toc":19072},[18064,18072,18078,18082,18091,18114,18118,18122,18131,18137,18140,18243,18249,18262,18266,18275,18311,18314,18351,18354,18386,18390,18393,18400,18406,18416,18426,18521,18536,18540,18552,18558,18564,18578,18858,18861,18865,18869,18874,18887,18892,18904,18907,18920,18923,18927,18930,18936,18940,18943,18949,18969,18973,18980,18986,18990,18996,19000,19003,19040,19069],[17,18065,18066,18067,18069,18070,1640],{},"A titre personnel je fabrique quelques programmes en Qt. Comme j'utilise\nun système ",[32,18068,12249],{},", j'ai cherché à fabriquer des paquets pour mon\nsystème (plus pour le plaisir qu'autre chose, car la plus grande partie\nde mes utilisateurs sont sous ",[32,18071,12256],{},[17,18073,18074,18075,18077],{},"Ce billet explique la création de paquet ",[32,18076,12249],{}," pour des\napplications Qt 4 utilisant QMake",[12,18079,18081],{"id":18080},"installation-des-paquets","Installation des paquets",[17,18083,18084,18085,18087,18088,44],{},"Pour la création des paquets pour des programmes utilisant ",[63,18086,2862],{},", il\nfaut ",[63,18089,18090],{},"cdbs, dh_make, dpkg-buildpackage",[56,18092,18094],{"className":58,"code":18093,"language":60,"meta":61,"style":61},"aptitude install cdbs dh-make fakeroot devscripts\n",[63,18095,18096],{"__ignoreMap":61},[66,18097,18098,18100,18102,18105,18108,18111],{"class":68,"line":69},[66,18099,12584],{"class":72},[66,18101,12587],{"class":76},[66,18103,18104],{"class":76}," cdbs",[66,18106,18107],{"class":76}," dh-make",[66,18109,18110],{"class":76}," fakeroot",[66,18112,18113],{"class":76}," devscripts\n",[12,18115,18117],{"id":18116},"création-du-paquet","Création du paquet",[4389,18119,18121],{"id":18120},"préparation","Préparation",[17,18123,18124,18125,18128,18129,44],{},"Vous pouvez donc choisir un de vos programmes que vous voulez\nempaqueter. Pour cela vous allez commencer par nettoyer l'arborescence\nde votre projet pour retirer les fichiers de sauvegarde ainsi que les\nfichiers de construction (",[63,18126,18127],{},"*~ *.o",", ...). Ce petit nettoyage va\npermettre d'avoir un paquet source ",[32,18130,4346],{},[17,18132,18133,18134,44],{},"Il faut que vous placiez les sources dans un dossier du nom de\n",[63,18135,18136],{},"\u003Cprogramme>-\u003Cversion>",[17,18138,18139],{},"Voici un exemple de fichier projet :",[56,18141,18144],{"className":18142,"code":18143,"language":2862,"meta":61,"style":61},"language-qmake shiki shiki-themes one-dark-pro","TARGET = qgenconfig\nTEMPLATE = app\n\nCONFIG += exceptions warn_on qt\nQT += xml\n\nHEADERS += src\u002Floadconfigimpl.h \\\\\n    src\u002Fsetupfile.h \\\\\n    src\u002Fconfigfile.h \\\\\n    src\u002Fp_configfile.h\nSOURCES += src\u002Floadconfigimpl.cpp \\\\\n    src\u002Fsetupfile.cpp \\\\\n    src\u002Fmain.cpp \\\\\n    src\u002Fconfigfile.cpp\nFORMS = ui\u002Floadconfig.ui\n\nDESTDIR = bin\nMOC_DIR = build\nOBJECTS_DIR = build\nUI_DIR = build\n",[63,18145,18146,18151,18156,18160,18165,18170,18174,18179,18184,18189,18194,18199,18204,18209,18214,18219,18223,18228,18233,18238],{"__ignoreMap":61},[66,18147,18148],{"class":68,"line":69},[66,18149,18150],{},"TARGET = qgenconfig\n",[66,18152,18153],{"class":68,"line":80},[66,18154,18155],{},"TEMPLATE = app\n",[66,18157,18158],{"class":68,"line":89},[66,18159,276],{"emptyLinePlaceholder":275},[66,18161,18162],{"class":68,"line":279},[66,18163,18164],{},"CONFIG += exceptions warn_on qt\n",[66,18166,18167],{"class":68,"line":307},[66,18168,18169],{},"QT += xml\n",[66,18171,18172],{"class":68,"line":329},[66,18173,276],{"emptyLinePlaceholder":275},[66,18175,18176],{"class":68,"line":334},[66,18177,18178],{},"HEADERS += src\u002Floadconfigimpl.h \\\\\n",[66,18180,18181],{"class":68,"line":340},[66,18182,18183],{},"    src\u002Fsetupfile.h \\\\\n",[66,18185,18186],{"class":68,"line":355},[66,18187,18188],{},"    src\u002Fconfigfile.h \\\\\n",[66,18190,18191],{"class":68,"line":372},[66,18192,18193],{},"    src\u002Fp_configfile.h\n",[66,18195,18196],{"class":68,"line":395},[66,18197,18198],{},"SOURCES += src\u002Floadconfigimpl.cpp \\\\\n",[66,18200,18201],{"class":68,"line":400},[66,18202,18203],{},"    src\u002Fsetupfile.cpp \\\\\n",[66,18205,18206],{"class":68,"line":416},[66,18207,18208],{},"    src\u002Fmain.cpp \\\\\n",[66,18210,18211],{"class":68,"line":421},[66,18212,18213],{},"    src\u002Fconfigfile.cpp\n",[66,18215,18216],{"class":68,"line":485},[66,18217,18218],{},"FORMS = ui\u002Floadconfig.ui\n",[66,18220,18221],{"class":68,"line":490},[66,18222,276],{"emptyLinePlaceholder":275},[66,18224,18225],{"class":68,"line":520},[66,18226,18227],{},"DESTDIR = bin\n",[66,18229,18230],{"class":68,"line":546},[66,18231,18232],{},"MOC_DIR = build\n",[66,18234,18235],{"class":68,"line":558},[66,18236,18237],{},"OBJECTS_DIR = build\n",[66,18239,18240],{"class":68,"line":607},[66,18241,18242],{},"UI_DIR = build\n",[17,18244,18245,18246,18248],{},"Pour générer le ",[63,18247,4326],{},", vous pouvez faire comme d'habitude :",[56,18250,18252],{"className":58,"code":18251,"language":60,"meta":61,"style":61},"qmake-qt4 qgenconfig.pro\n",[63,18253,18254],{"__ignoreMap":61},[66,18255,18256,18259],{"class":68,"line":69},[66,18257,18258],{"class":72},"qmake-qt4",[66,18260,18261],{"class":76}," qgenconfig.pro\n",[4389,18263,18265],{"id":18264},"création-des-scripts","Création des scripts",[17,18267,18268,18269,18271,18272,44],{},"Pour créer les paquets, il faut un ensemble de script dans le dossier\n",[63,18270,1595],{},". Pour se faciliter la vie, il est possible de créer les scripts\navec ",[63,18273,18274],{},"dh_make",[56,18276,18278],{"className":58,"code":18277,"language":60,"meta":61,"style":61},"DEBFULLNAME=\"Ulrich Van Den Hekke\"\ndh_make -e ulrich.vdh@shadoware.org -n -s -c gpl\n",[63,18279,18280,18290],{"__ignoreMap":61},[66,18281,18282,18285,18287],{"class":68,"line":69},[66,18283,18284],{"class":437},"DEBFULLNAME",[66,18286,378],{"class":83},[66,18288,18289],{"class":76},"\"Ulrich Van Den Hekke\"\n",[66,18291,18292,18294,18297,18300,18303,18305,18308],{"class":68,"line":80},[66,18293,18274],{"class":72},[66,18295,18296],{"class":114}," -e",[66,18298,18299],{"class":76}," ulrich.vdh@shadoware.org",[66,18301,18302],{"class":114}," -n",[66,18304,127],{"class":114},[66,18306,18307],{"class":114}," -c",[66,18309,18310],{"class":76}," gpl\n",[17,18312,18313],{},"Voici la description de la liste des paramètres :",[162,18315,18316,18321,18327,18336,18342],{},[165,18317,18318,18320],{},[63,18319,18284],{}," indique le nom du mainteneur.",[165,18322,18323,18326],{},[63,18324,18325],{},"-e"," Permet de préciser l'email (suivis de l'email).",[165,18328,18329,18332,18333,18335],{},[63,18330,18331],{},"-n"," Produit un paquet natif pour ",[32,18334,12249],{}," (quand l'auteur fait\nses paquets lui-même).",[165,18337,18338,18341],{},[63,18339,18340],{},"-s"," Indique que le paquet ne va contenir qu'un simple exécutable\n(si vous voulez faire plusieurs paquets, il suffit de ne pas mettre\ncette option).",[165,18343,18344,18347,18348,1640],{},[63,18345,18346],{},"-c"," Indique la licence d'utilisation (ici ",[63,18349,18350],{},"gpl",[17,18352,18353],{},"Vous pouvez ensuite supprimer les fichiers exemples (mais pas\nnécessairement si vous voulez les étudier).",[56,18355,18357],{"className":58,"code":18356,"language":60,"meta":61,"style":61},"rm debian\u002F*.ex  debian\u002F*.EX  debian\u002Fdocs  debian\u002Fdirs\n",[63,18358,18359],{"__ignoreMap":61},[66,18360,18361,18364,18367,18369,18372,18375,18377,18380,18383],{"class":68,"line":69},[66,18362,18363],{"class":72},"rm",[66,18365,18366],{"class":76}," debian\u002F",[66,18368,593],{"class":240},[66,18370,18371],{"class":76},".ex",[66,18373,18374],{"class":76},"  debian\u002F",[66,18376,593],{"class":240},[66,18378,18379],{"class":76},".EX",[66,18381,18382],{"class":76},"  debian\u002Fdocs",[66,18384,18385],{"class":76},"  debian\u002Fdirs\n",[4862,18387,18389],{"id":18388},"paquet-simple","Paquet simple",[17,18391,18392],{},"Nous allons commencer par créer un paquet simple. Cela signifie qu'il\nn'y aura qu'un seul exécutable dans le paquet (pas de librairie, ...).",[17,18394,18395,18396,18399],{},"Dans le fichier ",[63,18397,18398],{},"control",", il faut que vous renseignez les informations\ndu paquet que vous allez créer.",[56,18401,18404],{"className":18402,"code":18403,"language":840},[838],"Source: qgenconfig\nSection: devel\nPriority: extra\nMaintainer: Ulrich Van Den Hekke \u003Culrich.vdh@shadoware.org>\nBuild-Depends: debhelper (>= 7)\nStandards-Version: 3.7.3\nHomepage: http:\u002F\u002Fprojects.shadoware.org\u002Fqgenconfig\n\nPackage: qgenconfig\nArchitecture: any\nDepends: ${shlibs:Depends}, ${misc:Depends}\nDescription: Create a config class in Qt after loading a XML file.\n    Load an XML description file of a settings object and create a class\n    that can be used to load and save information in a QSettings class. To\n    load information structure are used.\n",[63,18405,18403],{"__ignoreMap":61},[17,18407,18408,18409,18412,18413,18415],{},"Dans le paquet ci-dessus, on créait un paquet binaire et un paquet\nsource. Les variables de dépendance (dans ",[63,18410,18411],{},"Depends",") sont remplacées\nautomatiquement à la génération du paquet. La description est celle\nécrite dans ",[63,18414,12584],{},". La première ligne est la description courte, les\nsuivantes (précédées d'un espace) sont la description longue.",[17,18417,18418,18419,18422,18423,4405],{},"Ensuite on va remplacer le fichier ",[63,18420,18421],{},"debian\u002Frules"," en utilisant ",[63,18424,18425],{},"cdbs",[56,18427,18429],{"className":58,"code":18428,"language":60,"meta":61,"style":61},"#!\u002Fusr\u002Fbin\u002Fmake -f\ninclude \u002Fusr\u002Fshare\u002Fcdbs\u002F1\u002Frules\u002Fdebhelper.mk\ninclude \u002Fusr\u002Fshare\u002Fcdbs\u002F1\u002Fclass\u002Fqmake.mk\nQMAKE=qmake-qt4\n\ninstall\u002Fqgenconfig::\n    mkdir $(DEB_DESTDIR)\u002Fusr\u002F\n    mkdir $(DEB_DESTDIR)\u002Fusr\u002Fbin\u002F\n    cp $(CURDIR)\u002Fbin\u002Fqgenconfig $(DEB_DESTDIR)\u002Fusr\u002Fbin\u002F\n",[63,18430,18431,18436,18443,18450,18460,18464,18469,18485,18498],{"__ignoreMap":61},[66,18432,18433],{"class":68,"line":69},[66,18434,18435],{"class":351},"#!\u002Fusr\u002Fbin\u002Fmake -f\n",[66,18437,18438,18440],{"class":68,"line":80},[66,18439,4830],{"class":72},[66,18441,18442],{"class":76}," \u002Fusr\u002Fshare\u002Fcdbs\u002F1\u002Frules\u002Fdebhelper.mk\n",[66,18444,18445,18447],{"class":68,"line":89},[66,18446,4830],{"class":72},[66,18448,18449],{"class":76}," \u002Fusr\u002Fshare\u002Fcdbs\u002F1\u002Fclass\u002Fqmake.mk\n",[66,18451,18452,18455,18457],{"class":68,"line":279},[66,18453,18454],{"class":437},"QMAKE",[66,18456,378],{"class":83},[66,18458,18459],{"class":76},"qmake-qt4\n",[66,18461,18462],{"class":68,"line":307},[66,18463,276],{"emptyLinePlaceholder":275},[66,18465,18466],{"class":68,"line":329},[66,18467,18468],{"class":72},"install\u002Fqgenconfig::\n",[66,18470,18471,18474,18477,18480,18482],{"class":68,"line":334},[66,18472,18473],{"class":72},"    mkdir",[66,18475,18476],{"class":230}," $(",[66,18478,18479],{"class":72},"DEB_DESTDIR",[66,18481,1295],{"class":230},[66,18483,18484],{"class":76},"\u002Fusr\u002F\n",[66,18486,18487,18489,18491,18493,18495],{"class":68,"line":340},[66,18488,18473],{"class":72},[66,18490,18476],{"class":230},[66,18492,18479],{"class":72},[66,18494,1295],{"class":230},[66,18496,18497],{"class":76},"\u002Fusr\u002Fbin\u002F\n",[66,18499,18500,18503,18505,18508,18510,18513,18515,18517,18519],{"class":68,"line":355},[66,18501,18502],{"class":72},"    cp",[66,18504,18476],{"class":230},[66,18506,18507],{"class":72},"CURDIR",[66,18509,1295],{"class":230},[66,18511,18512],{"class":76},"\u002Fbin\u002Fqgenconfig",[66,18514,18476],{"class":230},[66,18516,18479],{"class":72},[66,18518,1295],{"class":230},[66,18520,18497],{"class":76},[17,18522,18523,18524,18527,18532,18533,1640],{},"En premier lieu on définit les variables pour la compilation, puis\nensuite on définit les opérations d'installations dans la cible\n",[63,18525,18526],{},"install\u002Fqgenconfig",[1607,18528,18529],{},[39,18530,461],{"href":1611,"ariaDescribedBy":18531,"dataFootnoteRef":61,"id":1614},[1613],".Dans les opérations, vous allez copier\nvotre exécutable dans le dossier de génération de debian (dossier\n",[63,18534,18535],{},"debian\u002F\u003Ccible>",[4862,18537,18539],{"id":18538},"paquet-multiple","Paquet multiple",[17,18541,18542,18543,18545,18546,18548,18549,2457],{},"Créer plusieurs paquets à partir d'une même source avec ",[63,18544,18425],{}," est assez\nsimple. Il suffit de rajouter des cibles, correspondantes au fichier\n",[63,18547,18398],{},", dans le fichier ",[63,18550,18551],{},"rules",[17,18553,18554,18555,18557],{},"Dans le fichier de ",[63,18556,18398],{}," on va avoir plusieurs paquets binaires pour\nun seul paquet source.",[56,18559,18562],{"className":18560,"code":18561,"language":840},[838],"Source: xinx\nSection: devel\nPriority: extra\nMaintainer: Ulrich Van Den Hekke \u003Cxinx@shadoware.org>\nBuild-Depends: debhelper (>= 7)\nStandards-Version: 3.7.3\nHomepage: http:\u002F\u002Fxinx.shadoware.org\u002F\n\nPackage: xinx\nSection: devel\nArchitecture: any\nDepends: ${shlibs:Depends}, ${misc:Depends}, xinx-scripts (>= 0.7.2.0)\nRecommends: xinx-plugins-services, xinx-plugins-cvs, xinx-plugins-svn\nSuggests: xinx-doc\nDescription: XSL\u002FJS\u002FHTML editor for Generix\n    XINX is an editor of XSL stylesheet, JavaScript, Cascading Style Sheet.\n    This editor is used with egx.\n\nPackage: xinx-doc\nSection: doc\nArchitecture: all\nDepends: xinx (>= 0.7.2.0)\nDescription: Documentation for xinx\n    Technical Documentation of XINX\n",[63,18563,18561],{"__ignoreMap":61},[17,18565,18566,18567,18569,18570,18572,18577],{},"Nous allons définir dans le fichier ",[63,18568,18551],{}," les différentes cibles que\nnous avons dans le fichier ",[63,18571,18398],{},[1607,18573,18574],{},[39,18575,476],{"href":1637,"ariaDescribedBy":18576,"dataFootnoteRef":61,"id":1639},[1613],"^.",[56,18579,18581],{"className":58,"code":18580,"language":60,"meta":61,"style":61},"#!\u002Fusr\u002Fbin\u002Fmake -f\ninclude \u002Fusr\u002Fshare\u002Fcdbs\u002F1\u002Frules\u002Fdebhelper.mk\ninclude \u002Fusr\u002Fshare\u002Fcdbs\u002F1\u002Fclass\u002Fqmake.mk\nQMAKE=qmake-qt4 project.pro\n\ninstall\u002Fxinx::\n    mkdir $(CURDIR)\u002Fdebian\u002Fxinx\u002Fusr\u002F\n    mkdir $(CURDIR)\u002Fdebian\u002Fxinx\u002Fusr\u002Fbin\u002F\n    cp $(CURDIR)\u002Fxinx\u002Fxinx $(CURDIR)\u002Fdebian\u002Fxinx\u002Fusr\u002Fbin\u002F\n    cp $(CURDIR)\u002Fxinxprojectwizard\u002Fxinxprojectwizard $(CURDIR)\u002Fdebian\u002Fxinx\u002Fusr\u002Fbin\u002F\n\n    mkdir $(CURDIR)\u002Fdebian\u002Fxinx\u002Fusr\u002Flib\u002F\n    cp -a $(CURDIR)\u002Flibxinx\u002Flibsharedxinx* $(CURDIR)\u002Fdebian\u002Fxinx\u002Fusr\u002Flib\u002F\n    cp -a $(CURDIR)\u002Fcomponents\u002Flibxinxcmp* $(CURDIR)\u002Fdebian\u002Fxinx\u002Fusr\u002Flib\u002F\n\ninstall\u002Fxinx-doc::\n    mkdir $(CURDIR)\u002Fdebian\u002Fxinx-doc\u002Fusr\u002F\n    mkdir $(CURDIR)\u002Fdebian\u002Fxinx-doc\u002Fusr\u002Fshare\u002F\n    mkdir $(CURDIR)\u002Fdebian\u002Fxinx-doc\u002Fusr\u002Fshare\u002Fdoc\u002F\n    mkdir $(CURDIR)\u002Fdebian\u002Fxinx-doc\u002Fusr\u002Fshare\u002Fdoc\u002Fxinx-doc\u002F\n    cp -a $(CURDIR)\u002Fdoc\u002F* $(CURDIR)\u002Fdebian\u002Fxinx-doc\u002Fusr\u002Fshare\u002Fdoc\u002Fxinx-doc\u002F\n    rm -rf $(CURDIR)\u002Fdebian\u002Fxinx-doc\u002Fusr\u002Fshare\u002Fdoc\u002Fxinx-doc\u002Fhtml\u002F.svn\n",[63,18582,18583,18587,18593,18599,18610,18614,18619,18632,18645,18666,18687,18691,18704,18730,18755,18759,18764,18777,18790,18803,18816,18841],{"__ignoreMap":61},[66,18584,18585],{"class":68,"line":69},[66,18586,18435],{"class":351},[66,18588,18589,18591],{"class":68,"line":80},[66,18590,4830],{"class":72},[66,18592,18442],{"class":76},[66,18594,18595,18597],{"class":68,"line":89},[66,18596,4830],{"class":72},[66,18598,18449],{"class":76},[66,18600,18601,18603,18605,18607],{"class":68,"line":279},[66,18602,18454],{"class":437},[66,18604,378],{"class":83},[66,18606,18258],{"class":76},[66,18608,18609],{"class":72}," project.pro\n",[66,18611,18612],{"class":68,"line":307},[66,18613,276],{"emptyLinePlaceholder":275},[66,18615,18616],{"class":68,"line":329},[66,18617,18618],{"class":72},"install\u002Fxinx::\n",[66,18620,18621,18623,18625,18627,18629],{"class":68,"line":334},[66,18622,18473],{"class":72},[66,18624,18476],{"class":230},[66,18626,18507],{"class":72},[66,18628,1295],{"class":230},[66,18630,18631],{"class":76},"\u002Fdebian\u002Fxinx\u002Fusr\u002F\n",[66,18633,18634,18636,18638,18640,18642],{"class":68,"line":340},[66,18635,18473],{"class":72},[66,18637,18476],{"class":230},[66,18639,18507],{"class":72},[66,18641,1295],{"class":230},[66,18643,18644],{"class":76},"\u002Fdebian\u002Fxinx\u002Fusr\u002Fbin\u002F\n",[66,18646,18647,18649,18651,18653,18655,18658,18660,18662,18664],{"class":68,"line":355},[66,18648,18502],{"class":72},[66,18650,18476],{"class":230},[66,18652,18507],{"class":72},[66,18654,1295],{"class":230},[66,18656,18657],{"class":76},"\u002Fxinx\u002Fxinx",[66,18659,18476],{"class":230},[66,18661,18507],{"class":72},[66,18663,1295],{"class":230},[66,18665,18644],{"class":76},[66,18667,18668,18670,18672,18674,18676,18679,18681,18683,18685],{"class":68,"line":372},[66,18669,18502],{"class":72},[66,18671,18476],{"class":230},[66,18673,18507],{"class":72},[66,18675,1295],{"class":230},[66,18677,18678],{"class":76},"\u002Fxinxprojectwizard\u002Fxinxprojectwizard",[66,18680,18476],{"class":230},[66,18682,18507],{"class":72},[66,18684,1295],{"class":230},[66,18686,18644],{"class":76},[66,18688,18689],{"class":68,"line":395},[66,18690,276],{"emptyLinePlaceholder":275},[66,18692,18693,18695,18697,18699,18701],{"class":68,"line":400},[66,18694,18473],{"class":72},[66,18696,18476],{"class":230},[66,18698,18507],{"class":72},[66,18700,1295],{"class":230},[66,18702,18703],{"class":76},"\u002Fdebian\u002Fxinx\u002Fusr\u002Flib\u002F\n",[66,18705,18706,18708,18711,18713,18715,18717,18720,18722,18724,18726,18728],{"class":68,"line":416},[66,18707,18502],{"class":72},[66,18709,18710],{"class":114}," -a",[66,18712,18476],{"class":230},[66,18714,18507],{"class":72},[66,18716,1295],{"class":230},[66,18718,18719],{"class":76},"\u002Flibxinx\u002Flibsharedxinx",[66,18721,593],{"class":240},[66,18723,18476],{"class":230},[66,18725,18507],{"class":72},[66,18727,1295],{"class":230},[66,18729,18703],{"class":76},[66,18731,18732,18734,18736,18738,18740,18742,18745,18747,18749,18751,18753],{"class":68,"line":421},[66,18733,18502],{"class":72},[66,18735,18710],{"class":114},[66,18737,18476],{"class":230},[66,18739,18507],{"class":72},[66,18741,1295],{"class":230},[66,18743,18744],{"class":76},"\u002Fcomponents\u002Flibxinxcmp",[66,18746,593],{"class":240},[66,18748,18476],{"class":230},[66,18750,18507],{"class":72},[66,18752,1295],{"class":230},[66,18754,18703],{"class":76},[66,18756,18757],{"class":68,"line":485},[66,18758,276],{"emptyLinePlaceholder":275},[66,18760,18761],{"class":68,"line":490},[66,18762,18763],{"class":72},"install\u002Fxinx-doc::\n",[66,18765,18766,18768,18770,18772,18774],{"class":68,"line":520},[66,18767,18473],{"class":72},[66,18769,18476],{"class":230},[66,18771,18507],{"class":72},[66,18773,1295],{"class":230},[66,18775,18776],{"class":76},"\u002Fdebian\u002Fxinx-doc\u002Fusr\u002F\n",[66,18778,18779,18781,18783,18785,18787],{"class":68,"line":546},[66,18780,18473],{"class":72},[66,18782,18476],{"class":230},[66,18784,18507],{"class":72},[66,18786,1295],{"class":230},[66,18788,18789],{"class":76},"\u002Fdebian\u002Fxinx-doc\u002Fusr\u002Fshare\u002F\n",[66,18791,18792,18794,18796,18798,18800],{"class":68,"line":558},[66,18793,18473],{"class":72},[66,18795,18476],{"class":230},[66,18797,18507],{"class":72},[66,18799,1295],{"class":230},[66,18801,18802],{"class":76},"\u002Fdebian\u002Fxinx-doc\u002Fusr\u002Fshare\u002Fdoc\u002F\n",[66,18804,18805,18807,18809,18811,18813],{"class":68,"line":607},[66,18806,18473],{"class":72},[66,18808,18476],{"class":230},[66,18810,18507],{"class":72},[66,18812,1295],{"class":230},[66,18814,18815],{"class":76},"\u002Fdebian\u002Fxinx-doc\u002Fusr\u002Fshare\u002Fdoc\u002Fxinx-doc\u002F\n",[66,18817,18818,18820,18822,18824,18826,18828,18831,18833,18835,18837,18839],{"class":68,"line":645},[66,18819,18502],{"class":72},[66,18821,18710],{"class":114},[66,18823,18476],{"class":230},[66,18825,18507],{"class":72},[66,18827,1295],{"class":230},[66,18829,18830],{"class":76},"\u002Fdoc\u002F",[66,18832,593],{"class":240},[66,18834,18476],{"class":230},[66,18836,18507],{"class":72},[66,18838,1295],{"class":230},[66,18840,18815],{"class":76},[66,18842,18843,18846,18849,18851,18853,18855],{"class":68,"line":653},[66,18844,18845],{"class":72},"    rm",[66,18847,18848],{"class":114}," -rf",[66,18850,18476],{"class":230},[66,18852,18507],{"class":72},[66,18854,1295],{"class":230},[66,18856,18857],{"class":76},"\u002Fdebian\u002Fxinx-doc\u002Fusr\u002Fshare\u002Fdoc\u002Fxinx-doc\u002Fhtml\u002F.svn\n",[17,18859,18860],{},"Ici on génère deux paquets, le paquet binaire et la documentation.",[4389,18862,18864],{"id":18863},"génération-du-paquet","Génération du paquet",[4862,18866,18868],{"id":18867},"mise-à-jour-des-informations-du-paquets","Mise à jour des informations du paquets",[162,18870,18871],{},[165,18872,18873],{},"Pour modifier le changelog sur la version courante",[56,18875,18877],{"className":58,"code":18876,"language":60,"meta":61,"style":61},"dch -a\n",[63,18878,18879],{"__ignoreMap":61},[66,18880,18881,18884],{"class":68,"line":69},[66,18882,18883],{"class":72},"dch",[66,18885,18886],{"class":114}," -a\n",[162,18888,18889],{},[165,18890,18891],{},"Pour créer une nouvelle version",[56,18893,18895],{"className":58,"code":18894,"language":60,"meta":61,"style":61},"dch -i\n",[63,18896,18897],{"__ignoreMap":61},[66,18898,18899,18901],{"class":68,"line":69},[66,18900,18883],{"class":72},[66,18902,18903],{"class":114}," -i\n",[4862,18905,18117],{"id":18906},"création-du-paquet-1",[56,18908,18910],{"className":58,"code":18909,"language":60,"meta":61,"style":61},"dpkg-buildpackage -rfakeroot\n",[63,18911,18912],{"__ignoreMap":61},[66,18913,18914,18917],{"class":68,"line":69},[66,18915,18916],{"class":72},"dpkg-buildpackage",[66,18918,18919],{"class":114}," -rfakeroot\n",[17,18921,18922],{},"L'application va signer le paquet s'il trouve la clé assignée à\nl'utilisateur.",[12,18924,18926],{"id":18925},"création-dun-dépôt","Création d'un dépôt",[17,18928,18929],{},"Après avoir créé des paquets, il peut-être intéressant de créer un dépôt\npour installer ces paquets. voici la marche à suivre pour créer le\ndépôt.",[17,18931,18932,18933,1640],{},"Sur votre serveur internet (nous ne parlerons pas ici de la mise à\ndisposition sur Internet), vous allez devoir créer un dossier contenant\nvotre référentiel (exemple : ",[63,18934,18935],{},"\u002Fwww\u002Fsites\u002Fapt",[4389,18937,18939],{"id":18938},"création-de-larborescence","Création de l'arborescence",[17,18941,18942],{},"Vous allez devoir créer une arborescence comme suite :",[56,18944,18947],{"className":18945,"code":18946,"language":840},[838],"dists\n    +- main\n        |- binary-i386\n        |- binary-amd64\n        +- source\n",[63,18948,18946],{"__ignoreMap":61},[17,18950,18951,18952,18955,18956,251,18959,18962,18963,18966,18967,44],{},"Parmi les fichiers générés vous allez devoir mettre le fichier ",[63,18953,18954],{},".deb","\ndans le dossier binaire, et les fichiers ",[63,18957,18958],{},".changes",[63,18960,18961],{},".dsc",", et\n",[63,18964,18965],{},".tar.gz"," dans le dossier ",[63,18968,4366],{},[4389,18970,18972],{"id":18971},"création-dun-fichier-apt-ftparchiveconf","Création d'un fichier apt-ftparchive.conf",[17,18974,18975,18976,18979],{},"Nous allons commencer par créer un fichier ",[63,18977,18978],{},"apt-ftparchive.conf"," dans\nlequel nous allons définir les fichiers à créer.",[56,18981,18984],{"className":18982,"code":18983,"language":840},[838],"Dir {\n    ArchiveDir \".\";\n    CacheDir \".\";\n};\n\nTree \"dists\u002Funstable\" {\n    Sections \"main\";\n    Architectures \"amd64 source\";\n};\n\nBinDirectory \"dists\u002Funstable\u002Fmain\u002Fbinary-amd64\" {\n    Packages \"dists\u002Funstable\u002Fmain\u002Fbinary-amd64\u002FPackages\";\n    Contents \"dists\u002Funstable\u002FContents-amd64\";\n    SrcPackages \"dists\u002Funstable\u002Fmain\u002Fsource\u002FSources\";\n};\n",[63,18985,18983],{"__ignoreMap":61},[4389,18987,18989],{"id":18988},"création-du-fichier-apt-unstable-releaseconf","Création du fichier apt-unstable-release.conf",[56,18991,18994],{"className":18992,"code":18993,"language":840},[838],"APT::FTPArchive::Release::Origin    \"shadoware.org\";\nAPT::FTPArchive::Release::Label     \"shadoware.org\";\nAPT::FTPArchive::Release::Suite     \"unstable\";\nAPT::FTPArchive::Release::Codename   \"unstable\";\nAPT::FTPArchive::Release::Architectures  \"amd64 source\";\nAPT::FTPArchive::Release::Components \"main\";\nAPT::FTPArchive::Release::Description    \"Paquets du site Shadoware.Org\";\n",[63,18995,18993],{"__ignoreMap":61},[4389,18997,18999],{"id":18998},"création-du-fichier-update-archivesh","Création du fichier update-archive.sh",[17,19001,19002],{},"Ce fichier est celui que l'on doit exécuter pour la génération du\ncontenu de l'arborescence :",[56,19004,19006],{"className":58,"code":19005,"language":60,"meta":61,"style":61},"apt-ftparchive generate apt-ftparchive.conf\napt-ftparchive -c apt-unstable-release.conf release dists\u002Funstable > dists\u002Funstable\u002FRelease\n",[63,19007,19008,19019],{"__ignoreMap":61},[66,19009,19010,19013,19016],{"class":68,"line":69},[66,19011,19012],{"class":72},"apt-ftparchive",[66,19014,19015],{"class":76}," generate",[66,19017,19018],{"class":76}," apt-ftparchive.conf\n",[66,19020,19021,19023,19025,19028,19031,19034,19037],{"class":68,"line":80},[66,19022,19012],{"class":72},[66,19024,18307],{"class":114},[66,19026,19027],{"class":76}," apt-unstable-release.conf",[66,19029,19030],{"class":76}," release",[66,19032,19033],{"class":76}," dists\u002Funstable",[66,19035,19036],{"class":230}," > ",[66,19038,19039],{"class":76},"dists\u002Funstable\u002FRelease\n",[3349,19041,19043,19046],{"className":19042,"dataFootnotes":61},[3352],[1432,19044,3357],{"className":19045,"id":1613},[3356],[3359,19047,19048,19056],{},[165,19049,19050,19051,17533,19053],{"id":3363},"D'autres cibles sont disponibles (cf la doc de ",[63,19052,18425],{},[39,19054,3371],{"href":3367,"ariaLabel":3368,"className":19055,"dataFootnoteBackref":61},[3370],[165,19057,19058,19059,19062,19063,3438,19066],{"id":3374},"A cause d'un bogue, ou d'une mauvaise utilisation, la variable ",[63,19060,19061],{},"$(DEB_DESTDIR)"," ne me ramenait pas la bonne valeur, je l'ai donc remplacée par ",[63,19064,19065],{},"$(CURDIR)\u002Fdebian",[39,19067,3371],{"href":3378,"ariaLabel":3379,"className":19068,"dataFootnoteBackref":61},[3370],[1545,19070,19071],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .sU0A5, html code.shiki .sU0A5{--shiki-default:#E5C07B}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}",{"title":61,"searchDepth":80,"depth":80,"links":19073},[19074,19075,19076,19077],{"id":18080,"depth":89,"text":18081},{"id":18116,"depth":89,"text":18117},{"id":18925,"depth":89,"text":18926},{"id":1613,"depth":80,"text":3357},"2008-09-08","A titre personnel je fabrique quelques programmes en Qt. Comme j'utilise\nun système Gnu\u002FDebian, j'ai cherché à fabriquer des paquets pour mon\nsystème (plus pour le plaisir qu'autre chose, car la plus grande partie\nde mes utilisateurs sont sous MS\u002FWindows).",{"type":9,"value":19081},[19082,19088],[17,19083,18066,19084,18069,19086,1640],{},[32,19085,12249],{},[32,19087,12256],{},[17,19089,18074,19090,18077],{},[32,19091,12249],{},{},"\u002Fpost\u002Fpaquet-debian-et-qt",{"title":18061,"description":19079},"paquet-debian-et-qt","posts\u002FProgrammation\u002F2008-09-08-paquet-debian-et-qt",[1595,1592],"UfskBB2vEveCnHyHdgHEScfMRoTQzydi1tuF-O_x8Ik",{"id":19100,"title":19101,"author":7,"body":19102,"category":1560,"categorySlug":1561,"date":19177,"description":19178,"excerpt":19179,"extension":1584,"location":1585,"meta":19200,"navigation":275,"path":19201,"published":275,"seo":19202,"slug":19203,"stem":19204,"tags":19205,"timeToRead":69,"__hash__":19206},"posts\u002Fposts\u002FProgrammation\u002F2008-01-21-memo-qt.md","Mémo Qt",{"type":9,"value":19103,"toc":19173},[19104,19112,19115,19133,19137,19139,19144,19146,19149,19155,19157,19163,19167],[17,19105,19106,19107,44],{},"Ceci est un petit mémo pour me permettre de ne pas oublier quelques\nastuces lors de la programmation avec Qt. En parlant de cela, je me suis\ncommandé le livre suivant : ",[39,19108,19111],{"href":19109,"rel":19110},"http:\u002F\u002Fwww.amazon.fr\u002FGUI-Programming-Qt4-Jasmin-Blanchette\u002Fdp\u002F0132354160\u002Fref=sr_11_1?ie=UTF8&qid=1199972515&sr=11-1",[43],"C++ GUI Programming with Qt4",[12,19113,13009],{"id":19114},"qabstractitemmodel",[162,19116,19117,19120],{},[165,19118,19119],{},"Lors de l'insertion (avec beginInsertRows()), les éléments insérés\nne doivent pas contenir de sous éléments (rowCount() == 0) sous\npeine de causer des plantages.",[165,19121,19122,19123,3581,19128],{},"Un model de donnée interne, pouvant être utilisé avec\nQAbstractItemModel pour afficher une arborescence et étant capable\nde se rafraîchir à la lecture d'un fichier, se trouve dans les\nfichiers ",[39,19124,19127],{"href":19125,"rel":19126},"http:\u002F\u002Fhg.shadoware.org\u002FSoftware\u002FXINX\u002Fxinx\u002Ffiles\u002F53bd629daf731398437a8c2f328e7b4015a013ca\u002Flibxinx\u002Ffilecontentstructure.cpp",[43],"filecontentstructure.cpp",[39,19129,19132],{"href":19130,"rel":19131},"http:\u002F\u002Fhg.shadoware.org\u002FSoftware\u002FXINX\u002Fxinx\u002Ffiles\u002F53bd629daf731398437a8c2f328e7b4015a013ca\u002Flibxinx\u002Ffilecontentstructure.h",[43],"filecontentstructure.h",[12,19134,19136],{"id":19135},"cmake-et-qt","CMake et Qt",[4389,19138,5421],{"id":5420},[56,19140,19142],{"className":19141,"code":5424,"language":840},[838],[63,19143,5424],{"__ignoreMap":61},[4389,19145,5239],{"id":5238},[4862,19147,19148],{"id":19148},"dynamique",[56,19150,19153],{"className":19151,"code":19152,"language":840},[838],"add_definitions(${QT_DEFINITIONS})\nadd_definitions(-DQT_PLUGIN)\nadd_definitions(-DQT_NO_DEBUG)\nadd_definitions(-DQT_SHARED)\nadd_library(webplugin SHARED ${webplugin_SRCS} ${webplugin_MOC_SRCS})\n",[63,19154,19152],{"__ignoreMap":61},[4862,19156,8058],{"id":8058},[56,19158,19161],{"className":19159,"code":19160,"language":840},[838],"?\n",[63,19162,19160],{"__ignoreMap":61},[4389,19164,19166],{"id":19165},"compilation-de-fichier-rc-pour-windows","Compilation de fichier RC pour Windows",[56,19168,19171],{"className":19169,"code":19170,"language":840},[838],"if(WIN32)\n    add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}\u002Fxinx_ico.obj\n           COMMAND windres.exe -I${CMAKE_CURRENT_SOURCE_DIR} -o ${CMAKE_CURRENT_BINARY_DIR}\u002Fxinx_ico.obj -i${CMAKE_CURRENT_SOURCE_DIR}\u002F${xinx_RCS}\n    )\n    set(xinx_RESS ${CMAKE_CURRENT_BINARY_DIR}\u002Fxinx_ico.obj)\nendif(WIN32)\n",[63,19172,19170],{"__ignoreMap":61},{"title":61,"searchDepth":80,"depth":80,"links":19174},[19175,19176],{"id":19114,"depth":89,"text":13009},{"id":19135,"depth":89,"text":19136},"2008-01-21","Ceci est un petit mémo pour me permettre de ne pas oublier quelques\nastuces lors de la programmation avec Qt. En parlant de cela, je me suis\ncommandé le livre suivant : C++ GUI Programming with Qt4.",{"type":9,"value":19180},[19181,19186,19188],[17,19182,19106,19183,44],{},[39,19184,19111],{"href":19109,"rel":19185},[43],[12,19187,13009],{"id":19114},[162,19189,19190,19192],{},[165,19191,19119],{},[165,19193,19122,19194,3581,19197],{},[39,19195,19127],{"href":19125,"rel":19196},[43],[39,19198,19132],{"href":19130,"rel":19199},[43],{},"\u002Fpost\u002Fmemo-qt",{"title":19101,"description":19178},"memo-qt","posts\u002FProgrammation\u002F2008-01-21-memo-qt",[1592],"LurBRat5GKyW_n9EoVty1Vi5WkYd8uVKKIfb9AwdIE4",{"id":19208,"title":19209,"author":7,"body":19210,"category":3556,"categorySlug":3756,"date":19345,"description":61,"excerpt":19346,"extension":1584,"location":1585,"meta":19372,"navigation":275,"path":19373,"published":275,"seo":19374,"slug":19375,"stem":19376,"tags":19377,"timeToRead":89,"__hash__":19378},"posts\u002Fposts\u002FKMDAlert\u002F2007-08-17-kmdalert-logiciel-de-surveillance-raid.md","KMDAlert - Logiciel de surveillance de périphériques RAID",{"type":9,"value":19211,"toc":19337},[19212,19214,19220,19226,19233,19244,19247,19250,19253,19255,19269,19272,19275,19278,19280,19283,19306,19308,19310,19315,19317,19330,19332,19334],[1432,19213,3514],{"id":3513},[17,19215,19216,19217,19219],{},"Possédant chez moi des disques durs en RAID logiciel ",[32,19218,17613],{},", j'ai\ntoujours ressenti le besoin d'avoir une application graphique minimale\npour m'avertir des changements d'états du RAID. (Par exemple un disque\ndur est défectueux, le RAID est dégradé, le RAID est en reconstruction).\nEt, par exemple, dans le cas de la reconstruction être averti à la fin\nde la reconstruction.",[17,19221,19222,19223,19225],{},"KMDAlert est un petit logiciel ",[32,19224,17613],{}," que j'ai écrit, et permettant\nd'afficher des informations sur les volumes RAID (gérés à l'aide du\nmodule noyau md-mod) dans la boîte à miniature (SystemTray).",[17,19227,19228,19229,19232],{},"L'icône change suivant l'état du RAID (",[8154,19230,19231],{},"ATTENTION : Les icônes\nchoisies sont moches, si un graphiste veut me proposer d'autres icônes,\nje reste ouvert aux propositions",") :",[162,19234,19235,19238,19241],{},[165,19236,19237],{},"dégradé",[165,19239,19240],{},"en cours de synchronisation",[165,19242,19243],{},"ou tout simplement Ok.",[17,19245,19246],{},"Des messages de notifications informent aussi l'utilisateur du\nchangement d'état d'un disque sur le RAID (par exemple le disque est en\néchec, supprimé, ajouté, la synchronisation démarre ou est terminée).",[17,19248,19249],{},"Le logiciel est actuellement uniquement disponible pour KDE 3. Je\nn'ai pas encore pris le temps de la ré-écrire.",[17,19251,19252],{},"Bien que cette application a été écrite dans mon cas particulier (un\nRAID 1) je me suis dit qu'elle devrait fonctionner pour les autres types\nde RAID et intéresser d'autres personnes.",[1432,19254,3550],{"id":3549},[17,19256,19257,19258,19260,19261,3565,19263,251,19265,3572,19267,3575],{},"Pour fonctionner KMDAlert nécessite que le dossier ",[63,19259,3560],{}," soit monté et\nque ",[63,19262,3564],{},[63,19264,3568],{},[63,19266,3571],{},[63,19268,3556],{},[17,19270,19271],{},"L'application a été développée sur Gnu\u002FDebian Etch donc sur un KDE 3.5\navec un noyau 2.6.18.",[17,19273,19274],{},"KMDAlert ne nécessite pas de Inotify. KMDAlert lit le contenu de\nplusieurs fichiers dans le dossier \u002Fsys toutes les 6 secondes pour être\ninformé de la modification de l'état du périphérique. En effet sur le\nnoyau 2.6.18 que je possède, Inotify n'est pas averti des modifications\nfaites sur le système de fichier \u002Fsys. Les dates de ces fichiers ne sont\npas non plus modifiées. Si quelqu'un a une autre méthode à me proposer,\nje reste ouvert à toutes propositions.",[17,19276,19277],{},"KMDAlert est une application écrite en utilisant les librairies de KDE,\nmais devrait tout de même fonctionner sous Gnome. Les messages de\nnotification utilisent donc le système de notification de KDE (bien que\nje n'utilise pas toutes ses possibilités).",[1432,19279,3621],{"id":3620},[17,19281,19282],{},"La compilation et l'installation de KMDAlert se fait à l'aide du trio\nhabituel :",[56,19284,19286],{"className":58,"code":19285,"language":60,"meta":61,"style":61},".\u002Fconfigure --prefix=\u002Fusr\u002Flocal\u002F\nmake\nmake install\n",[63,19287,19288,19296,19300],{"__ignoreMap":61},[66,19289,19290,19293],{"class":68,"line":69},[66,19291,19292],{"class":72},".\u002Fconfigure",[66,19294,19295],{"class":114}," --prefix=\u002Fusr\u002Flocal\u002F\n",[66,19297,19298],{"class":68,"line":80},[66,19299,5483],{"class":72},[66,19301,19302,19304],{"class":68,"line":89},[66,19303,3694],{"class":72},[66,19305,3697],{"class":76},[17,19307,3700],{},[1432,19309,3704],{"id":3703},[17,19311,3707,19312],{},[39,19313,3712],{"href":3710,"rel":19314},[43],[1432,19316,3716],{"id":3715},[162,19318,19319,19324],{},[165,19320,3721,19321,44],{},[39,19322,3726],{"href":3724,"rel":19323},[43],[165,19325,19326,19327,44],{},"Le dépot officiel pour télécharger les sources et participer :\n",[39,19328,3734],{"href":3732,"rel":19329},[43],[1432,19331,3741],{"id":3740},[17,19333,3744],{},[1545,19335,19336],{},"html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":61,"searchDepth":80,"depth":80,"links":19338},[19339,19340,19341,19342,19343,19344],{"id":3513,"depth":80,"text":3514},{"id":3549,"depth":80,"text":3550},{"id":3620,"depth":80,"text":3621},{"id":3703,"depth":80,"text":3704},{"id":3715,"depth":80,"text":3716},{"id":3740,"depth":80,"text":3741},"2007-08-17",{"type":9,"value":19347},[19348,19350,19354,19358,19362,19370],[1432,19349,3514],{"id":3513},[17,19351,19216,19352,19219],{},[32,19353,17613],{},[17,19355,19222,19356,19225],{},[32,19357,17613],{},[17,19359,19228,19360,19232],{},[8154,19361,19231],{},[162,19363,19364,19366,19368],{},[165,19365,19237],{},[165,19367,19240],{},[165,19369,19243],{},[17,19371,19246],{},{},"\u002Fpost\u002Fkmdalert-logiciel-de-surveillance-raid",{"title":19209,"description":61},"kmdalert-logiciel-de-surveillance-raid","posts\u002FKMDAlert\u002F2007-08-17-kmdalert-logiciel-de-surveillance-raid",[3788,1592,3756,3789],"PNNDW_nxCgCKf7lh8X7JuMHGPhrQnNwu5riYqVB4k-U",1777849587899]