Merge branch 'master' of https://bitbucket.org/caotek/dumas_gestion
This commit is contained in:
@@ -340,7 +340,7 @@ def get_status_by_id(request, code):
|
||||
return results
|
||||
|
||||
def get_motifs(request):
|
||||
query = """SELECT * FROM p_motfs;"""
|
||||
query = """SELECT * FROM p_motifs;"""
|
||||
results = request.dbsession.execute(query,).fetchall()
|
||||
return results
|
||||
|
||||
@@ -348,4 +348,37 @@ def get_factures_en_att(request, societe):
|
||||
query = """SELECT f.date, LPAD(f.no_id,6,'0') AS numero, f.nomcli, CONCAT(f.c_nom,'; ',f.c_adr,'; ',f.c_ville) AS chantier, f.totalht AS montant, f.status, s.libelle, f.nosin, f.nopol, f.usermaj
|
||||
FROM facture f JOIN p_statuts s ON f.STATUS = s.CODE WHERE f.societe=:societe AND f.STATUS < 8 ORDER BY f.societe, f.STATUS, f.nomcli;"""
|
||||
results = request.dbsession.execute(query, {'societe': societe}).fetchall()
|
||||
return results
|
||||
return results
|
||||
|
||||
def insert_dem_note(request, nodossier, type_note, logged_in):
|
||||
societe = nodossier[0:2]
|
||||
nochantier = int(nodossier[3:])
|
||||
# une note ou croquis
|
||||
query = "INSERT INTO dem_notes (societe, nochantier, type_note, usermaj) VALUES (:societe, :nochantier, :type_note, :logged_in);"
|
||||
execute_query(request, query, {'societe': societe, 'nochantier': nochantier, 'type_note': type_note, 'logged_in': logged_in})
|
||||
|
||||
def get_dem_notes(request, nodossier, noligne, type):
|
||||
societe = nodossier[0:2]
|
||||
nochantier = int(nodossier[3:])
|
||||
|
||||
if noligne == '0':
|
||||
query = "SELECT societe, nochantier, noligne, type_note, libelle FROM dem_notes WHERE societe = :societe AND nochantier = :nochantier AND type_note=:type ORDER BY libelle;"
|
||||
results = request.dbsession.execute(query, {'societe': societe, 'nochantier': nochantier, 'noligne': noligne, 'type': type}).fetchall()
|
||||
else:
|
||||
query = "SELECT * FROM dem_notes WHERE societe = :societe AND nochantier = :nochantier AND noligne = :noligne;"
|
||||
results = request.dbsession.execute(query, {'societe': societe, 'nochantier': nochantier, 'noligne': noligne}).first()
|
||||
return results
|
||||
|
||||
def delete_dem_note(request, nodossier, noligne):
|
||||
societe = nodossier[0:2]
|
||||
nochantier = int(nodossier[3:])
|
||||
# une note ou croquis
|
||||
query = "DELETE FROM dem_notes WHERE societe=:societe AND nochantier=:nochantier AND noligne=:noligne;"
|
||||
execute_query(request, query, {'societe': societe, 'nochantier': nochantier, 'noligne': noligne})
|
||||
|
||||
def update_dem_note(request, nodossier, noligne, notes):
|
||||
societe = nodossier[0:2]
|
||||
nochantier = int(nodossier[3:])
|
||||
# une note ou croquis
|
||||
query = "UPDATE dem_notes SET notes=:notes WHERE societe=:societe AND nochantier=:nochantier AND noligne=:noligne;"
|
||||
execute_query(request, query, {'societe': societe, 'nochantier': nochantier, 'noligne': noligne, 'notes': notes})
|
||||
|
||||
@@ -34,14 +34,18 @@ def includeme(config):
|
||||
config.add_route('facture_select', '/facture_select/{date}')
|
||||
config.add_route('facture_selected', '/facture_selected/{goto}/{date}/{nofacture}')
|
||||
# dossier
|
||||
config.add_route('croquis_edit','/croquis_edit/')
|
||||
config.add_route('demandes','/demandes')
|
||||
config.add_route('demandes_dl','/demandes_dl/{societe}/{email_from}/{email_uid}')
|
||||
config.add_route('dem_devis','/dem_devis')
|
||||
config.add_route('delete_img','/delete_img/{nodossier}/{norapport}/{origine}/{nomfic}')
|
||||
config.add_route('dossier_edit', '/dossier_edit/{nodossier}')
|
||||
config.add_route('dossier_lookup', '/dossier_lookup')
|
||||
config.add_route('dossier_select', '/dossier_select/{date}')
|
||||
config.add_route('dossier_selected', '/dossier_selected/{goto}/{date}/{nodossier}')
|
||||
config.add_route('dossier_view', '/dossier_view/{nodossier}')
|
||||
config.add_route('note_add','/note_add/{nodossier}')
|
||||
config.add_route('note_edit','/note_edit/{nodossier}/{noligne}')
|
||||
config.add_route('rdf_bill','/rdf_bill/{no_id}')
|
||||
config.add_route('rdf_client','/rdf_client/{no_id}')
|
||||
config.add_route('rdf_edit','/rdf_edit/{nodossier}/{date_inter}')
|
||||
@@ -53,7 +57,6 @@ def includeme(config):
|
||||
config.add_route('upload_doc', '/upload_doc/{nodossier}/{origine}')
|
||||
config.add_route('upload_img', '/upload_img/{norapport}/{origine}')
|
||||
config.add_route('upload_om', '/upload_om')
|
||||
config.add_route('dem_devis','/dem_devis')
|
||||
# parametres
|
||||
config.add_route('parametres', '/parametres')
|
||||
config.add_route('article_edit', '/article_edit/{ref}')
|
||||
|
||||
@@ -276,6 +276,10 @@ color: black;
|
||||
}
|
||||
}
|
||||
|
||||
#dessin {
|
||||
width: 1140px;
|
||||
height: 1140px;
|
||||
}
|
||||
|
||||
/* ne pas affichier l'url after the link */
|
||||
@media print {
|
||||
|
||||
88
mondumas/static/dist/drawingboard/drawingboard.css
vendored
Normal file
88
mondumas/static/dist/drawingboard/drawingboard.css
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
/* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js
|
||||
* Copyright (c) 2015 Emmanuel Pelletier
|
||||
* Licensed MIT */
|
||||
.drawing-board, .drawing-board * { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; }
|
||||
|
||||
.drawing-board-utils-hidden, .drawing-board-controls-hidden { display: none !important; }
|
||||
|
||||
.drawing-board { position: relative; display: block; }
|
||||
|
||||
.drawing-board-canvas-wrapper { position: relative; margin: 0; border: 1px solid #ddd; }
|
||||
|
||||
.drawing-board-canvas { position: absolute; top: 0; left: 0; z-index: 10; width: auto; }
|
||||
|
||||
.drawing-board-canvas { cursor: crosshair; z-index: 20; }
|
||||
|
||||
.drawing-board-cursor { position: absolute; top: 0; left: 0; pointer-events: none; border-radius: 50%; background: #ccc; background: rgba(0, 0, 0, 0.2); z-index: 30; }
|
||||
|
||||
.drawing-board-control > button, .drawing-board-control-colors-rainbows, .drawing-board-control-size .drawing-board-control-inner, .drawing-board-control-size-dropdown { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; overflow: hidden; border: none; background-color: #eee; padding: 2px 4px; border: 1px solid #ccc; box-shadow: 0 1px 3px -2px #121212, inset 0 2px 5px 0 rgba(255, 255, 255, 0.3); -webkit-box-shadow: 0 1px 3px -2px #121212, inset 0 2px 5px 0 rgba(255, 255, 255, 0.3); height: 28px; }
|
||||
|
||||
.drawing-board-control > button { cursor: pointer; min-width: 28px; line-height: 14px; }
|
||||
.drawing-board-control > button:hover, .drawing-board-control > button:focus { background-color: #ddd; }
|
||||
.drawing-board-control > button:active, .drawing-board-control > button.active { box-shadow: inset 0 1px 2px 0 rgba(0, 0, 0, 0.2); -webkit-box-shadow: inset 0 1px 2px 0 rgba(0, 0, 0, 0.2); background-color: #ddd; }
|
||||
.drawing-board-control > button[disabled] { color: gray; }
|
||||
.drawing-board-control > button[disabled]:hover, .drawing-board-control > button[disabled]:focus, .drawing-board-control > button[disabled]:active, .drawing-board-control > button[disabled].active { background-color: #eee; box-shadow: 0 1px 3px -2px #121212, inset 0 2px 5px 0 rgba(255, 255, 255, 0.3); -webkit-box-shadow: 0 1px 3px -2px #121212, inset 0 2px 5px 0 rgba(255, 255, 255, 0.3); cursor: default; }
|
||||
|
||||
.drawing-board-controls { margin: 0 auto; text-align: center; font-size: 0; display: table; border-spacing: 9.33333px 0; position: relative; min-height: 28px; }
|
||||
.drawing-board-controls[data-align="left"] { margin: 0; left: -9.33333px; }
|
||||
.drawing-board-controls[data-align="right"] { margin: 0 0 0 auto; right: -9.33333px; }
|
||||
.drawing-board-canvas-wrapper + .drawing-board-controls, .drawing-board-controls + .drawing-board-canvas-wrapper { margin-top: 5px; }
|
||||
|
||||
.drawing-board-controls-hidden { height: 0; min-height: 0; padding: 0; margin: 0; border: 0; }
|
||||
|
||||
.drawing-board-control { display: table-cell; border-collapse: separate; vertical-align: middle; font-size: 16px; height: 100%; }
|
||||
|
||||
.drawing-board-control-inner { position: relative; height: 100%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
|
||||
|
||||
.drawing-board-control > button { margin: 0; vertical-align: middle; }
|
||||
|
||||
.drawing-board-control-colors { font-size: 0; line-height: 0; }
|
||||
|
||||
.drawing-board-control-colors-current { border: 1px solid #ccc; cursor: pointer; display: inline-block; width: 26px; height: 26px; }
|
||||
|
||||
.drawing-board-control-colors-rainbows { display: inline-block; margin-left: 5px; position: absolute; left: 0; top: 33px; margin-left: 0; z-index: 100; width: 250px; height: auto; padding: 4px; }
|
||||
|
||||
.drawing-board-control-colors-rainbow { height: 18px; }
|
||||
|
||||
.drawing-board-control-colors-picker:first-child { margin-right: 5px; }
|
||||
|
||||
.drawing-board-control-colors-picker { display: inline-block; width: 18px; height: 18px; cursor: pointer; }
|
||||
|
||||
.drawing-board-control-colors-picker[data-color="rgba(255, 255, 255, 1)"] { width: 16px; height: 17px; border: 1px solid #ccc; border-bottom: none; }
|
||||
|
||||
.drawing-board-control-colors-picker:hover { width: 16px; height: 16px; border: 1px solid #555; }
|
||||
|
||||
.drawing-board-control-drawingmode > button { margin-right: 2px; }
|
||||
.drawing-board-control-drawingmode > button:last-child { margin-right: 0; }
|
||||
|
||||
.drawing-board-control-drawingmode-pencil-button { overflow: hidden; *text-indent: -9999px; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAe9JREFUeNpiZAACVlFRBhYREQZcQPnbNwa3N28YlL5+ZfgLFfvPwGD9m4FhIgsDHuAO0gTUDNKIBvyBmqt/MTDMY8Gl0f31azD7L6oUIxCnAzWmAPHBfwwM01AMUAV6JfPQIVwOYgVqqPnFyOjz6///O38YGKpAgmAD1OXlGdTk5PD5hgeouZudj8/uy9evP/78/dsFFPsJNiAoKIiBABAHap4oLi9v8fTNm48//v7NBwbgWZgkE7rqt8DY+A8JZRBW+cfIuEDT0NDlzadP3z98/doPFDuCrB7TAGFhBqCNIGwM9OcKUzs7+xdv3355+f79VqDYAiTDwZgJh7ONgYpnOvn4GL949erT7UePdgL5JVCD4fgBLBBxaX74+PG789evnwby0/8jKXgExIeB+CG6Af///1e9Ki9vFSAkZPzoyZPPJy9evA9MB77/sWiEARZkzV+/fvXYtGnTpG3btj28EBT0BqjZ5D8OjXCwPksUhA1Wpggf/PHjx/9169Y9EBERaUlgZmaIAcrLE4rk5sIqBqDmlefnRPzfWGX5EaSZm5ubgRloADGA5QZ3RgK7gESY4PMNn9ZtObPpzZvfU4DiYkiB/RcHG+S7fyxAMH/lFU2GOZd2bLx18/cEUMoD4j9I+DcS/RtJHGTYf4AAAwAxaOMYHjxKFwAAAABJRU5ErkJggg=='); background-position: 50% 50%; background-repeat: no-repeat; }
|
||||
.drawing-board-control-drawingmode-pencil-button:before { content: ""; display: block; width: 0; height: 100%; }
|
||||
|
||||
.drawing-board-control-drawingmode-eraser-button { overflow: hidden; *text-indent: -9999px; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAkpJREFUeNp0kk+IElEcx39vFBc9+OfQRTAwzFt4CaYOKStj6MoeculStzoIQSB4kCVckmDx4iGCXWYJIqjoVOzO1l4qT1F7WfBWHvxzDPyTB3XUmXn93suRybUffHmP997n9/cRsFgwGARJkiAcDsPlwgEIeEZQAhCRAkgAlOD6SQP4rgMFDWVnYCAQgFgsBqFQCBwOByzZNQOotPHx1RNCCCipu6bfb+zSnslkeOQVILPrBkAirbws9btdTEWAzZPXpfepOzaeGMBXwe/3w3+MwTc3Dl+UeghTiskbBvR6Pbh18mZHB0jjmxvCKhIfR37s3r+Sevf8ca/T4TBF2HTSODuDxP7uNjrZFFbBk8lEzOVyspa4ykGYw2zfbTb/7ilvok1YhlVVFfP5vDydTkHXdXDdlhZOOnPY4/HA0YPtp3h6LFjh8XgsFgoFGTPgsKm1zDr8ajTQh8Fh5eGjZzjGI8yjKlgjF4tFGdd/YKYmRja24hw+zu3sYe2HiH3hYzQjl8tleTQanWtou93G6Qngdrth6+1+9h6hTULJZ/PeziJXKhV5OByeg1ut1gJOp9NZTdNOcQ419ot+ggp1qoLdBFmqVmNpm3A8Huewy+Wq1RH8QH9zmBlJJpMRdCIqiiIPBgN+2MCGsW/r8/kgGo1m0fmpzWarseayHlmNeL1eFiWC0cRqtSr3+/3FpSiKHMZtjU1glbFyfKgLTqfzEka9OJvNeDnzz1JnCaFmqOl8ZdJY1SiDOXCiXKg1NtG5DIt0y6ov3dE/AgwAENFWYYLj4mYAAAAASUVORK5CYII='); background-position: 50% 50%; background-repeat: no-repeat; }
|
||||
.drawing-board-control-drawingmode-eraser-button:before { content: ""; display: block; width: 0; height: 100%; }
|
||||
|
||||
.drawing-board-control-drawingmode-filler-button { overflow: hidden; *text-indent: -9999px; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnNJREFUeNp0k0trE1EUx89MJpNJooYYXBgDNtCKdRPwlbqoCKUtaNVNA0Uo7UbMxoVPEARTXEi+QWfnwn6DEAlEkrSLttTGRiULEQlJ8yChmbzI++E50yTUJA78uMy953/u/557LmOz2WDEZ2m1WrckSRJSqdR2tVrdHQyYebwHtVoNuFHqTqczhQnWKaBYLDoKhcIuzgHDMKBSqeD20qd+LNdsNocSoFhRr9ctpVLJigl4xIIJQizLAmG4cAPa7bYcy9Iug5TL5UYikbD6/X7Rbre/IUcYe3WUW5ZsnQQzW9LpNOPz+UQc5aBM5mgdh7vI9FCCAesW2tnr9YqZTAby+bw8f3AQRP6853n+Ph5hemSCntjj8YjZbFYWx2IxeS2RSEMwuA87O79eqdXquVolK+GxnP0EPbHb7RZJSGABIR6PA11zJHKIR2MhHA5DIPDj7eH3j95KpfK60Wg8Yntil8slkqgnpioLghacTidoNDpEC3q9HnheCc3s1jZeLcW943pirPw/4lKpBkqlDubnl/riycnLsLy88EKj0fhzuRyZv8RFo1E6wpBYkiqy7Z54YmIcVlYeyOKC4mYwJ0nHRaQuM5vNT6hB/iceG7sIq6sPnwmC4MerDkby40AOCCoiddie1Wp92W7zQ2KTyQSLizNP8T0EsPLBbxEDnCj0GkM2qIEwyZRCobizsfH5A1ZXFhuN52F29vpz3HkL574mk8lj24Y5wsHkvjjoX0BOIWc5jruHzbK2ufmzEwpFO3jnDhQv4JoROYdoERVyGjEgZ8iBDlF3FzXo4go6utZ9lftY4N/dXisjR0i1G0ublv8KMAA0ZoUlicxrhwAAAABJRU5ErkJggg=='); background-position: 50% 50%; background-repeat: no-repeat; }
|
||||
.drawing-board-control-drawingmode-filler-button:before { content: ""; display: block; width: 0; height: 100%; }
|
||||
|
||||
.drawing-board-control-navigation > button { font-family: Helvetica, Arial, sans-serif; font-size: 14px; font-weight: bold; margin-right: 2px; }
|
||||
.drawing-board-control-navigation > button:last-child { margin-right: 0; }
|
||||
|
||||
.drawing-board-control-size[data-drawing-board-type="range"] .drawing-board-control-inner { width: 75px; }
|
||||
.drawing-board-control-size[data-drawing-board-type="dropdown"] .drawing-board-control-inner { overflow: visible; }
|
||||
|
||||
.drawing-board-control-size-range-input { position: relative; width: 100%; z-index: 100; margin: 0; padding: 0; border: 0; }
|
||||
|
||||
.drawing-board-control-size-range-current, .drawing-board-control-size-dropdown-current span, .drawing-board-control-size-dropdown span { display: block; background: #333; opacity: .8; }
|
||||
|
||||
.drawing-board-control-size-range-current { display: inline-block; opacity: .15; position: absolute; pointer-events: none; left: 50%; top: 50%; z-index: 50; }
|
||||
|
||||
.drawing-board-control-size-dropdown-current { display: block; height: 100%; width: 40px; overflow: hidden; position: relative; }
|
||||
.drawing-board-control-size-dropdown-current span { position: absolute; left: 50%; top: 50%; }
|
||||
|
||||
.drawing-board-control-size-dropdown { position: absolute; left: -6px; top: 33px; height: auto; list-style-type: none; margin: 0; padding: 0; z-index: 100; }
|
||||
.drawing-board-control-size-dropdown li { display: block; padding: 4px; margin: 3px 0; min-height: 16px; }
|
||||
.drawing-board-control-size-dropdown li:hover { background: #ccc; }
|
||||
.drawing-board-control-size-dropdown span { margin: 0 auto; }
|
||||
|
||||
.drawing-board-control-download-button { overflow: hidden; *text-indent: -9999px; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAoBJREFUeNqMkr9PU1EUx7/vR1tQ3yu10hAmTawtBSYSy2YccFOcnDQm/gewOLnj5GYMg4sdXFxkMca4OBAwdUBe/ZkIGFp+9tHXvh/3/fTcAm01aLzJybnn3nM+95tzrnDl6Tb+sibuTmWUWj3C6/Juk+LySUmyvt0FCKKA02ryOCy6LBiu15ngMbZ5DDCNBqIw6gKM+n4nECUJru3glKry8CpjQaHVYmC2rVH82DIMMMdGGARdwJ+SPNdFS9chx+MXDNMp/NzagWNatk/nQU/hiYAoih6FYTBCBs9zUXMCbAhx2OYOv351lPOJ3EwH4LteL6Dcp/Rfu3FrstDyIizt+agpaYxNDU0M9gl4v7Ck+TYrCYLQqZHUyTtdQBiutPSGUflczSXHs5lVKwZdSOBMvwztxVvN0RtzsiyXBFHsAvL5PBSnCpXV2getILFiE2SjspYbuZzPiDSZ2vOXmlvX5yQqTmMfg9ZXqtls1wnT09OHEyAq0aFLg/gSXsSWq9wWk+p9PrCoYTwcijdLOfE7UsEufN9HGIYnT4EnTGIXe1KqtNNIvuNnGamxfi7SgQD/nIJCTbzOPQ/SQh1pud7T4M6W/8qFIw/5WAr5m7Ozsw9UVc069Fls2yJzSC5/lnc9RhaHZVnfSqUnEgXP2oBqtYqBgYG2+mKxmOVADnAcB4yxHgD1RzehKKns/LyV4gUHBweQy+UyRkdH6UKJ6fQDFxcXoWkaXJeRuTgUGCdLQJ9bx72lGZimGWs2m+083oN+2iiFQiGxvLy8RrDzudyltgrG3N8U2G8CrPz4sGYYRqJSqWR4H/jNWbJhUjAWi8XG8R/L87yPpGCVttVfAgwAVpZR+8tZC08AAAAASUVORK5CYII='); background-position: 50% 50%; background-repeat: no-repeat; }
|
||||
.drawing-board-control-download-button:before { content: ""; display: block; width: 0; height: 100%; }
|
||||
1374
mondumas/static/dist/drawingboard/drawingboard.js
vendored
Normal file
1374
mondumas/static/dist/drawingboard/drawingboard.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5
mondumas/static/dist/drawingboard/drawingboard.min.css
vendored
Normal file
5
mondumas/static/dist/drawingboard/drawingboard.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
4
mondumas/static/dist/drawingboard/drawingboard.min.js
vendored
Normal file
4
mondumas/static/dist/drawingboard/drawingboard.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
16
mondumas/static/dist/drawingboard/drawingboard.nocontrol.css
vendored
Normal file
16
mondumas/static/dist/drawingboard/drawingboard.nocontrol.css
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
/* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js
|
||||
* Copyright (c) 2015 Emmanuel Pelletier
|
||||
* Licensed MIT */
|
||||
.drawing-board, .drawing-board * { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; }
|
||||
|
||||
.drawing-board-utils-hidden { display: none !important; }
|
||||
|
||||
.drawing-board { position: relative; display: block; }
|
||||
|
||||
.drawing-board-canvas-wrapper { position: relative; margin: 0; border: 1px solid #ddd; }
|
||||
|
||||
.drawing-board-canvas { position: absolute; top: 0; left: 0; z-index: 10; width: auto; }
|
||||
|
||||
.drawing-board-canvas { cursor: crosshair; z-index: 20; }
|
||||
|
||||
.drawing-board-cursor { position: absolute; top: 0; left: 0; pointer-events: none; border-radius: 50%; background: #ccc; background: rgba(0, 0, 0, 0.2); z-index: 30; }
|
||||
971
mondumas/static/dist/drawingboard/drawingboard.nocontrol.js
vendored
Normal file
971
mondumas/static/dist/drawingboard/drawingboard.nocontrol.js
vendored
Normal file
@@ -0,0 +1,971 @@
|
||||
/* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js
|
||||
* Copyright (c) 2015 Emmanuel Pelletier
|
||||
* Licensed MIT */
|
||||
(function() {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* SimpleUndo is a very basic javascript undo/redo stack for managing histories of basically anything.
|
||||
*
|
||||
* options are: {
|
||||
* * `provider` : required. a function to call on `save`, which should provide the current state of the historized object through the given "done" callback
|
||||
* * `maxLength` : the maximum number of items in history
|
||||
* * `opUpdate` : a function to call to notify of changes in history. Will be called on `save`, `undo`, `redo` and `clear`
|
||||
* }
|
||||
*
|
||||
*/
|
||||
var SimpleUndo = function(options) {
|
||||
|
||||
var settings = options ? options : {};
|
||||
var defaultOptions = {
|
||||
provider: function() {
|
||||
throw new Error("No provider!");
|
||||
},
|
||||
maxLength: 30,
|
||||
onUpdate: function() {}
|
||||
};
|
||||
|
||||
this.provider = (typeof settings.provider != 'undefined') ? settings.provider : defaultOptions.provider;
|
||||
this.maxLength = (typeof settings.maxLength != 'undefined') ? settings.maxLength : defaultOptions.maxLength;
|
||||
this.onUpdate = (typeof settings.onUpdate != 'undefined') ? settings.onUpdate : defaultOptions.onUpdate;
|
||||
|
||||
this.initialItem = null;
|
||||
this.clear();
|
||||
};
|
||||
|
||||
function truncate (stack, limit) {
|
||||
while (stack.length > limit) {
|
||||
stack.shift();
|
||||
}
|
||||
}
|
||||
|
||||
SimpleUndo.prototype.initialize = function(initialItem) {
|
||||
this.stack[0] = initialItem;
|
||||
this.initialItem = initialItem;
|
||||
};
|
||||
|
||||
|
||||
SimpleUndo.prototype.clear = function() {
|
||||
this.stack = [this.initialItem];
|
||||
this.position = 0;
|
||||
this.onUpdate();
|
||||
};
|
||||
|
||||
SimpleUndo.prototype.save = function() {
|
||||
this.provider(function(current) {
|
||||
truncate(this.stack, this.maxLength);
|
||||
this.position = Math.min(this.position,this.stack.length - 1);
|
||||
|
||||
this.stack = this.stack.slice(0, this.position + 1);
|
||||
this.stack.push(current);
|
||||
this.position++;
|
||||
this.onUpdate();
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
SimpleUndo.prototype.undo = function(callback) {
|
||||
if (this.canUndo()) {
|
||||
var item = this.stack[--this.position];
|
||||
this.onUpdate();
|
||||
|
||||
if (callback) {
|
||||
callback(item);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SimpleUndo.prototype.redo = function(callback) {
|
||||
if (this.canRedo()) {
|
||||
var item = this.stack[++this.position];
|
||||
this.onUpdate();
|
||||
|
||||
if (callback) {
|
||||
callback(item);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SimpleUndo.prototype.canUndo = function() {
|
||||
return this.position > 0;
|
||||
};
|
||||
|
||||
SimpleUndo.prototype.canRedo = function() {
|
||||
return this.position < this.count();
|
||||
};
|
||||
|
||||
SimpleUndo.prototype.count = function() {
|
||||
return this.stack.length - 1; // -1 because of initial item
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//exports
|
||||
// node module
|
||||
if (typeof module != 'undefined') {
|
||||
module.exports = SimpleUndo;
|
||||
}
|
||||
|
||||
// browser global
|
||||
if (typeof window != 'undefined') {
|
||||
window.SimpleUndo = SimpleUndo;
|
||||
}
|
||||
|
||||
})();
|
||||
window.DrawingBoard = typeof DrawingBoard !== "undefined" ? DrawingBoard : {};
|
||||
|
||||
|
||||
DrawingBoard.Utils = {};
|
||||
|
||||
/*!
|
||||
* Tim (lite)
|
||||
* github.com/premasagar/tim
|
||||
*//*
|
||||
A tiny, secure JavaScript micro-templating script.
|
||||
*/
|
||||
DrawingBoard.Utils.tpl = (function(){
|
||||
"use strict";
|
||||
|
||||
var start = "{{",
|
||||
end = "}}",
|
||||
path = "[a-z0-9_][\\.a-z0-9_]*", // e.g. config.person.name
|
||||
pattern = new RegExp(start + "\\s*("+ path +")\\s*" + end, "gi"),
|
||||
undef;
|
||||
|
||||
return function(template, data){
|
||||
// Merge data into the template string
|
||||
return template.replace(pattern, function(tag, token){
|
||||
var path = token.split("."),
|
||||
len = path.length,
|
||||
lookup = data,
|
||||
i = 0;
|
||||
|
||||
for (; i < len; i++){
|
||||
lookup = lookup[path[i]];
|
||||
|
||||
// Property not found
|
||||
if (lookup === undef){
|
||||
throw "tim: '" + path[i] + "' not found in " + tag;
|
||||
}
|
||||
|
||||
// Return the required value
|
||||
if (i === len - 1){
|
||||
return lookup;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
}());
|
||||
|
||||
/**
|
||||
* https://github.com/jeromeetienne/microevent.js
|
||||
* MicroEvent - to make any js object an event emitter (server or browser)
|
||||
*
|
||||
* - pure javascript - server compatible, browser compatible
|
||||
* - dont rely on the browser doms
|
||||
* - super simple - you get it immediatly, no mistery, no magic involved
|
||||
*
|
||||
* - create a MicroEventDebug with goodies to debug
|
||||
* - make it safer to use
|
||||
*/
|
||||
DrawingBoard.Utils.MicroEvent = function(){};
|
||||
|
||||
DrawingBoard.Utils.MicroEvent.prototype = {
|
||||
bind : function(event, fct){
|
||||
this._events = this._events || {};
|
||||
this._events[event] = this._events[event] || [];
|
||||
this._events[event].push(fct);
|
||||
},
|
||||
unbind : function(event, fct){
|
||||
this._events = this._events || {};
|
||||
if( event in this._events === false ) return;
|
||||
this._events[event].splice(this._events[event].indexOf(fct), 1);
|
||||
},
|
||||
trigger : function(event /* , args... */){
|
||||
this._events = this._events || {};
|
||||
if( event in this._events === false ) return;
|
||||
for(var i = 0; i < this._events[event].length; i++){
|
||||
this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//I know.
|
||||
DrawingBoard.Utils._boxBorderSize = function($el, withPadding, withMargin, direction) {
|
||||
withPadding = !!withPadding || true;
|
||||
withMargin = !!withMargin || false;
|
||||
var width = 0,
|
||||
props;
|
||||
if (direction == "width") {
|
||||
props = ['border-left-width', 'border-right-width'];
|
||||
if (withPadding) props.push('padding-left', 'padding-right');
|
||||
if (withMargin) props.push('margin-left', 'margin-right');
|
||||
} else {
|
||||
props = ['border-top-width', 'border-bottom-width'];
|
||||
if (withPadding) props.push('padding-top', 'padding-bottom');
|
||||
if (withMargin) props.push('margin-top', 'margin-bottom');
|
||||
}
|
||||
for (var i = props.length - 1; i >= 0; i--)
|
||||
width += parseInt($el.css(props[i]).replace('px', ''), 10);
|
||||
return width;
|
||||
};
|
||||
|
||||
DrawingBoard.Utils.boxBorderWidth = function($el, withPadding, withMargin) {
|
||||
return DrawingBoard.Utils._boxBorderSize($el, withPadding, withMargin, 'width');
|
||||
};
|
||||
|
||||
DrawingBoard.Utils.boxBorderHeight = function($el, withPadding, withMargin) {
|
||||
return DrawingBoard.Utils._boxBorderSize($el, withPadding, withMargin, 'height');
|
||||
};
|
||||
|
||||
DrawingBoard.Utils.isColor = function(string) {
|
||||
if (!string || !string.length) return false;
|
||||
return (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i).test(string) || $.inArray(string.substring(0, 3), ['rgb', 'hsl']) !== -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Packs an RGB color into a single integer.
|
||||
*/
|
||||
DrawingBoard.Utils.RGBToInt = function(r, g, b) {
|
||||
var c = 0;
|
||||
c |= (r & 255) << 16;
|
||||
c |= (g & 255) << 8;
|
||||
c |= (b & 255);
|
||||
return c;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns informations on the pixel located at (x,y).
|
||||
*/
|
||||
DrawingBoard.Utils.pixelAt = function(image, x, y) {
|
||||
var i = (y * image.width + x) * 4;
|
||||
var c = DrawingBoard.Utils.RGBToInt(
|
||||
image.data[i],
|
||||
image.data[i + 1],
|
||||
image.data[i + 2]
|
||||
);
|
||||
|
||||
return [
|
||||
i, // INDEX
|
||||
x, // X
|
||||
y, // Y
|
||||
c // COLOR
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Compares two colors with the given tolerance (between 0 and 255).
|
||||
*/
|
||||
DrawingBoard.Utils.compareColors = function(a, b, tolerance) {
|
||||
if (tolerance === 0) {
|
||||
return (a === b);
|
||||
}
|
||||
|
||||
var ra = (a >> 16) & 255, rb = (b >> 16) & 255,
|
||||
ga = (a >> 8) & 255, gb = (b >> 8) & 255,
|
||||
ba = a & 255, bb = b & 255;
|
||||
|
||||
return (Math.abs(ra - rb) <= tolerance)
|
||||
&& (Math.abs(ga - gb) <= tolerance)
|
||||
&& (Math.abs(ba - bb) <= tolerance);
|
||||
};
|
||||
|
||||
(function() {
|
||||
var lastTime = 0;
|
||||
var vendors = ['ms', 'moz', 'webkit', 'o'];
|
||||
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
|
||||
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
|
||||
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
|
||||
}
|
||||
}());
|
||||
|
||||
window.DrawingBoard = typeof DrawingBoard !== "undefined" ? DrawingBoard : {};
|
||||
|
||||
/**
|
||||
* pass the id of the html element to put the drawing board into
|
||||
* and some options : {
|
||||
* controls: array of controls to initialize with the drawingboard. 'Colors', 'Size', and 'Navigation' by default
|
||||
* instead of simple strings, you can pass an object to define a control opts
|
||||
* ie ['Color', { Navigation: { reset: false }}]
|
||||
* controlsPosition: "top left" by default. Define where to put the controls: at the "top" or "bottom" of the canvas, aligned to "left"/"right"/"center"
|
||||
* background: background of the drawing board. Give a hex color or an image url "#ffffff" (white) by default
|
||||
* color: pencil color ("#000000" by default)
|
||||
* size: pencil size (3 by default)
|
||||
* webStorage: 'session', 'local' or false ('session' by default). store the current drawing in session or local storage and restore it when you come back
|
||||
* droppable: true or false (false by default). If true, dropping an image on the canvas will include it and allow you to draw on it,
|
||||
* errorMessage: html string to put in the board's element on browsers that don't support canvas.
|
||||
* stretchImg: default behavior of image setting on the canvas: set to the canvas width/height or not? false by default
|
||||
* }
|
||||
*/
|
||||
DrawingBoard.Board = function(id, opts) {
|
||||
this.opts = this.mergeOptions(opts);
|
||||
|
||||
this.ev = new DrawingBoard.Utils.MicroEvent();
|
||||
|
||||
this.id = id;
|
||||
this.$el = $(document.getElementById(id));
|
||||
if (!this.$el.length)
|
||||
return false;
|
||||
|
||||
var tpl = '<div class="drawing-board-canvas-wrapper"></canvas><canvas class="drawing-board-canvas"></canvas><div class="drawing-board-cursor drawing-board-utils-hidden"></div></div>';
|
||||
if (this.opts.controlsPosition.indexOf("bottom") > -1) tpl += '<div class="drawing-board-controls"></div>';
|
||||
else tpl = '<div class="drawing-board-controls"></div>' + tpl;
|
||||
|
||||
this.$el.addClass('drawing-board').append(tpl);
|
||||
this.dom = {
|
||||
$canvasWrapper: this.$el.find('.drawing-board-canvas-wrapper'),
|
||||
$canvas: this.$el.find('.drawing-board-canvas'),
|
||||
$cursor: this.$el.find('.drawing-board-cursor'),
|
||||
$controls: this.$el.find('.drawing-board-controls')
|
||||
};
|
||||
|
||||
$.each(['left', 'right', 'center'], $.proxy(function(n, val) {
|
||||
if (this.opts.controlsPosition.indexOf(val) > -1) {
|
||||
this.dom.$controls.attr('data-align', val);
|
||||
return false;
|
||||
}
|
||||
}, this));
|
||||
|
||||
this.canvas = this.dom.$canvas.get(0);
|
||||
this.ctx = this.canvas && this.canvas.getContext && this.canvas.getContext('2d') ? this.canvas.getContext('2d') : null;
|
||||
this.color = this.opts.color;
|
||||
|
||||
if (!this.ctx) {
|
||||
if (this.opts.errorMessage)
|
||||
this.$el.html(this.opts.errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.storage = this._getStorage();
|
||||
|
||||
this.initHistory();
|
||||
//init default board values before controls are added (mostly pencil color and size)
|
||||
this.reset({ webStorage: false, history: false, background: false });
|
||||
//init controls (they will need the default board values to work like pencil color and size)
|
||||
this.initControls();
|
||||
//set board's size after the controls div is added
|
||||
this.resize();
|
||||
//reset the board to take all resized space
|
||||
this.reset({ webStorage: false, history: false, background: true });
|
||||
this.restoreWebStorage();
|
||||
this.initDropEvents();
|
||||
this.initDrawEvents();
|
||||
};
|
||||
|
||||
|
||||
|
||||
DrawingBoard.Board.defaultOpts = {
|
||||
controls: ['Color', 'DrawingMode', 'Size', 'Navigation'],
|
||||
controlsPosition: "top left",
|
||||
color: "#000000",
|
||||
size: 1,
|
||||
background: "#fff",
|
||||
eraserColor: "background",
|
||||
fillTolerance: 100,
|
||||
fillHack: true, //try to prevent issues with anti-aliasing with a little hack by default
|
||||
webStorage: 'session',
|
||||
droppable: false,
|
||||
enlargeYourContainer: false,
|
||||
errorMessage: "<p>It seems you use an obsolete browser. <a href=\"http://browsehappy.com/\" target=\"_blank\">Update it</a> to start drawing.</p>",
|
||||
stretchImg: false //when setting the canvas img, strech the image at the whole canvas size when this opt is true
|
||||
};
|
||||
|
||||
|
||||
|
||||
DrawingBoard.Board.prototype = {
|
||||
|
||||
mergeOptions: function(opts) {
|
||||
opts = $.extend({}, DrawingBoard.Board.defaultOpts, opts);
|
||||
if (!opts.background && opts.eraserColor === "background")
|
||||
opts.eraserColor = "transparent";
|
||||
return opts;
|
||||
},
|
||||
|
||||
/**
|
||||
* Canvas reset/resize methods: put back the canvas to its default values
|
||||
*
|
||||
* depending on options, can set color, size, background back to default values
|
||||
* and store the reseted canvas in webstorage and history queue
|
||||
*
|
||||
* resize values depend on the `enlargeYourContainer` option
|
||||
*/
|
||||
|
||||
reset: function(opts) {
|
||||
opts = $.extend({
|
||||
color: this.opts.color,
|
||||
size: this.opts.size,
|
||||
webStorage: true,
|
||||
history: true,
|
||||
background: false
|
||||
}, opts);
|
||||
|
||||
this.setMode('pencil');
|
||||
|
||||
if (opts.background) {
|
||||
this.resetBackground(this.opts.background, $.proxy(function() {
|
||||
if (opts.history) this.saveHistory();
|
||||
}, this));
|
||||
}
|
||||
|
||||
if (opts.color) this.setColor(opts.color);
|
||||
if (opts.size) this.ctx.lineWidth = opts.size;
|
||||
|
||||
this.ctx.lineCap = "round";
|
||||
this.ctx.lineJoin = "round";
|
||||
// this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.width);
|
||||
|
||||
if (opts.webStorage) this.saveWebStorage();
|
||||
|
||||
// if opts.background we already dealt with the history
|
||||
if (opts.history && !opts.background) this.saveHistory();
|
||||
|
||||
this.blankCanvas = this.getImg();
|
||||
|
||||
this.ev.trigger('board:reset', opts);
|
||||
},
|
||||
|
||||
resetBackground: function(background, callback) {
|
||||
background = background || this.opts.background;
|
||||
|
||||
var bgIsColor = DrawingBoard.Utils.isColor(background);
|
||||
var prevMode = this.getMode();
|
||||
this.setMode('pencil');
|
||||
this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
|
||||
if (bgIsColor) {
|
||||
this.ctx.fillStyle = background;
|
||||
this.ctx.fillRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
|
||||
this.history.initialize(this.getImg());
|
||||
if (callback) callback();
|
||||
} else if (background)
|
||||
this.setImg(background, {
|
||||
callback: $.proxy(function() {
|
||||
this.history.initialize(this.getImg());
|
||||
if (callback) callback();
|
||||
}, this)
|
||||
});
|
||||
this.setMode(prevMode);
|
||||
},
|
||||
|
||||
resize: function() {
|
||||
this.dom.$controls.toggleClass('drawing-board-controls-hidden', (!this.controls || !this.controls.length));
|
||||
|
||||
var canvasWidth, canvasHeight;
|
||||
var widths = [
|
||||
this.$el.width(),
|
||||
DrawingBoard.Utils.boxBorderWidth(this.$el),
|
||||
DrawingBoard.Utils.boxBorderWidth(this.dom.$canvasWrapper, true, true)
|
||||
];
|
||||
var heights = [
|
||||
this.$el.height(),
|
||||
DrawingBoard.Utils.boxBorderHeight(this.$el),
|
||||
this.dom.$controls.height(),
|
||||
DrawingBoard.Utils.boxBorderHeight(this.dom.$controls, false, true),
|
||||
DrawingBoard.Utils.boxBorderHeight(this.dom.$canvasWrapper, true, true)
|
||||
];
|
||||
var that = this;
|
||||
var sum = function(values, multiplier) { //make the sum of all array values
|
||||
multiplier = multiplier || 1;
|
||||
var res = values[0];
|
||||
for (var i = 1; i < values.length; i++) {
|
||||
res = res + (values[i]*multiplier);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
var sub = function(values) { return sum(values, -1); }; //substract all array values from the first one
|
||||
|
||||
if (this.opts.enlargeYourContainer) {
|
||||
canvasWidth = this.$el.width();
|
||||
canvasHeight = this.$el.height();
|
||||
|
||||
this.$el.width( sum(widths) );
|
||||
this.$el.height( sum(heights) );
|
||||
} else {
|
||||
canvasWidth = sub(widths);
|
||||
canvasHeight = sub(heights);
|
||||
}
|
||||
|
||||
this.dom.$canvasWrapper.css('width', canvasWidth + 'px');
|
||||
this.dom.$canvasWrapper.css('height', canvasHeight + 'px');
|
||||
|
||||
this.dom.$canvas.css('width', canvasWidth + 'px');
|
||||
this.dom.$canvas.css('height', canvasHeight + 'px');
|
||||
|
||||
this.canvas.width = canvasWidth;
|
||||
this.canvas.height = canvasHeight;
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Controls:
|
||||
* the drawing board can has various UI elements to control it.
|
||||
* one control is represented by a class in the namespace DrawingBoard.Control
|
||||
* it must have a $el property (jQuery object), representing the html element to append on the drawing board at initialization.
|
||||
*
|
||||
*/
|
||||
|
||||
initControls: function() {
|
||||
this.controls = [];
|
||||
if (!this.opts.controls.length || !DrawingBoard.Control) return false;
|
||||
for (var i = 0; i < this.opts.controls.length; i++) {
|
||||
var c = null;
|
||||
if (typeof this.opts.controls[i] == "string")
|
||||
c = new window['DrawingBoard']['Control'][this.opts.controls[i]](this);
|
||||
else if (typeof this.opts.controls[i] == "object") {
|
||||
for (var controlName in this.opts.controls[i]) break;
|
||||
c = new window['DrawingBoard']['Control'][controlName](this, this.opts.controls[i][controlName]);
|
||||
}
|
||||
if (c) {
|
||||
this.addControl(c);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
//add a new control or an existing one at the position you want in the UI
|
||||
//to add a totally new control, you can pass a string with the js class as 1st parameter and control options as 2nd ie "addControl('Navigation', { reset: false }"
|
||||
//the last parameter (2nd or 3rd depending on the situation) is always the position you want to place the control at
|
||||
addControl: function(control, optsOrPos, pos) {
|
||||
if (typeof control !== "string" && (typeof control !== "object" || !control instanceof DrawingBoard.Control))
|
||||
return false;
|
||||
|
||||
var opts = typeof optsOrPos == "object" ? optsOrPos : {};
|
||||
pos = pos ? pos*1 : (typeof optsOrPos == "number" ? optsOrPos : null);
|
||||
|
||||
if (typeof control == "string")
|
||||
control = new window['DrawingBoard']['Control'][control](this, opts);
|
||||
|
||||
if (pos)
|
||||
this.dom.$controls.children().eq(pos).before(control.$el);
|
||||
else
|
||||
this.dom.$controls.append(control.$el);
|
||||
|
||||
if (!this.controls)
|
||||
this.controls = [];
|
||||
this.controls.push(control);
|
||||
this.dom.$controls.removeClass('drawing-board-controls-hidden');
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* History methods: undo and redo drawed lines
|
||||
*/
|
||||
|
||||
initHistory: function() {
|
||||
this.history = new SimpleUndo({
|
||||
maxLength: 30,
|
||||
provider: $.proxy(function(done) {
|
||||
done(this.getImg());
|
||||
}, this),
|
||||
onUpdate: $.proxy(function() {
|
||||
this.ev.trigger('historyNavigation');
|
||||
}, this)
|
||||
});
|
||||
},
|
||||
|
||||
saveHistory: function() {
|
||||
this.history.save();
|
||||
},
|
||||
|
||||
restoreHistory: function(image) {
|
||||
this.setImg(image, {
|
||||
callback: $.proxy(function() {
|
||||
this.saveWebStorage();
|
||||
}, this)
|
||||
});
|
||||
},
|
||||
|
||||
goBackInHistory: function() {
|
||||
this.history.undo($.proxy(this.restoreHistory, this));
|
||||
},
|
||||
|
||||
goForthInHistory: function() {
|
||||
this.history.redo($.proxy(this.restoreHistory, this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Image methods: you can directly put an image on the canvas, get it in base64 data url or start a download
|
||||
*/
|
||||
|
||||
setImg: function(src, opts) {
|
||||
opts = $.extend({
|
||||
stretch: this.opts.stretchImg,
|
||||
callback: null
|
||||
}, opts);
|
||||
|
||||
var ctx = this.ctx;
|
||||
var img = new Image();
|
||||
var oldGCO = ctx.globalCompositeOperation;
|
||||
img.onload = function() {
|
||||
ctx.globalCompositeOperation = "source-over";
|
||||
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
|
||||
if (opts.stretch) {
|
||||
ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
} else {
|
||||
ctx.drawImage(img, 0, 0);
|
||||
}
|
||||
|
||||
ctx.globalCompositeOperation = oldGCO;
|
||||
|
||||
if (opts.callback) {
|
||||
opts.callback();
|
||||
}
|
||||
};
|
||||
img.src = src;
|
||||
},
|
||||
|
||||
getImg: function() {
|
||||
return this.canvas.toDataURL("image/png");
|
||||
},
|
||||
|
||||
downloadImg: function() {
|
||||
var img = this.getImg();
|
||||
img = img.replace("image/png", "image/octet-stream");
|
||||
window.location.href = img;
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* WebStorage handling : save and restore to local or session storage
|
||||
*/
|
||||
|
||||
saveWebStorage: function() {
|
||||
if (window[this.storage]) {
|
||||
window[this.storage].setItem('drawing-board-' + this.id, this.getImg());
|
||||
this.ev.trigger('board:save' + this.storage.charAt(0).toUpperCase() + this.storage.slice(1), this.getImg());
|
||||
}
|
||||
},
|
||||
|
||||
restoreWebStorage: function() {
|
||||
if (window[this.storage] && window[this.storage].getItem('drawing-board-' + this.id) !== null) {
|
||||
this.setImg(window[this.storage].getItem('drawing-board-' + this.id));
|
||||
this.ev.trigger('board:restore' + this.storage.charAt(0).toUpperCase() + this.storage.slice(1), window[this.storage].getItem('drawing-board-' + this.id));
|
||||
}
|
||||
},
|
||||
|
||||
clearWebStorage: function() {
|
||||
if (window[this.storage] && window[this.storage].getItem('drawing-board-' + this.id) !== null) {
|
||||
window[this.storage].removeItem('drawing-board-' + this.id);
|
||||
this.ev.trigger('board:clear' + this.storage.charAt(0).toUpperCase() + this.storage.slice(1));
|
||||
}
|
||||
},
|
||||
|
||||
_getStorage: function() {
|
||||
if (!this.opts.webStorage || !(this.opts.webStorage === 'session' || this.opts.webStorage === 'local')) return false;
|
||||
return this.opts.webStorage + 'Storage';
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Drop an image on the canvas to draw on it
|
||||
*/
|
||||
|
||||
initDropEvents: function() {
|
||||
if (!this.opts.droppable)
|
||||
return false;
|
||||
|
||||
this.dom.$canvas.on('dragover dragenter drop', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
this.dom.$canvas.on('drop', $.proxy(this._onCanvasDrop, this));
|
||||
},
|
||||
|
||||
_onCanvasDrop: function(e) {
|
||||
e = e.originalEvent ? e.originalEvent : e;
|
||||
var files = e.dataTransfer.files;
|
||||
if (!files || !files.length || files[0].type.indexOf('image') == -1 || !window.FileReader)
|
||||
return false;
|
||||
var fr = new FileReader();
|
||||
fr.readAsDataURL(files[0]);
|
||||
fr.onload = $.proxy(function(ev) {
|
||||
this.setImg(ev.target.result, {
|
||||
callback: $.proxy(function() {
|
||||
this.saveHistory();
|
||||
}, this)
|
||||
});
|
||||
this.ev.trigger('board:imageDropped', ev.target.result);
|
||||
this.ev.trigger('board:userAction');
|
||||
}, this);
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* set and get current drawing mode
|
||||
*
|
||||
* possible modes are "pencil" (draw normally), "eraser" (draw transparent, like, erase, you know), "filler" (paint can)
|
||||
*/
|
||||
|
||||
setMode: function(newMode, silent) {
|
||||
silent = silent || false;
|
||||
newMode = newMode || 'pencil';
|
||||
|
||||
this.ev.unbind('board:startDrawing', $.proxy(this.fill, this));
|
||||
|
||||
if (this.opts.eraserColor === "transparent")
|
||||
this.ctx.globalCompositeOperation = newMode === "eraser" ? "destination-out" : "source-over";
|
||||
else {
|
||||
if (newMode === "eraser") {
|
||||
if (this.opts.eraserColor === "background" && DrawingBoard.Utils.isColor(this.opts.background))
|
||||
this.ctx.strokeStyle = this.opts.background;
|
||||
else if (DrawingBoard.Utils.isColor(this.opts.eraserColor))
|
||||
this.ctx.strokeStyle = this.opts.eraserColor;
|
||||
} else if (!this.mode || this.mode === "eraser") {
|
||||
this.ctx.strokeStyle = this.color;
|
||||
}
|
||||
|
||||
if (newMode === "filler")
|
||||
this.ev.bind('board:startDrawing', $.proxy(this.fill, this));
|
||||
}
|
||||
this.mode = newMode;
|
||||
if (!silent)
|
||||
this.ev.trigger('board:mode', this.mode);
|
||||
},
|
||||
|
||||
getMode: function() {
|
||||
return this.mode || "pencil";
|
||||
},
|
||||
|
||||
setColor: function(color) {
|
||||
var that = this;
|
||||
color = color || this.color;
|
||||
if (!DrawingBoard.Utils.isColor(color))
|
||||
return false;
|
||||
this.color = color;
|
||||
if (this.opts.eraserColor !== "transparent" && this.mode === "eraser") {
|
||||
var setStrokeStyle = function(mode) {
|
||||
if (mode !== "eraser")
|
||||
that.strokeStyle = that.color;
|
||||
that.ev.unbind('board:mode', setStrokeStyle);
|
||||
};
|
||||
this.ev.bind('board:mode', setStrokeStyle);
|
||||
} else
|
||||
this.ctx.strokeStyle = this.color;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fills an area with the current stroke color.
|
||||
*/
|
||||
fill: function(e) {
|
||||
if (this.getImg() === this.blankCanvas) {
|
||||
this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
|
||||
this.ctx.fillStyle = this.color;
|
||||
this.ctx.fillRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
|
||||
return;
|
||||
}
|
||||
|
||||
var img = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
|
||||
|
||||
// constants identifying pixels components
|
||||
var INDEX = 0, X = 1, Y = 2, COLOR = 3;
|
||||
|
||||
// target color components
|
||||
var stroke = this.ctx.strokeStyle;
|
||||
var r = parseInt(stroke.substr(1, 2), 16);
|
||||
var g = parseInt(stroke.substr(3, 2), 16);
|
||||
var b = parseInt(stroke.substr(5, 2), 16);
|
||||
|
||||
// starting point
|
||||
var start = DrawingBoard.Utils.pixelAt(img, parseInt(e.coords.x, 10), parseInt(e.coords.y, 10));
|
||||
var startColor = start[COLOR];
|
||||
var tolerance = this.opts.fillTolerance;
|
||||
var useHack = this.opts.fillHack; //see https://github.com/Leimi/drawingboard.js/pull/38
|
||||
|
||||
// no need to continue if starting and target colors are the same
|
||||
if (DrawingBoard.Utils.compareColors(startColor, DrawingBoard.Utils.RGBToInt(r, g, b), tolerance))
|
||||
return;
|
||||
|
||||
// pixels to evaluate
|
||||
var queue = [start];
|
||||
|
||||
// loop vars
|
||||
var pixel, x, y;
|
||||
var maxX = img.width - 1;
|
||||
var maxY = img.height - 1;
|
||||
|
||||
function updatePixelColor(pixel) {
|
||||
img.data[pixel[INDEX]] = r;
|
||||
img.data[pixel[INDEX] + 1] = g;
|
||||
img.data[pixel[INDEX] + 2] = b;
|
||||
}
|
||||
|
||||
while ((pixel = queue.pop())) {
|
||||
if (useHack)
|
||||
updatePixelColor(pixel);
|
||||
|
||||
if (DrawingBoard.Utils.compareColors(pixel[COLOR], startColor, tolerance)) {
|
||||
if (!useHack)
|
||||
updatePixelColor(pixel);
|
||||
if (pixel[X] > 0) // west
|
||||
queue.push(DrawingBoard.Utils.pixelAt(img, pixel[X] - 1, pixel[Y]));
|
||||
if (pixel[X] < maxX) // east
|
||||
queue.push(DrawingBoard.Utils.pixelAt(img, pixel[X] + 1, pixel[Y]));
|
||||
if (pixel[Y] > 0) // north
|
||||
queue.push(DrawingBoard.Utils.pixelAt(img, pixel[X], pixel[Y] - 1));
|
||||
if (pixel[Y] < maxY) // south
|
||||
queue.push(DrawingBoard.Utils.pixelAt(img, pixel[X], pixel[Y] + 1));
|
||||
}
|
||||
}
|
||||
|
||||
this.ctx.putImageData(img, 0, 0);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Drawing handling, with mouse or touch
|
||||
*/
|
||||
|
||||
initDrawEvents: function() {
|
||||
this.isDrawing = false;
|
||||
this.isMouseHovering = false;
|
||||
this.coords = {};
|
||||
this.coords.old = this.coords.current = this.coords.oldMid = { x: 0, y: 0 };
|
||||
|
||||
this.dom.$canvas.on('mousedown touchstart', $.proxy(function(e) {
|
||||
this._onInputStart(e, this._getInputCoords(e) );
|
||||
}, this));
|
||||
|
||||
this.dom.$canvas.on('mousemove touchmove', $.proxy(function(e) {
|
||||
this._onInputMove(e, this._getInputCoords(e) );
|
||||
}, this));
|
||||
|
||||
this.dom.$canvas.on('mousemove', $.proxy(function(e) {
|
||||
|
||||
}, this));
|
||||
|
||||
this.dom.$canvas.on('mouseup touchend', $.proxy(function(e) {
|
||||
this._onInputStop(e, this._getInputCoords(e) );
|
||||
}, this));
|
||||
|
||||
this.dom.$canvas.on('mouseover', $.proxy(function(e) {
|
||||
this._onMouseOver(e, this._getInputCoords(e) );
|
||||
}, this));
|
||||
|
||||
this.dom.$canvas.on('mouseout', $.proxy(function(e) {
|
||||
this._onMouseOut(e, this._getInputCoords(e) );
|
||||
|
||||
}, this));
|
||||
|
||||
$('body').on('mouseup touchend', $.proxy(function(e) {
|
||||
this.isDrawing = false;
|
||||
}, this));
|
||||
|
||||
if (window.requestAnimationFrame) requestAnimationFrame( $.proxy(this.draw, this) );
|
||||
},
|
||||
|
||||
draw: function() {
|
||||
//if the pencil size is big (>10), the small crosshair makes a friend: a circle of the size of the pencil
|
||||
//todo: have the circle works on every browser - it currently should be added only when CSS pointer-events are supported
|
||||
//we assume that if requestAnimationFrame is supported, pointer-events is too, but this is terribad.
|
||||
if (window.requestAnimationFrame && this.ctx.lineWidth > 10 && this.isMouseHovering) {
|
||||
this.dom.$cursor.css({ width: this.ctx.lineWidth + 'px', height: this.ctx.lineWidth + 'px' });
|
||||
var transform = DrawingBoard.Utils.tpl("translateX({{x}}px) translateY({{y}}px)", { x: this.coords.current.x-(this.ctx.lineWidth/2), y: this.coords.current.y-(this.ctx.lineWidth/2) });
|
||||
this.dom.$cursor.css({ 'transform': transform, '-webkit-transform': transform, '-ms-transform': transform });
|
||||
this.dom.$cursor.removeClass('drawing-board-utils-hidden');
|
||||
} else {
|
||||
this.dom.$cursor.addClass('drawing-board-utils-hidden');
|
||||
}
|
||||
|
||||
if (this.isDrawing) {
|
||||
var currentMid = this._getMidInputCoords(this.coords.current);
|
||||
this.ctx.beginPath();
|
||||
this.ctx.moveTo(currentMid.x, currentMid.y);
|
||||
this.ctx.quadraticCurveTo(this.coords.old.x, this.coords.old.y, this.coords.oldMid.x, this.coords.oldMid.y);
|
||||
this.ctx.stroke();
|
||||
|
||||
this.coords.old = this.coords.current;
|
||||
this.coords.oldMid = currentMid;
|
||||
}
|
||||
|
||||
if (window.requestAnimationFrame) requestAnimationFrame( $.proxy(function() { this.draw(); }, this) );
|
||||
},
|
||||
|
||||
_onInputStart: function(e, coords) {
|
||||
this.coords.current = this.coords.old = coords;
|
||||
this.coords.oldMid = this._getMidInputCoords(coords);
|
||||
this.isDrawing = true;
|
||||
|
||||
if (!window.requestAnimationFrame) this.draw();
|
||||
|
||||
this.ev.trigger('board:startDrawing', {e: e, coords: coords});
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
},
|
||||
|
||||
_onInputMove: function(e, coords) {
|
||||
this.coords.current = coords;
|
||||
this.ev.trigger('board:drawing', {e: e, coords: coords});
|
||||
|
||||
if (!window.requestAnimationFrame) this.draw();
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
},
|
||||
|
||||
_onInputStop: function(e, coords) {
|
||||
if (this.isDrawing && (!e.touches || e.touches.length === 0)) {
|
||||
this.isDrawing = false;
|
||||
|
||||
this.saveWebStorage();
|
||||
this.saveHistory();
|
||||
|
||||
this.ev.trigger('board:stopDrawing', {e: e, coords: coords});
|
||||
this.ev.trigger('board:userAction');
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
|
||||
_onMouseOver: function(e, coords) {
|
||||
this.isMouseHovering = true;
|
||||
this.coords.old = this._getInputCoords(e);
|
||||
this.coords.oldMid = this._getMidInputCoords(this.coords.old);
|
||||
|
||||
this.ev.trigger('board:mouseOver', {e: e, coords: coords});
|
||||
},
|
||||
|
||||
_onMouseOut: function(e, coords) {
|
||||
this.isMouseHovering = false;
|
||||
|
||||
this.ev.trigger('board:mouseOut', {e: e, coords: coords});
|
||||
},
|
||||
|
||||
_getInputCoords: function(e) {
|
||||
e = e.originalEvent ? e.originalEvent : e;
|
||||
var
|
||||
rect = this.canvas.getBoundingClientRect(),
|
||||
width = this.dom.$canvas.width(),
|
||||
height = this.dom.$canvas.height()
|
||||
;
|
||||
var x, y;
|
||||
if (e.touches && e.touches.length == 1) {
|
||||
x = e.touches[0].pageX;
|
||||
y = e.touches[0].pageY;
|
||||
} else {
|
||||
x = e.pageX;
|
||||
y = e.pageY;
|
||||
}
|
||||
x = x - this.dom.$canvas.offset().left;
|
||||
y = y - this.dom.$canvas.offset().top;
|
||||
x *= (width / rect.width);
|
||||
y *= (height / rect.height);
|
||||
return {
|
||||
x: x,
|
||||
y: y
|
||||
};
|
||||
},
|
||||
|
||||
_getMidInputCoords: function(coords) {
|
||||
return {
|
||||
x: this.coords.old.x + coords.x>>1,
|
||||
y: this.coords.old.y + coords.y>>1
|
||||
};
|
||||
}
|
||||
};
|
||||
5
mondumas/static/dist/drawingboard/drawingboard.nocontrol.min.css
vendored
Normal file
5
mondumas/static/dist/drawingboard/drawingboard.nocontrol.min.css
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js
|
||||
* Copyright (c) 2015 Emmanuel Pelletier
|
||||
* Licensed MIT */
|
||||
|
||||
.drawing-board,.drawing-board *{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.drawing-board-utils-hidden{display:none!important}.drawing-board{position:relative;display:block}.drawing-board-canvas-wrapper{position:relative;margin:0;border:1px solid #ddd}.drawing-board-canvas{position:absolute;top:0;left:0;width:auto;cursor:crosshair;z-index:20}.drawing-board-cursor{position:absolute;top:0;left:0;pointer-events:none;border-radius:50%;background:#ccc;background:rgba(0,0,0,.2);z-index:30}
|
||||
4
mondumas/static/dist/drawingboard/drawingboard.nocontrol.min.js
vendored
Normal file
4
mondumas/static/dist/drawingboard/drawingboard.nocontrol.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -14,12 +14,9 @@
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">Type de texte</label>
|
||||
<div class="col-sm-10">
|
||||
<label class="radio-inline"><input type="radio" name="ref" value="T1"
|
||||
tal:attributes="checked ligne.ref=='T1'">Titre</label>
|
||||
<label class="radio-inline"><input type="radio" name="ref" value="T2"
|
||||
tal:attributes="checked ligne.ref=='T2'">Sous-titre</label>
|
||||
<label class="radio-inline"><input type="radio" name="ref" value="TX"
|
||||
tal:attributes="checked ligne.ref=='TX'">Texte libre</label>
|
||||
<label class="radio-inline"><input type="radio" name="ref" value="T1" checked>Titre</label>
|
||||
<label class="radio-inline"><input type="radio" name="ref" value="T2">Sous-titre</label>
|
||||
<label class="radio-inline"><input type="radio" name="ref" value="TX">Texte libre</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@@ -47,8 +44,11 @@
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">Quantité</label>
|
||||
<div class="col-sm-10">
|
||||
<input class="form-control" type="text" id="qte" name="qte" value="${ligne.qte}">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon" id="unite">.00</span>
|
||||
<input class="form-control" type="text" id="qte" name="qte" value="${ligne.qte}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">Prix HT</label>
|
||||
@@ -196,11 +196,13 @@ $(document).ready(function() {
|
||||
var ref = response[0]['ref'];
|
||||
var libelle = response[0]['libelle'];
|
||||
var prixht = response[0]['prixht'];
|
||||
var unite = response[0]['unite'];
|
||||
|
||||
// Set value to textboxes
|
||||
document.getElementById('ref').value = ref;
|
||||
document.getElementById('libelle').value = libelle;
|
||||
document.getElementById('prixht').value = prixht;
|
||||
document.getElementById("unite").innerHTML= unite;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
28
mondumas/templates/dossier/croquis_edit.pt
Normal file
28
mondumas/templates/dossier/croquis_edit.pt
Normal file
@@ -0,0 +1,28 @@
|
||||
<metal:block use-macro="main_template">
|
||||
<div metal:fill-slot="content">
|
||||
|
||||
<div style="row">
|
||||
<div id="dessin"></div>
|
||||
</div> <!-- row -->
|
||||
|
||||
|
||||
<!-- Drawingboard -->
|
||||
<link href="${request.static_url('mondumas:static/dist/drawingboard/drawingboard.min.css')}" rel="stylesheet" media="all">
|
||||
<script src="${request.static_url('mondumas:static/dist/drawingboard/drawingboard.min.js')}"></script>
|
||||
<script>
|
||||
var simpleBoard = new DrawingBoard.Board('dessin', {
|
||||
background: 'none',
|
||||
size: 10,
|
||||
controls: [
|
||||
'Color',
|
||||
{ Size: { type: 'dropdown' } },
|
||||
{ Navigation: { } },
|
||||
],
|
||||
size: 1,
|
||||
webStorage: 'session',
|
||||
enlargeYourContainer: true
|
||||
});
|
||||
</script>
|
||||
|
||||
</div><!-- content -->
|
||||
</metal:block>
|
||||
@@ -282,6 +282,39 @@
|
||||
<td class="text-center">${detail.usermaj}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3 class="text-center">NOTES et CROQUIS</h3>
|
||||
<br />
|
||||
<div class="row">
|
||||
<!-- bouton AJOUT NOTE-->
|
||||
<div class="text-center col-sm-3">
|
||||
<a href="${request.application_url}/note_add/${nodossier}">
|
||||
<span class="glyphicon glyphicon-plus logo-success"></span>
|
||||
<h4>NOTE</h4></a>
|
||||
</div>
|
||||
<!-- Listes des Notes -->
|
||||
<div class="text-center" tal:repeat="item dem_notes">
|
||||
<div class="col-sm-3">
|
||||
<a href="${request.application_url}/note_edit/${nodossier}/${item.noligne}" tal:condition="item.type_note=='NOTE'">
|
||||
<span class="glyphicon glyphicon-text-size logo-primary"></span>
|
||||
<h4>${item.libelle}</h4></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="text-center col-sm-3">
|
||||
<a href="${request.application_url}/croquis_edit/">
|
||||
<span class="glyphicon glyphicon-plus logo-success"></span>
|
||||
<h4>CROQUIS</h4></a>
|
||||
</div>
|
||||
<div class="text-center" tal:repeat="item dem_croquis">
|
||||
<div class="col-sm-3">
|
||||
<a href="${request.application_url}/croquis_edit/" tal:condition="item.type_note=='CROQUIS'">
|
||||
<span class="glyphicon glyphicon-picture logo-primary"></span>
|
||||
<h4>${item.libelle}</h4></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- PANEL RDF -->
|
||||
<div id="tab_rdf" class="tab-pane fade">
|
||||
@@ -345,8 +378,8 @@
|
||||
<div class="col-xs-8">
|
||||
<select class="form-control" id="motif" name="motif">
|
||||
<option selected> </option>
|
||||
<div tal:repeat="item motif">
|
||||
<option>${item.code} | ${item.libelle}</option>
|
||||
<div tal:repeat="item motifs">
|
||||
<option>${item.libelle}</option>
|
||||
</div>
|
||||
</select>
|
||||
</div>
|
||||
@@ -361,6 +394,34 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Modal : add NOTES et CROQUIS -->
|
||||
<div class="modal fade" id="addNote" role="dialog" aria-labelledby="addNoteLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">Ajouter une note ou un croquis</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- The form is placed inside the body of modal -->
|
||||
<form id="add_justif-form" class="form-horizontal" action="${url}" method="post">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-6">Voulez-vous ajouter</label>
|
||||
<div class="col-sm-6">
|
||||
<label class="radio-inline"><input type="radio" name="type_note" value="NOTE" checked>une note</label>
|
||||
<label class="radio-inline"><input type="radio" name="type_note" value="CROQUIS">un croquis</label>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Annuler</button>
|
||||
<button type="submit" class="btn btn-warning" name="form.addNote">Ajouter</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</metal:block>
|
||||
|
||||
38
mondumas/templates/dossier/note_edit.pt
Normal file
38
mondumas/templates/dossier/note_edit.pt
Normal file
@@ -0,0 +1,38 @@
|
||||
<metal:block use-macro="main_template">
|
||||
<div metal:fill-slot="content">
|
||||
|
||||
<div class="alert alert-danger" tal:condition="message" tal:content="message" />
|
||||
|
||||
<div class="row">
|
||||
<form id="text_edit-form" action="${url}" method="post">
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="text-text">Tapez ou dictez le texte :</label>
|
||||
<textarea class="form-control monospace-font" rows="30" cols="40" id="notes" name="notes">${note.notes}</textarea>
|
||||
</div>
|
||||
<p>Modifié le : ${note.modif_le.strftime('%d-%m-%Y')} par ${note.usermaj}
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<a href="${request.application_url}/dossier_view/${nodossier}" class="btn btn-default" role="button">
|
||||
<span class="glyphicon glyphicon-chevron-left"></span> Annuler</a>
|
||||
<button class="btn btn-primary" type="submit" name="form.submitted">
|
||||
<span class="glyphicon glyphicon-ok"></span> Enregistrer</button>
|
||||
<button class="btn btn-warning" type="submit" name="form.deleted">
|
||||
<span class="glyphicon glyphicon-remove"></span> Supprimer</button>
|
||||
</div>
|
||||
</form>
|
||||
<br />
|
||||
<br />
|
||||
</div> <!-- row -->
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#text_edit-form').formValidation();
|
||||
$('form input').on('keypress', function(e) {
|
||||
return e.which !== 13;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</metal:block>
|
||||
@@ -34,10 +34,6 @@
|
||||
<a href="${request.application_url}/text_list"><span class="glyphicon glyphicon-list logo-primary"></span></a>
|
||||
<h4>TEXTES EMAIL</h4>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<a href="${request.application_url}/new_home"><span class="glyphicon glyphicon-dashboard logo-primary"></span></a>
|
||||
<h4>PROTOTYPE HOME</h4>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="row text-center">
|
||||
|
||||
@@ -87,16 +87,19 @@
|
||||
var options_ca_3y_1 = {
|
||||
title: '${title1}',
|
||||
colors: ['purple', 'ff9900', '#dc3912', '3366cc', 'green'],
|
||||
pieHole: 0.3,
|
||||
};
|
||||
|
||||
var options_ca_3y_2 = {
|
||||
title: '${title2}',
|
||||
colors: ['purple', 'ff9900', '#dc3912', '3366cc', 'green'],
|
||||
pieHole: 0.3,
|
||||
};
|
||||
|
||||
var options_ca_3y_3 = {
|
||||
title: '${title3}',
|
||||
colors: ['purple', 'ff9900', '#dc3912', '3366cc', 'green'],
|
||||
pieHole: 0.3,
|
||||
};
|
||||
|
||||
var options_ca_3y_1_x = {
|
||||
|
||||
@@ -410,6 +410,6 @@ def ajax_article(request):
|
||||
d['ref'] = items.ref
|
||||
d['libelle'] = items.libelle
|
||||
d['prixht'] = "%.2f" % items.prixht
|
||||
d['unite'] = items.unite
|
||||
liste.append(d)
|
||||
|
||||
return Response(json.dumps(liste))
|
||||
|
||||
@@ -128,6 +128,10 @@ def dossier_view(request):
|
||||
|
||||
status = get_status_by_id(request, '')
|
||||
motifs = get_motifs(request)
|
||||
# lire les notes du dossier
|
||||
dem_notes = get_dem_notes(request, nodossier, '0', 'NOTE')
|
||||
# lire les croquis du dossier
|
||||
dem_croquis = get_dem_notes(request, nodossier, '0', 'CROQUIS')
|
||||
|
||||
if 'form.close' in request.params:
|
||||
status = request.params["status"]
|
||||
@@ -161,6 +165,9 @@ def dossier_view(request):
|
||||
'access': access,
|
||||
'status': status,
|
||||
'motifs': motifs,
|
||||
'motif': '',
|
||||
'dem_notes': dem_notes,
|
||||
'dem_croquis': dem_croquis,
|
||||
}
|
||||
|
||||
@view_config(route_name='dossier_selected', permission='view')
|
||||
@@ -1578,4 +1585,49 @@ def dem_devis(request):
|
||||
'dt_data': json.dumps(liste),
|
||||
'societe': societe,
|
||||
'order_option': order_option,
|
||||
}
|
||||
}
|
||||
|
||||
@view_config(route_name='note_add', permission='view')
|
||||
def note_add(request):
|
||||
logged_in = request.authenticated_userid.upper()
|
||||
nodossier = request.matchdict['nodossier']
|
||||
insert_dem_note(request, nodossier, 'NOTE', logged_in)
|
||||
|
||||
return HTTPFound(request.route_url('dossier_view', nodossier=nodossier))
|
||||
|
||||
@view_config(route_name='note_edit', renderer='../templates/dossier/note_edit.pt', permission='view')
|
||||
def note_edit(request):
|
||||
nodossier = request.matchdict['nodossier']
|
||||
noligne = request.matchdict['noligne']
|
||||
url = request.route_url('note_edit', nodossier=nodossier, noligne=noligne)
|
||||
|
||||
message = ""
|
||||
note = get_dem_notes(request, nodossier, noligne)
|
||||
|
||||
if 'form.submitted' in request.params:
|
||||
notes = request.params["notes"]
|
||||
|
||||
update_dem_note(request, nodossier, noligne, notes)
|
||||
request.session.flash("'%s' a été modifiée avec succès." % note.libelle, 'success')
|
||||
return HTTPFound(location=request.route_url('dossier_view', nodossier=nodossier))
|
||||
|
||||
if 'form.deleted' in request.params:
|
||||
delete_dem_note(request, nodossier, noligne)
|
||||
request.session.flash("'%s' a été supprimée avec succès." % note.libelle, 'success')
|
||||
return HTTPFound(location=request.route_url('dossier_view', nodossier=nodossier))
|
||||
|
||||
return {
|
||||
'page_title': note.libelle,
|
||||
'url': url,
|
||||
'message': message,
|
||||
'nodossier': nodossier,
|
||||
'note': note,
|
||||
}
|
||||
|
||||
@view_config(route_name='croquis_edit', renderer='../templates/dossier/croquis_edit.pt', permission='view')
|
||||
def croquis_edit(request):
|
||||
|
||||
return {
|
||||
'page_title': 'NOUVEAU CROQUIS',
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user