Tooltipy w przyciskach.
#
# Document List Handlers
#
+# TODO: security check
class BasicLibraryHandler(AnonymousBaseHandler):
allowed_methods = ('GET',)
return {'documents' : document_list}
+#
+# This handler controlls the document collection
+#
class LibraryHandler(BaseHandler):
allowed_methods = ('GET', 'POST')
anonymous = BasicLibraryHandler
+
@hglibrary
def read(self, request, lib):
"""Return the list of documents."""
lock.release()
except LibraryException, e:
import traceback
- return response.InternalError().django_response(\
- {'exception': traceback.format_exc()} )
+ return response.InternalError().django_response({
+ "reason": traceback.format_exc()
+ })
except DocumentAlreadyExists:
# Document is already there
- return response.EntityConflict().django_response(\
- {"reason": "Document %s already exists." % docid})
+ return response.EntityConflict().django_response({
+ "reason": "already-exists",
+ "message": "Document already exists." % docid
+ })
#
# Document Handlers
# we're done :)
return document.data('xml')
else:
- xdoc = parser.WLDocument.from_string(document.data('xml'))
+ xdoc = parser.WLDocument.from_string(document.data('xml'),\
+ parse_dublincore=False)
ptext = xdoc.part_as_text(part)
if ptext is None:
"provided": target_rev,
"latest": udoc.revision })
- if not request.user.has_perm('explorer.document.can_share'):
- # User is not permitted to make a merge, right away
- # So we instead create a pull request in the database
- try:
- prq, created = PullRequest.objects.get_or_create(
- source_revision = str(udoc.revision),
- defaults = {
- 'comitter': request.user,
- 'document': docid,
- 'status': "N",
- 'comment': form.cleaned_data['message'] or '$AUTO$ Document shared.',
- }
- )
-
- return response.RequestAccepted().django_response(\
- ticket_status=prq.status, \
- ticket_uri=reverse("pullrequest_view", args=[prq.id]) )
- except IntegrityError, e:
- return response.InternalError().django_response()
-
if form.cleaned_data['type'] == 'update':
# update is always performed from the file branch
# to the user branch
success, changed = udoc.update(request.user.username)
- if form.cleaned_data['type'] == 'share':
- success, changed = udoc.share(form.cleaned_data['message'])
+ if form.cleaned_data['type'] == 'share':
+ if not request.user.has_perm('explorer.document.can_share'):
+ # User is not permitted to make a merge, right away
+ # So we instead create a pull request in the database
+ try:
+ prq, created = PullRequest.objects.get_or_create(
+ source_revision = str(udoc.revision),
+ defaults = {
+ 'comitter': request.user,
+ 'document': docid,
+ 'status': "N",
+ 'comment': form.cleaned_data['message'] or '$AUTO$ Document shared.',
+ }
+ )
+
+ return response.RequestAccepted().django_response(\
+ ticket_status=prq.status, \
+ ticket_uri=reverse("pullrequest_view", args=[prq.id]) )
+ except IntegrityError:
+ return response.EntityConflict().django_response({
+ 'reason': 'request-already-exist'
+ })
+ else:
+ success, changed = udoc.share(form.cleaned_data['message'])
if not success:
return response.EntityConflict().django_response({
def read(self, request):
groups = toolbar.models.ButtonGroup.objects.all()
- return [ {'name': g.name, 'position': g.position,\
- 'buttons': g.button_set.all()} for g in groups ]
-
+ return [g.to_dict(with_buttons=True) for g in groups]
class ScriptletsHandler(BaseHandler):
allowed_methods = ('GET',)
def __unicode__(self):
return self.name
+ def to_dict(self, with_buttons=False):
+ d = {'name': self.name, 'position': self.position}
+
+ if with_buttons:
+ d['buttons'] = [ b.to_dict() for b in self.button_set.all() ]
+
+ return d
#class ButtonGroupManager(models.Manager):
#
if self.key_mod & 0x01: mods.append('Alt')
if self.key_mod & 0x02: mods.append('Ctrl')
if self.key_mod & 0x04: mods.append('Shift')
- mods.append('"'+self.key+'"')
- return '+'.join(mods)
+ mods.append(str(self.key))
+ return '[' + '+'.join(mods) + ']'
+
+ def to_dict(self):
+ return {
+ 'label': self.label,
+ 'tooltip': (self.tooltip or '') + self.hotkey_name(),
+ 'key': self.key,
+ 'key_mod': self.key_mod,
+ 'params': self.params,
+ 'scriptlet_id': self.scriptlet_id
+ }
def __unicode__(self):
return self.label
this.set('state', 'loading');
// load the transformed data
- messageCenter.addMessage('info', 'Wczytuję HTML...');
+ // messageCenter.addMessage('info', 'Wczytuję HTML...');
$.ajax({
url: this.htmlURL,
}
this.set('data', data);
this.set('state', 'synced');
- messageCenter.addMessage('success', 'Wczytałem HTML :-)');
+ // messageCenter.addMessage('success', 'Wczytałem HTML :-)');
},
- loadingFailed: function() {
+ loadingFailed: function(response) {
if (this.get('state') != 'loading') {
alert('erroneous state:', this.get('state'));
}
- this.set('error', 'Nie udało się załadować panelu');
+
+ var json_response = null;
+ var message = "";
+
+ try {
+ json_response = $.evalJSON(response.responseText);
+
+ if(json_response.reason == 'xml-parse-error') {
+
+ message = json_response.message.replace(/(line\s+)(\d+)(\s+)/i,
+ "<a class='xml-editor-ref' href='#xml-$2-1'>$1$2$3</a>");
+
+ message = message.replace(/(line\s+)(\d+)(\,\s*column\s+)(\d+)/i,
+ "<a class='xml-editor-ref' href='#xml-$2-$4'>$1$2$3$4</a>");
+
+
+ }
+ else {
+ message = json_response.message || json_response.reason || "nieznany błąd.";
+ }
+ }
+ catch (e) {
+ message = response.statusText;
+ }
+
+ this.set('error', '<p>Nie udało się wczytać widoku HTML: </p>' + message);
+
this.set('state', 'error');
- messageCenter.addMessage('error', 'Nie udało mi się wczytać HTML. Spróbuj ponownie :-(');
+ // messageCenter.addMessage('error', 'Nie udało mi się wczytać HTML. Spróbuj ponownie :-(');
},
getXMLPart: function(elem, callback)
toolbarUrl = $('#api-toolbar-url').text();
doc = new Editor.DocumentModel();
- var editor = new EditorView('#body-wrap', doc);
- editor.freeze();
- var flashView = new FlashView('#flashview', messageCenter);
- var splitView = new SplitView('#splitview', doc);
+ EditorView = new EditorView('#body-wrap', doc);
+ EditorView.freeze();
leftPanelView = new PanelContainerView('#left-panel-container', doc);
rightPanelContainer = new PanelContainerView('#right-panel-container', doc);
+
+ var flashView = new FlashView('#flashview', messageCenter);
});
buttonPressed: function(event)
{
+ var self = this;
var target = event.target;
var groupIndex = parseInt($(target).attr('ui:groupindex'), 10);
console.log('Executing', scriptletId, 'with params', params);
try {
- scriptletCenter.scriptlets[scriptletId](this.parent, params);
+ self.parent.freeze('Wykonuję akcję...');
+ setTimeout(function() {
+ scriptletCenter.scriptlets[scriptletId](self.parent, params);
+ self.parent.unfreeze();
+ }, 10);
} catch(e) {
- console.log("Scriptlet", scriptletId, "failed.");
+ console.log("Scriptlet", scriptletId, "failed.", e);
}
},
/*global View render_template panels */
var EditorView = View.extend({
- _className: 'EditorView',
- element: null,
- model: null,
- template: null,
+ _className: 'EditorView',
+ element: null,
+ model: null,
+ template: null,
- init: function(element, model, template) {
- this._super(element, model, template);
+ init: function(element, model, template) {
+ this._super(element, model, template);
- this.quickSaveButton = $('#action-quick-save', this.element).bind('click.editorview', this.quickSave.bind(this));
- this.commitButton = $('#action-commit', this.element).bind('click.editorview', this.commit.bind(this));
- this.updateButton = $('#action-update', this.element).bind('click.editorview', this.update.bind(this));
- this.mergeButton = $('#action-merge', this.element).bind('click.editorview', this.merge.bind(this));
+ this.quickSaveButton = $('#action-quick-save', this.element).bind('click.editorview', this.quickSave.bind(this));
+ this.commitButton = $('#action-commit', this.element).bind('click.editorview', this.commit.bind(this));
+ this.updateButton = $('#action-update', this.element).bind('click.editorview', this.update.bind(this));
+ this.mergeButton = $('#action-merge', this.element).bind('click.editorview', this.merge.bind(this));
- this.model.addObserver(this, 'state', this.modelStateChanged.bind(this));
- this.modelStateChanged('state', this.model.get('state'));
-
- // Inicjalizacja okien jQuery Modal
- $('#commit-dialog', this.element).
- jqm({
- modal: true,
- onShow: this.loadRelatedIssues.bind(this)
- });
+ this.model.addObserver(this, 'state', this.modelStateChanged.bind(this));
+ this.modelStateChanged('state', this.model.get('state'));
+
+ this.splitView = new SplitView('#splitview', doc);
+
+ // Inicjalizacja okien jQuery Modal
+ $('#commit-dialog', this.element).
+ jqm({
+ modal: true,
+ onShow: this.loadRelatedIssues.bind(this)
+ });
- $('#commit-dialog-cancel-button', this.element).click(function() {
- $('#commit-dialog-error-empty-message').hide();
- $('#commit-dialog').jqmHide();
- });
+ $('#commit-dialog-cancel-button', this.element).click(function() {
+ $('#commit-dialog-error-empty-message').hide();
+ $('#commit-dialog').jqmHide();
+ });
- // $('#split-dialog').jqm({
- // modal: true,
- // onShow: $.fbind(self, self.loadSplitDialog)
- // }).
- // jqmAddClose('button.dialog-close-button');
+ // $('#split-dialog').jqm({
+ // modal: true,
+ // onShow: $.fbind(self, self.loadSplitDialog)
+ // }).
+ // jqmAddClose('button.dialog-close-button');
- this.model.load();
- },
+ this.model.load();
+ },
- quickSave: function(event) {
- this.model.saveDirtyContentModel();
- },
+ quickSave: function(event) {
+ this.model.saveDirtyContentModel();
+ },
- commit: function(event) {
- $('#commit-dialog', this.element).jqmShow({callback: this.doCommit.bind(this)});
- },
+ commit: function(event) {
+ $('#commit-dialog', this.element).jqmShow({
+ callback: this.doCommit.bind(this)
+ });
+ },
- doCommit: function(message) {
- this.model.saveDirtyContentModel(message);
- },
+ doCommit: function(message) {
+ this.model.saveDirtyContentModel(message);
+ },
- update: function(event) {
- this.model.update();
- },
+ update: function(event) {
+ this.model.update();
+ },
- merge: function(event) {
- $('#commit-dialog', this.element).jqmShow({callback: this.doMerge.bind(this)});
- },
+ merge: function(event) {
+ $('#commit-dialog', this.element).jqmShow({
+ callback: this.doMerge.bind(this)
+ });
+ },
- doMerge: function(message) {
- this.model.merge(message);
- },
+ doMerge: function(message) {
+ this.model.merge(message);
+ },
- loadRelatedIssues: function(hash) {
- var self = this;
- var c = $('#commit-dialog-related-issues');
+ loadRelatedIssues: function(hash) {
+ var self = this;
+ var c = $('#commit-dialog-related-issues');
- $('#commit-dialog-save-button').click(function(event, data)
- {
- if ($('#commit-dialog-message').val().match(/^\s*$/)) {
- $('#commit-dialog-error-empty-message').fadeIn();
- } else {
- $('#commit-dialog-error-empty-message').hide();
- $('#commit-dialog').jqmHide();
+ $('#commit-dialog-save-button').click(function(event, data)
+ {
+ if ($('#commit-dialog-message').val().match(/^\s*$/)) {
+ $('#commit-dialog-error-empty-message').fadeIn();
+ } else {
+ $('#commit-dialog-error-empty-message').hide();
+ $('#commit-dialog').jqmHide();
- var message = $('#commit-dialog-message').val();
- $('#commit-dialog-related-issues input:checked')
- .each(function() { message += ' refs #' + $(this).val(); });
- console.log("COMMIT APROVED", hash.t);
- hash.t.callback(message);
- }
- return false;
- });
+ var message = $('#commit-dialog-message').val();
+ $('#commit-dialog-related-issues input:checked')
+ .each(function() {
+ message += ' refs #' + $(this).val();
+ });
+ console.log("COMMIT APROVED", hash.t);
+ hash.t.callback(message);
+ }
+ return false;
+ });
- $("div.loading-box", c).show();
- $("div.fatal-error-box", c).hide();
- $("div.container-box", c).hide();
+ $("div.loading-box", c).show();
+ $("div.fatal-error-box", c).hide();
+ $("div.container-box", c).hide();
- $.getJSON(c.attr('ui:ajax-src') + '?callback=?',
- function(data, status)
- {
- var fmt = '';
- $(data).each( function() {
- fmt += '<label><input type="checkbox" checked="checked"';
- fmt += ' value="' + this.id + '" />' + this.subject +'</label>\n';
- });
- $("div.container-box", c).html(fmt);
- $("div.loading-box", c).hide();
- $("div.container-box", c).show();
- });
+ $.getJSON(c.attr('ui:ajax-src') + '?callback=?',
+ function(data, status)
+ {
+ var fmt = '';
+ $(data).each( function() {
+ fmt += '<label><input type="checkbox" checked="checked"';
+ fmt += ' value="' + this.id + '" />' + this.subject +'</label>\n';
+ });
+ $("div.container-box", c).html(fmt);
+ $("div.loading-box", c).hide();
+ $("div.container-box", c).show();
+ });
- hash.w.show();
- },
+ hash.w.show();
+ },
- modelStateChanged: function(property, value) {
- // Uaktualnia stan przycisków
- if (value == 'dirty') {
- this.quickSaveButton.attr('disabled', null);
- this.commitButton.attr('disabled', null);
- this.updateButton.attr('disabled', 'disabled');
- this.mergeButton.attr('disabled', 'disabled');
- } else if (value == 'synced') {
- this.quickSaveButton.attr('disabled', 'disabled');
- this.commitButton.attr('disabled', 'disabled');
- this.updateButton.attr('disabled', null);
- this.mergeButton.attr('disabled', null);
- } else if (value == 'empty') {
- this.quickSaveButton.attr('disabled', 'disabled');
- this.commitButton.attr('disabled', 'disabled');
- this.updateButton.attr('disabled', 'disabled');
- this.mergeButton.attr('disabled', 'disabled');
- }
- },
+ modelStateChanged: function(property, value) {
+ // Uaktualnia stan przycisków
+ if (value == 'dirty') {
+ this.quickSaveButton.attr('disabled', null);
+ this.commitButton.attr('disabled', null);
+ this.updateButton.attr('disabled', 'disabled');
+ this.mergeButton.attr('disabled', 'disabled');
+ } else if (value == 'synced') {
+ this.quickSaveButton.attr('disabled', 'disabled');
+ this.commitButton.attr('disabled', 'disabled');
+ this.updateButton.attr('disabled', null);
+ this.mergeButton.attr('disabled', null);
+ } else if (value == 'empty') {
+ this.quickSaveButton.attr('disabled', 'disabled');
+ this.commitButton.attr('disabled', 'disabled');
+ this.updateButton.attr('disabled', 'disabled');
+ this.mergeButton.attr('disabled', 'disabled');
+ }
+ },
- dispose: function() {
- $('#action-quick-save', this.element).unbind('click.editorview');
- $('#action-commit', this.element).unbind('click.editorview');
- $('#action-update', this.element).unbind('click.editorview');
- $('#action-merge', this.element).unbind('click.editorview');
+ dispose: function() {
+ $('#action-quick-save', this.element).unbind('click.editorview');
+ $('#action-commit', this.element).unbind('click.editorview');
+ $('#action-update', this.element).unbind('click.editorview');
+ $('#action-merge', this.element).unbind('click.editorview');
- this.model.removeObserver(this);
- this._super();
- }
+ this.model.removeObserver(this);
+ this._super();
+ }
});
this.$printLink.attr('href', base + "?revision=" + this.model.get('revision'));
},
- modelStateChanged: function(property, value) {
+ modelStateChanged: function(property, value)
+ {
+ var self = $(this);
+
if (value == 'synced' || value == 'dirty') {
this.unfreeze();
} else if (value == 'unsynced') {
this.freeze('Zapisywanie...');
} else if (value == 'error') {
this.freeze(this.model.get('error'));
+ $('.xml-editor-ref', this.overlay).click(
+ function(event) {
+ console.log("Sending scroll rq.", this);
+ try {
+ var href = $(this).attr('href').split('-');
+ var line = parseInt(href[1]);
+ var column = parseInt(href[2]);
+
+ $(document).trigger('xml-scroll-request', {line:line, column:column});
+ } catch(e) {
+ console.log(e);
+ }
+
+ return false;
+ });
}
},
init: function(element, model) {
this._super(element, model, null);
this.element.css('position', 'relative');
- this._resizingSubviews = false;
+ this._resizingSubviews = false;
this.views = $(">*", this.element[0]).css({
position: 'absolute', // positioned inside splitter container
this.leftView = $(this.views[0]);
this.rightView = $(this.views[1]);
+
this.splitbar = $(this.views[2] || '<div></div>')
.insertAfter(this.leftView)
.css({
-/*global View CodeMirror ButtonToolbarView render_template panels */
+/*global View CodeMirror ToolbarView render_template panels */
var XMLView = View.extend({
_className: 'XMLView',
element: null,
var self = this;
$('.xmlview-toolbar', this.element).bind('resize.xmlview', this.resized.bind(this));
-
-
+
+ // scroll to the given position (if availble)
+ this.scrollCallback = this.scrollOnRequest.bind(this);
+ $(document).bind('xml-scroll-request', this.scrollCallback);
+
this.parent.freeze('Ładowanie edytora...');
this.editor = new CodeMirror($('.xmlview', this.element).get(0), {
parserfile: 'parsexml.js',
parserConfig: {
useHTMLKludges: false
},
- textWrapping: false,
+ textWrapping: true,
tabMode: 'spaces',
indentUnit: 0,
onChange: this.editorDataChanged.bind(this),
},
dispose: function() {
+ $(document).unbind('xml-scroll-request', this.scrollCallback);
+
this.model.removeObserver(this);
$(this.editor.frame).remove();
this._super();
var ch = String.fromCharCode(code & 0xff).toLowerCase();
/* # console.log(ch.charCodeAt(0), '#', buttons); */
- var buttons = $('.buttontoolbarview-button[title='+ch+']', this.element);
+ var buttons = $('.buttontoolbarview-button[hotkey='+ch+']', this.element);
var mod = 0;
if(event.altKey) mod |= 0x01;
this.buttonToolbar.buttonPressed({
target: button
});
+ },
+
+ scrollOnRequest: function(event, data)
+ {
+ try {
+ var line = this.editor.nthLine(data.line);
+ this.editor.selectLines(line, (data.column-1));
+ } catch(e) {
+ console.log('Exception in scrollOnRequest:', e);
+ }
}
});
<div class="buttontoolbarview-group toolbar-buttons-container" ui:groupIndex="<%= i %>" style="display: none">
<% for (var j=0; j < buttons[i].buttons.length; j++) { %>
<% if (buttons[i].buttons[j].scriptlet_id) { %>
- <button type="button" class="buttontoolbarview-button"
- title="<%= buttons[i].buttons[j].key %>"
+ <button type="button" class="buttontoolbarview-button"
+ title="<%= buttons[i].buttons[j].tooltip %>"
+ hotkey="<%= buttons[i].buttons[j].key %>"
ui:hotkey_mod="<%= buttons[i].buttons[j].key_mod %>"
ui:groupindex="<%= i %>" ui:buttonindex="<%= j %>">
<%= buttons[i].buttons[j].label %>