* Changed default logging behaviour
We now log by default to a timestamped file in $datadir/logs/. No longer
shall restarting Manuskript after a crash wipe a very useful logfile.
Logs older than 35 days in the $datadir/logs/ directory are pruned
during startup. In case of subtle corruption detected a few weeks after
the fact, relevant logs might still exist to explain what had happened...
yet it does not come at the cost of infinitely gobbling up a users
storage space, either.
The --logfile (-L) argument can now utilize strftime() specifiers. A
special modifier %# is also supported which will insert the process id.
Besides being an added factor of uniqueness for a filename, it can also
be relevant to help identify the log file belonging to a misbehaving
Manuskript process.
* Added support-related items to Help menu
The 'Technical Support' item should lead to a landing page that will
guide the user to the most efficient way to resolve their problem.
How to report bugs and submit logs would be one of those.
The 'Locate Log File' item should open a file manager window with the
logfile of this session highlighted. Because Manuskript is still writing
to it, we first remind them of its limited use until Manuskript is
closed.
This approach was chosen because users might want to locate the file
prior to reproducing a bug, or because they'd like to look at other logs
from previous sessions.
* Updated translation files and added german translation
Co-authored-by: TheJackiMonster <thejackimonster@gmail.com>
Manuskript now logs the versions of modules and libraries powering them
for as far those are easily accessible. This includes all the optional
modules, too. None of this is visible on the terminal of course - unless
Manuskript is run with the --verbose flag. This clears up the last bit
of unnecessary console spam, leaving our users blissfully unaware.
Until we (and/or Qt) break something again, that is...
Some snippets have yet to be converted due to the more complex nature
of those snippets, and to keep things neat a separate commit makes more
sense for those.
This is the quick way to patch this. I'd recommend changing the findFirstFile function in functions/__init__.py for a more permanent solution, but this should suffice for now.
When creating a new character, sets an appropriate importance level.
* If a character is selected, the new character has the same importance level.
* If a top-level importance level is selected, the new character has that level
* Otherwise, the importance level is zero
When i was using certain styles like cleanlooks or qt5ct-style, a TypeError was raising in cascade about the function not having enough arguments.
It looked like that, despite the last args of Qstyle.subElementRect() and Qstyle.sizeFromContents() were optional, it was still required to mention it (even if it was just None).
That TypeError was only appearing with certain styles, at startup or when changing styles in the settings window.
A previous fix (5f9ea3) inadvertently broke the progress bar by
converting to the wrong data type. (See issue #561 / PR #609).
While checking the code I realized the problem occurred primarily
because we weren't checking the validity of the values closer to the
source. Doing so alleviates the need to check elsewhere.
In the hope of inspiring a more systematic approach, a new uiParse()
utility function has been added to curb the further growth of toXxx()
functions that exist solely to validate user input.
There is no doubt room for improvement, both on the end of the new
uiParse() function as well as the spot where it is used. Ideally, the
data that comes out of the model should already be 'safe', but since
this is a bugfix for a bugfix I want to keep waves to a minimum.
This commit fixes issue #652.
See PR #651
This commit restores the functionality that prevents spell checking a
word that is being actively typed at the end of a paragraph.
The goals for the spell check word match regexp are:
A. Words should include those with an apostrophe
*E.g., can't*
B. Words should exclude underscore
*E.g., hello_world is two words*
C. Words in other languages should be recognized
*E.g., French word familiarisé*
D. Spell check should include word at absolute end of line with no
trailing space or punctuation
*E.g., tezt*
E. Spell check should ignore partial words in progress (user typing)
*E.g., paragr while midway through typing paragraph*
This commit addresses all five of the above goals.
HISTORY:
- See issue #166 and commit 6ec0c19 in the 0.5.0 release.
- See issue #283 and commit 63b471e in the 0.7.0 release.
Also fix minor incorrect utf-8 encoding at top of source file.
This code change sets:
- Fequency Analyzer tool default first tab of "Word frequency"
(was Phrase frequency)
Steps to set default window tab:
1. Start Qt Designer
2. Open .ui file
3. Ensure that each selected window tab is the one desired as default
4. Save .ui file
5. Exit Qt Designer
6. Generate .py file with: make ui
See PR #623
This code change sets:
- Character pane default first tab of "Basic info" (was Notes)
- Character pane Basic info "Name" as the default first field (was Motivation)
- Plots pane default first tab of "Basic info" (was Resolution steps)
Steps to edit tab order and default window tab:
1. Start Qt Designer
2. Open .ui file
3. Choose menu **Edit -> Edit Tab Order**
4. Ctrl-click on item just before the first incorrect tab order item
5. Click other items in order until remaining order is correct
6. Ensure that each selected window tab is the one desired as default
7. Save .ui file
8. Exit Qt Designer
9. Generate .py file with: make ui
See https://doc.qt.io/qt-5/designer-tab-order.html
This code change implements a portion of issue #244
Last time I touched this code, I went in looking for a specific problem,
and came out with a fix specific to that issue. That fix was not wrong,
yet it hardly covered all the problems present in the code once one took
into account issues like:
- local vs remote resources,
- relative vs absolute paths,
- different operating systems behaving differently, and
- Qt being uniquely buggy on different platforms.
The major part of it was fixed by using QUrl.fromUserInput(), which does
the exact kind of auto-detection for the nature of the resource that we
were in need of.
The rest of the issues were fixed by creating a number of test cases and
fixing problems as they popped up. Testing was done in Windows & Ubunty
against the above-mentioned test cases, which can be found in PR #629.
Regarding ImageTooltip.supportedSchemes
When QUrl.fromUserInput() misidentifies the scheme on Linux, it causes
all resemblance between the original request and the reply.request() in
the finished() signal to be lost, which results in this item getting
stuck in the ImageTooltip processing pipeline.
Limiting the supported schemes to the ones most commonly encountered
('file', 'http', 'https' and the schema-less local paths) is the only
reliable method I have found to work around this particular bug in Qt.
It is the only FileDialog in the entire codebase that does not conform
to the rest of the OS like its brethren, and it stuck out like a sore
thumb because of it.
See PR #615
This rename is being done to clarify that when a user enables "Save on
project close" then the project will be saved whenever the user
chooses to close the project or to quit Manuskript.
Note that the actual name of the setting saveOnQuit should also be
changed but instead has been marked as a future TODO because it
involves a change in the project file format.
See issue #561.
The problem appears to be a due to a combination of factors, such as:
- Python does not automatically convert an empty/blank variable to the
integer zero (0)
- Default goal value is empty/blank for a new Text (scene)
- Asynchronous events can occur such that the change in the Outline
pane of a new Text (scene) goal from empty/blank to a value is not
saved to the data model prior to the update event in the Editor pane
accessing the model value for the word count progress display.
Steps to Reproduce:
1. Start manuskript and create new project (no template).
2. Select **Outline** pane.
3. Click "Text Plus" icon to create a text (default name "New")
4. Select **Editor** pane.
5. Click on **New** to display empty text.
6. Select **Outline** pane.
7. Double-click the empty area on **New** line under title **Goal**,
type in "300", and press **Enter**.
Note that manuskript crashes with a segmentation fault.
Work around the crash by using the already existing manuskript
function toInt() which handles conversion of empty/blank values to
integer value zero (0).
The About/Settings/Import/Export/ExportManager windows were all created
in odd places, usually to the left of the main window, which meant outside the
desktop area with little overlap if the main window is maximized. The logic in
centering the window on its parent was wrong. This fixes it.
Describing all the rabbitholes that I and kakaroto have gone through
while debugging this one until dawn can frankly not do enough justice to
the crazy amount of rubberducking that went on while trying to fix this.
This bug would be triggered whenever you had a document open in the
editor and then moved an ancestor object downwards (visually) in the tree.
Or when you simply deleted the ancestor. Depending on the exact method
that caused the opened item to be removed from the internal model, the
exact nature of the bug would vary, which means this commit fixes a few
different bits of code that lead to what appears to be the same bug.
In order of appearance, the bugs that ruined our sleep were:
1) The editor widget was trying to handle the removed item at too late a
stage.
2) The editor widget tried to fix its view after a move by searching for
the new item with the same ID, but in the case of moving an object down
it came across its own old item, ruining the attempt.
3) The editor widget did not properly account for the hierarchical
nature of the model.
Upon fixing these the next day, it was revealed that:
4) The outlineItem.updateWordCount(emit=False) flag is broken. This
function would call setData() in several spots which would still cause
emits to bubble through the system despite emit=False, and we simply got
lucky that it stopped enough of them until now.
This last one was caused by a small mistake in the fixes for the first
three bugs, but it has led to a couple of extra changes to make any
future bug hunts slightly less arduous and frustrating:
a) When calling item.removeChild(c), it now resets the associated parent
and model to mirror item.insertChild(c). This has also led to an extra
check in model.parent() to check for its validity.
b) The outlineItem.updateWordCount(emit=) flag has been removed entirely
and it now emits away with reckless abandon. I have been unable to
reproduce the crashes the code warned about, so I consider this a code
quality fix to prevent mysterious future issues where things sometimes
do not properly update right.
Worthy of note is that the original code clearly showed the intention to
close tabs for items that were removed. Reworking the editor to support
closing a tab is unfortunately way out of scope, so this intention was
left in and the new fix was structured to make it trivial to implement
such a change when the time comes. An existing FIXME regarding unrelated
buggy editor behaviour was left in, too.
Many thanks to Kakaroto for burning the midnight oil with me to get to
the bottom of this. (I learned a lot that night!)
Issues #479, #516 and #559 are fixed by this commit. And maybe some others,
too.
This is in preparation for adding support for additional spellchecking libraries
other than PyEnchant which seems to be unmaintained and does not build in
Windows 64 bit.
Issue #549 was caused because the request and reply object urls are not
guaranteed to be the same. Redirects are the most common cause, but a
malformed URL apparently also qualifies. We now make sure to look at the
original request.
Because the code confused me while I was working on it, I decided to
refactor and document it in order to understand what was going on. I am
glad I did: I found another crashing bug involving the rapid-firing of
tooltip requests, and the processing dict never had its entries removed
either, leading to a (very slow) memory leak over time.
All is good in the world of image tooltips now.